mirror of
https://github.com/crawlab-team/crawlab.git
synced 2026-01-25 17:42:25 +01:00
added vue3-sfc-loader
This commit is contained in:
@@ -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(() => {
|
||||
|
||||
14
frontend/src/interfaces/global.d.ts
vendored
14
frontend/src/interfaces/global.d.ts
vendored
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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');
|
||||
|
||||
@@ -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({
|
||||
|
||||
13
frontend/src/router/plugin.ts
Normal file
13
frontend/src/router/plugin.ts
Normal 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
39
frontend/src/utils/sfc.ts
Normal 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;
|
||||
@@ -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';
|
||||
|
||||
Reference in New Issue
Block a user