added vue3-sfc-loader

This commit is contained in:
Marvin Zhang
2021-08-23 11:09:34 +08:00
parent c6ce602b3b
commit 047dcca4a3
17 changed files with 18006 additions and 117 deletions

View File

@@ -23,7 +23,7 @@ import {computed, defineComponent, PropType} from 'vue';
import MenuItemIcon from '@/components/icon/MenuItemIcon.vue';
import {useStore} from 'vuex';
import {getPrimaryPath} from '@/utils/path';
import {useI18n} from 'vue-i18n';
// import {useI18n} from 'vue-i18n';
import {useRouter} from 'vue-router';
import Icon from '@/components/icon/Icon.vue';
@@ -57,7 +57,7 @@ export default defineComponent({
'click',
],
setup(props: TabProps, {emit}) {
const {tm} = useI18n();
// const {tm} = useI18n();
const router = useRouter();
const storeNamespace = 'layout';
const store = useStore();
@@ -77,7 +77,8 @@ export default defineComponent({
const title = computed(() => {
// TODO: detailed title
return item.value?.title || tm('No Title');
// return item.value?.title || tm('No Title');
return item.value?.title;
});
const active = computed(() => {

View File

@@ -1,5 +1,11 @@
interface Window {
initCanvas?: Function;
resetCanvas?: Function;
_hmt?: Array;
import Vue from 'vue';
declare global {
interface Window {
initCanvas?: Function;
resetCanvas?: Function;
_hmt?: Array;
'vue3-sfc-loader': { loadModule };
Vue: Vue;
}
}

View File

@@ -1,12 +1,12 @@
<template>
<span :class="sidebarCollapsed ? 'collapsed' : ''" class="sidebar-toggle" @click="toggleSidebar">
<font-awesome-icon v-if="!sidebarCollapsed" :icon="['fas', 'outdent']"/>
<font-awesome-icon v-else :icon="['fas', 'indent']"/>
<font-awesome-icon v-if="!sidebarCollapsed" :icon="['fas', 'outdent']" />
<font-awesome-icon v-else :icon="['fas', 'indent']" />
</span>
<el-aside :class="sidebarCollapsed ? 'collapsed' : ''" class="sidebar" width="inherit">
<div class="logo-container">
<div class="logo">
<img :src="logo" alt="logo" className="logo-img"/>
<img :src="logo" alt="logo" className="logo-img" />
<span class="logo-title">Crawlab</span>
<span class="logo-sub-title">
<div class="logo-sub-title-block">
@@ -32,14 +32,16 @@
:index="item.path"
@click="onMenuItemClick(item)"
>
<MenuItemIcon :item="item" size="normal"/>
<MenuItemIcon :item="item" size="normal" />
<template #title>
<span class="menu-item-title">{{ item.title }}</span>
</template>
</el-menu-item>
<div class="plugin-anchor" />
</el-menu>
</div>
</el-aside>
<div class="script-anchor" />
</template>
<script lang="ts">

View File

@@ -3,7 +3,7 @@ import ElementPlus from 'element-plus';
import App from '@/App.vue';
import router from '@/router';
import store from '@/store';
import i18n from '@/i18n';
// import i18n from '@/i18n';
import {FontAwesomeIcon} from '@fortawesome/vue-fontawesome';
import {library} from '@fortawesome/fontawesome-svg-core';
import {fab} from '@fortawesome/free-brands-svg-icons';
@@ -23,10 +23,11 @@ initBaiduTonji();
// remove loading placeholder
document.querySelector('#loading-placeholder')?.remove();
createApp(App)
const app = createApp(App);
app
.use(store)
.use(router)
.use(ElementPlus)
.use(i18n)
// .use(i18n)
.component('font-awesome-icon', FontAwesomeIcon)
.mount('#app');

View File

@@ -9,6 +9,7 @@ import schedule from '@/router/schedule';
import user from '@/router/user';
import tag from '@/router/tag';
import token from '@/router/token';
import plugin from '@/router/plugin';
import {initRouterAuth} from '@/router/auth';
import {sendPv} from '@/utils/admin';
@@ -28,6 +29,7 @@ export const routes: Array<RouteRecordRaw> = [
...user,
...tag,
...token,
...plugin,
],
},
];
@@ -42,6 +44,7 @@ export const menuItems: MenuItem[] = [
{path: '/users', title: 'Users', icon: ['fa', 'users']},
{path: '/tags', title: 'Tags', icon: ['fa', 'tag']},
{path: '/tokens', title: 'Tokens', icon: ['fa', 'key']},
{path: '/plugins', title: 'Plugins', icon: ['fa', 'plug']},
];
const router = createRouter({

View File

@@ -0,0 +1,13 @@
import {defineAsyncComponent} from 'vue';
import {RouteRecordRaw} from 'vue-router';
import {getLoadModuleOptions, loadModule} from '@/utils/sfc';
const endpoint = 'plugins';
export default [
{
path: endpoint,
// component: defineAsyncComponent(() => loadModule('/vue/HelloWorld.vue', getLoadModuleOptions())),
component: defineAsyncComponent(() => loadModule('/vue/App.vue', getLoadModuleOptions())),
},
] as Array<RouteRecordRaw>;

39
frontend/src/utils/sfc.ts Normal file
View File

@@ -0,0 +1,39 @@
const vue = window['Vue'];
const {loadModule: sfcLoadModule} = window['vue3-sfc-loader'];
export const getLoadModuleOptions = () => {
return {
moduleCache: {
vue,
},
pathResolve({ refPath, relPath }: {refPath?: string; relPath?: string}) {
// self
if ( relPath === '.' ) {
return refPath;
}
// relPath is a module name ?
if ( relPath?.[0] !== '.' && relPath?.[0] !== '/' ) {
return relPath;
}
return String(new URL(relPath, refPath === undefined ? window.location.toString() : refPath));
},
async getFile(url: string) {
const res = await fetch(url);
if (!res.ok) {
throw Object.assign(new Error(res.statusText + ' ' + url), {res});
}
return {
getContentData: (asBinary: boolean) => asBinary ? res.arrayBuffer() : res.text(),
};
},
addStyle(textContent: string) {
const style = Object.assign(document.createElement('style'), {textContent});
const ref = document.head.getElementsByTagName('style')[0] || null;
document.head.insertBefore(style, ref);
},
};
};
export const loadModule = sfcLoadModule;

View File

@@ -117,7 +117,6 @@
<script lang="ts">
import {computed, defineComponent, onMounted, onUnmounted, ref} from 'vue';
import {isValidUsername} from '@/utils/validate';
import {useI18n} from 'vue-i18n';
import {useRoute, useRouter} from 'vue-router';
import logo from '@/assets/logo.svg';
import {ElForm, ElMessage} from 'element-plus';