远程组件创建提交, 国际化部分代码优化 merge代码

zhufu
zhufu 2025-01-17 09:15:22 +08:00
parent 4b66115c88
commit 915df23b2c
22 changed files with 265 additions and 175 deletions

View File

@ -84,7 +84,7 @@
"animate.css": "^4.1.1",
"axios": "^1.6.4",
"color": "^4.2.3",
"codemirror": "^5.65.16",
"codemirror": "^6.0.1",
"cropperjs": "^1.6.1",
"crypto-js": "^4.2.0",
"dayjs": "^1.11.10",
@ -137,7 +137,14 @@
"jszip":"^3.10.1",
"shpjs":"^6.1.0",
"js-base64":"3.7.7",
"monaco-editor": "^0.33.0"
"monaco-editor": "^0.33.0",
"@codemirror/lang-javascript": "^6.2.2",
"@codemirror/language": "^6.10.8",
"@codemirror/state": "^6.5.1",
"@codemirror/view": "^6.36.2",
"@codemirror/basic-setup": "^0.20.0",
"vue-codemirror": "^6.1.1",
"@codemirror/theme-one-dark": "^6.1.2"
},
"devDependencies": {
"@amap/amap-jsapi-loader": "^1.0.1",

View File

@ -61,6 +61,16 @@ export enum PageEnum {
BASE_HOME_ITEMS = '/project/items',
BASE_HOME_ITEMS_NAME = 'Project-Items',
// 远程组件
BASE_HOME_REMOTE = '/project/remote',
BASE_HOME_REMOTE_NAME = 'Project-Remote',
BASE_HOME_LIST_REMOTE = '/project/remote/list',
BASE_HOME_LIST_REMOTE_NAME = 'Project-Remote-List',
BASE_HOME_CREATE_REMOTE = '/project/remote/create/:id(.*)*',
BASE_HOME_CREATE_REMOTE_NAME = 'Project-Remote-Create',
// 我的模板
BASE_HOME_TEMPLATE = '/project/my-template',
BASE_HOME_TEMPLATE_NAME = 'Project-My-Template',

View File

@ -1,33 +0,0 @@
import login from './login'
import project from './project'
const global = {
doc_addr: 'Document',
code_addr: 'Code',
form_account: 'Please enter your account or email',
form_password: 'Please enter your password',
// header
doc: 'Document',
help: 'Help',
contact: 'About Software',
logout: 'Logout',
// system setting
sys_set: 'System Setting',
lang_set: 'Language Setting',
// right key
r_edit: 'Edit',
r_preview: 'Preview',
r_copy: 'Clone',
r_rename: 'Rename',
r_publish: 'Publish',
r_unpublish: 'Unpublish',
r_download: 'Download',
r_delete: 'Delete',
r_more: 'More',
}
export default {
global,
login,
project
}

View File

@ -1,7 +0,0 @@
export default {
desc: "Login",
form_auto: "Sign in automatically",
form_button: "Login",
login_success: "Login success",
login_message: "Please complete the letter",
}

View File

@ -1,15 +0,0 @@
export default {
create_btn: 'Create',
create_tip: 'Please select a content for development',
project: 'Project',
my: 'My',
new_project: 'New Project',
all_project: 'All Project',
my_templete: 'My Templete',
template_market: 'Template Market',
// items
release: 'Release',
unreleased: 'Unrelease',
last_edit: 'Last edit time'
}

View File

@ -1,33 +0,0 @@
//语言
import { lang } from '@/settings/designSetting';
import { createI18n } from 'vue-i18n'; //引入vue-i18n组件
import { getLocalStorage } from '@/utils';
import { StorageEnum } from '@/enums/storageEnum';
import { LangEnum } from '@/enums/styleEnum';
import { LangStateType } from '@/store/modules/langStore/langStore.d';
import zh from './zh/index';
import en from './en/index';
const langStorage: LangStateType = getLocalStorage(StorageEnum.GO_LANG_STORE);
// 语言数组
export const langList = [
{
label: '中文',
key: LangEnum.ZH,
},
{
label: 'English',
key: LangEnum.EN,
},
];
export const i18n = createI18n({
legacy: false,
globalInjection: true,
locale: langStorage?.lang || lang,
fallbackLocale: langStorage?.lang || lang,
messages: {
[LangEnum.ZH]: zh,
[LangEnum.EN]: en,
},
});

View File

@ -1,33 +0,0 @@
import login from './login'
import project from './project'
const global = {
doc_addr: '文档地址',
code_addr: '仓库地址',
form_account: '请输入账号或邮箱',
form_password: '请输入密码',
// 头部
doc: '说明文档',
help: '帮助中心',
contact: '关于软件',
logout: '退出登录',
// 系统设置
sys_set: '系统设置',
lang_set: '语言设置',
// 功能键
r_edit: '编辑',
r_preview: '预览',
r_copy: '克隆',
r_rename: '重命名',
r_publish: '发布',
r_unpublish: '取消发布',
r_download: '下载',
r_delete: '删除',
r_more: '更多',
}
export default {
global,
login,
project
}

View File

@ -1,7 +0,0 @@
export default {
desc: "登录",
form_auto: "自动登录",
form_button: "登录",
login_success: "登录成功",
login_message: "请填写完整信息",
}

View File

@ -1,16 +0,0 @@
export default {
// aside
create_btn: '新建',
create_tip: '从哪里出发好呢?',
project: '项目',
my: '我的',
new_project: '新项目',
all_project: '全部项目',
my_templete: '我的模板',
template_market: '模板市场',
// items
release: '已发布',
unreleased: '未发布',
last_edit: '最后编辑'
}

View File

@ -1,6 +1,6 @@
{
"create_btn": "Create",
"create_tip": "Please select a content for development",
"create_tip": "Please select the content to create",
"project": "Project",
"my": "My",
"new_project": "New Project",
@ -9,5 +9,6 @@
"template_market": "Template Market",
"release": "Release",
"unreleased": "Unrelease",
"last_edit": "Last edit time"
"last_edit": "Last edit time",
"remote_component": "remote"
}

View File

@ -1,6 +1,6 @@
{
"create_btn": "新建",
"create_tip": "从哪里出发好呢?",
"create_tip": "请选择要创建的内容",
"project": "项目",
"my": "我的",
"new_project": "新项目",
@ -9,5 +9,6 @@
"template_market": "模板市场",
"release": "已发布",
"unreleased": "未发布",
"last_edit": "最后编辑"
"last_edit": "最后编辑",
"remote_component": "远程组件"
}

View File

@ -35,7 +35,6 @@ import lineMdIcons from '@iconify/json/json/line-md.json';
import wiIcons from '@iconify/json/json/wi.json';
import { addCollection } from 'iconify-icon';
import { setupNaive, setupDirectives, setupCustomComponents, initFunction } from '@/plugins';
import { i18n } from '@/i18n';
import { GoAppProvider } from '@/components/GoAppProvider/index';
import * as echarts from 'echarts'
@ -49,9 +48,7 @@ async function bootstrap() {
// 语言注册
// app.use(i18n);
// 在Vue应用挂载后绑定$t到window对象
app.config.globalProperties.$t = i18n.global.t;
app.config.globalProperties.$echarts = echarts
window['$t'] = i18n.global.t;
// 注册全局常用的 naive-ui 组件
setupNaive(app);

View File

@ -24,7 +24,7 @@ const props = defineProps({
})
let remote = ref()
let url = 'http://192.168.10.130:3000/getVue3Str1'
let url = 'http://192.168.10.124:3000/getVue3Str2'
const data = ref(props.chartConfig.option.dataset)
onMounted(() => {

View File

@ -5,6 +5,8 @@ import { PageEnum } from '@/enums/pageEnum';
const importPath = {
'PageEnum.BASE_HOME_NAME': () => import('@/views/project/index.vue'),
'PageEnum.BASE_HOME_ITEMS_NAME': () => import('@/views/project/items/index.vue'),
'PageEnum.BASE_HOME_REMOTE_NAME': () => import('@/views/project/remote/list/index.vue'),
'PageEnum.BASE_HOME_REMOTE_CREATE_NAME': () => import('@/views/project/remote/create/index.vue'),
'PageEnum.BASE_HOME_TEMPLATE_NAME': () => import('@/views/project/mtTemplate/index.vue'),
'PageEnum.BASE_HOME_TEMPLATE_MARKET_NAME': () =>
import('@/views/project/templateMarket/index.vue'),
@ -28,6 +30,34 @@ export const projectRoutes: RouteRecordRaw = {
title: '我的项目',
},
},
{
path: PageEnum.BASE_HOME_REMOTE,
name: PageEnum.BASE_HOME_REMOTE_NAME,
redirect: PageEnum.BASE_HOME_LIST_REMOTE,
meta: {
title: '远程组件',
},
children: [
{
path: PageEnum.BASE_HOME_LIST_REMOTE,
name: PageEnum.BASE_HOME_LIST_REMOTE_NAME,
meta: {
title: '远程组件列表',
hideMenu: true,
},
component: importPath['PageEnum.BASE_HOME_REMOTE_NAME'],
},
{
path: PageEnum.BASE_HOME_CREATE_REMOTE,
name: PageEnum.BASE_HOME_CREATE_REMOTE_NAME,
meta: {
title: '创建远程组件',
hideMenu: true,
},
component: importPath['PageEnum.BASE_HOME_REMOTE_CREATE_NAME'],
},
]
},
{
path: PageEnum.BASE_HOME_TEMPLATE,
name: PageEnum.BASE_HOME_TEMPLATE_NAME,

View File

@ -2,5 +2,5 @@
* *
*/
export const httpErrorHandle = () => {
window['$message'].error(window['$t']('http.error_message'))
window['$message'].error('error')
}

View File

@ -37,6 +37,6 @@
}
}
.go-project .content-top {
top: 10px;
top: 0px;
}
</style>

View File

@ -18,7 +18,7 @@
:disabled="item.disabled"
v-for="item in typeList"
:key="item.key"
@click="btnHandle"
@click="btnHandle(item.key)"
>
<component :is="item.title"></component>
<template #icon>
@ -57,17 +57,23 @@
disabled: false,
},
{
title: renderLang('project.my_templete'),
key: PageEnum.BASE_HOME_TEMPLATE_NAME,
title: renderLang('project.remote_component'),
key: PageEnum.BASE_HOME_CREATE_REMOTE_NAME,
icon: ObjectStorageIcon,
disabled: true,
},
{
title: renderLang('project.template_market'),
key: PageEnum.BASE_HOME_TEMPLATE_MARKET_NAME,
icon: StoreIcon,
disabled: true,
disabled: false,
},
// {
// title: renderLang('project.my_templete'),
// key: PageEnum.BASE_HOME_TEMPLATE_NAME,
// icon: ObjectStorageIcon,
// disabled: true,
// },
// {
// title: renderLang('project.template_market'),
// key: PageEnum.BASE_HOME_TEMPLATE_MARKET_NAME,
// icon: StoreIcon,
// disabled: true,
// },
]);
watch(props, (newValue) => {
@ -83,8 +89,13 @@
const btnHandle = (key: string) => {
closeHandle();
const id = getUUID();
const path = fetchPathByName(ChartEnum.CHART_HOME_NAME, 'href');
routerTurnByPath(path, [id], undefined, true);
let path = fetchPathByName(key, 'href');
if(key == ChartEnum.CHART_HOME_NAME){
routerTurnByPath(path, [id], undefined, true);
}else{
path = path.replace('#','')
routerTurnByPath(path, [id], undefined, false);
}
};
</script>
<style lang="scss" scoped>

View File

@ -47,11 +47,11 @@
const modalShow = ref<boolean>(false);
const clickHandle = () => {
console.log('clickHandle');
const id = getUUID();
const path = fetchPathByName(ChartEnum.CHART_HOME_NAME, 'href');
routerTurnByPath(path, [id], undefined, true);
// modalShow.value = true;
// console.log('clickHandle');
// const id = getUUID();
// const path = fetchPathByName(ChartEnum.CHART_HOME_NAME, 'href');
// routerTurnByPath(path, [id], undefined, true);
modalShow.value = true;
};
const closeHandle = () => {

View File

@ -45,7 +45,10 @@
const { getAsideCollapsedWidth } = toRefs(useSettingStore());
const route = useRoute();
const menuValue = computed(() => route.name);
const menuValue = computed(() => {
let routeName = route.name.split('-')
return `${routeName[0]}-${routeName[1]}`
});
const menuOptions = menuOptionsInit();

View File

@ -4,6 +4,7 @@ import { RouterLink } from 'vue-router';
import { PageEnum } from '@/enums/pageEnum';
import { MenuOption, MenuGroupOption } from 'naive-ui';
import { icon } from '@/plugins';
import { useI18n } from '@/hooks/web/useI18n';
const { GridIcon, TvOutlineIcon } = icon.ionicons5;
const { StoreIcon, ObjectStorageIcon, DevicesIcon } = icon.carbon;
@ -14,7 +15,7 @@ export const renderMenuLabel = (option: MenuOption | MenuGroupOption) => {
export const expandedKeys = () => ['all-project'];
// 我的项目菜单
export const menuOptionsInit = () => {
const t = window['$t'];
const { t } = useI18n();
return reactive([
{
@ -36,6 +37,20 @@ export const menuOptionsInit = () => {
key: PageEnum.BASE_HOME_ITEMS_NAME,
icon: renderIcon(TvOutlineIcon),
},
{
label: () =>
h(
RouterLink,
{
to: {
name: PageEnum.BASE_HOME_REMOTE_NAME,
},
},
{ default: () => t('project.remote_component') },
),
key: PageEnum.BASE_HOME_REMOTE_NAME,
icon: renderIcon(TvOutlineIcon),
},
],
},
]);

View File

@ -0,0 +1,150 @@
<template>
<div class="out-div">
<div class="header">
<div class="component-name-div">
<n-icon size="20" :depth="3">
<fish-icon></fish-icon>
</n-icon>
<n-text @click="handleFocus" style="white-space: nowrap;">
组件名称 -
<n-button v-show="!focus" secondary size="tiny">
<span class="title">
{{ title }}
</span>
</n-button>
</n-text>
<n-input
v-show="focus"
ref="inputInstRef"
size="small"
type="text"
maxlength="16"
show-count
placeholder="请输入项目名称"
v-model:value.trim="title"
@keyup.enter="handleBlur"
@blur="handleBlur"
></n-input>
</div>
</div>
<div class="content-div">
<div class="code-div">
<Codemirror
v-model="code"
:extensions="extensions"
placeholder="Code goes here..."
:style="{ height: '100%' }"
:autofocus="true"
:indent-with-tab="true"
:tab-size="2"
@blur="load"/>
</div>
<div class="show-div">
<component :is="remote" v-if="remote" />
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import { defineComponent, ref, shallowRef, defineAsyncComponent, nextTick } from 'vue'
import {Codemirror} from "vue-codemirror";
import { javascript } from '@codemirror/lang-javascript'
import { oneDark } from '@codemirror/theme-one-dark'
import { loadModule } from 'vue3-sfc-loader/dist/vue3-sfc-loader'
import * as Vue from 'vue'
import { keymap } from "@codemirror/view";
import { icon } from '@/plugins';
const { FishIcon } = icon.ionicons5;
const customKeymap = keymap.of([
{
key: "Ctrl-s", // Ctrl+S
run() {
load()
alert("代码已保存!"); //
return true; // true
},
},
{
key: "Mod-s", // Mac Command+S
run() {
alert("代码已保存Mac"); //
return true;
},
},
]);
const extensions = [javascript(),oneDark, customKeymap ]
const code = ref(`console.log('Hello, world!')`)
const remote = ref()
const title = ref()
const focus = ref(false)
const inputInstRef = ref(null);
const load = () => {
const options = {
moduleCache: {
vue: Vue
},
getFile() {
return code.value
},
addStyle(textContent) {
const style = Object.assign(document.createElement('style'), { textContent })
const ref = document.head.getElementsByTagName('style')[0] || null
document.head.insertBefore(style, ref)
}
}
remote.value = defineAsyncComponent(() => loadModule('remote.vue', options))
}
const handleFocus = () => {
focus.value = true;
nextTick(() => {
inputInstRef.value && (inputInstRef.value as any).focus();
});
};
const handleBlur = () => {
focus.value = false;
}
</script>
<style lang="scss" scoped>
.out-div{
width: 100%;
.header{
width: 100%;
height: 60px;
display: flex;
align-items: center;
justify-content: center;
.component-name-div{
width: 300px;
display: flex;
align-items: center;
}
}
.content-div{
height: calc(100vh - 61px);
display: flex;
.code-div{
width: 50%;
height: 100%;
}
.show-div{
width: 50%;
height: 100%;
background: #282c34;
border-left: 4px solid;
}
}
}
:deep(.v-codemirror) {
font-size: 16px; /* 设置字体大小 */
line-height: 1.5; /* 设置行高,提升可读性 */
}
</style>

View File

@ -0,0 +1,9 @@
<template>
<div class="">远程组件List</div>
</template>
<script setup lang="ts">
import {} from "vue"
</script>
<style lang="scss" scoped></style>