背景:节俭的、清晰的代码目录结构,可维护性、复用性高的公共组件是开发时良好的习惯;
一、文件目录结构设计:
├── build // 构建相关 ├── config // 配置相关 ├── src // 源代码 │ ├── server // 所有请求api、mock请求、axios封装 │ ├── assets // 静态资源,同vendor │ │ ├──styles //自定义样式(UI组件) │ │ ├──icons //图标 │ │ ├──theme //主题 │ │ └──lang //语言 │ ├── components // 全局组件(common-x或module-x) │ ├──utils // 工具箱(公共方法) │ │ ├──directive //全局指令 │ │ ├──filtres //全局过滤 │ │ └──moment //全局日期配置等,如copyRouer、cloneDeep │ ├── router // 路由 │ ├── store // 全局 store管理 │ ├── views // 同pages │ ├── App.vue // 入口页面 │ ├── main.js // 入口 加载组件 初始化等 │ └── permission.js // 权限管理 ├── static // 第三方不打包资源 │ ├── echart // 可视化图形插件 │ └── Tinymce // 如:富文本编辑器 ├── .babelrc // babel-loader 配置 ├── eslintrc.js // eslint 配置项 ├── .gitignore // git 忽略项 ├── favicon.ico // favicon图标 ├── index.html // html模板 └── package.json // package.json
补充一下views视图页面的目录层级设计:
├── src // 源代码 │ ├── views // 页面视图 │ │ ├──app //1.应用 │ │ ├──chart //2.画布 │ │ ├──feature //3.特征 │ │ └──... //4.其他 ├── app // 应用 │ ├── common-comp //公共组件 │ ├── appDev //1.开发 │ ├── appConfig //2.配置 │ ├── appRelease //3.发布 │ └── index.vue //路由的匹配的入口文件 ├── appDev // 应用开发 │ ├── module-comp //模板组件 │ │ ├── leftMenu //左侧菜单 │ │ ├── rightNav //右侧导航 │ │ └── rightTabs //右侧分栏 │ └── index.vue //入口布局
二、路由设计:
import Vue from 'vue' import Router from 'vue-router' import App from '../App.vue' Vue.use(Router) // 一级路由:webpack设置了相对路径缩写,其他:如appManage const page404 = () => { return import('comp/page404.vue') } export default new Router({ mode: 'history', // 2种模式,默认带#号 // eslint-disable-next-line // 不校验下一行 base: __serverBasePath, routes: [ { path: '/', name: '主页', component: Index, redirect: '/web', beforeEnter (to, from, next) { console.log('beforeEnter') next(false) } }, { path: '/web', name: 'web', component: App, redirect: '/web/appManage', children: [ { path: '/web/appManage', name: 'appManage', component: appManage, redirect: '/web/appManage/appList', children: appManageRoute, // 【二级路由】 beforeEnter (to, form, next) { console.log('before enter') next(true) } }, { path: '*', name: '404', component: page404 } ] })
二级路由独立定义,也有可能是后台控制的动态路由:
// 第二级:/appManage/appList const appList = () => { return import('views/appManage/appList/index.vue') } // 第三级:/appManage/appConfig const appConfig = () => { return import('views/appManage/appEdit/app-config/index.vue') } export default [ { path: '/web/appManage/appList', name: '应用列表', component: appList }, { path: '/web/appManage/appEdit', name: '应用编辑', component: appEdit, redirect: '/web/appManage/appEdit/appConfig', children: [ { path: '/web/appManage/appEdit/appConfig', name: 'appConfig', // 应用配置 component: appConfig, redirect: '/web/appManage/appEdit/appConfig/basicInfo', children: [ { path: '/web/appManage/appEdit/appConfig/new', name: 'newAppConfig', component: newAppConfig }] }] ]] } ]
三、路由相关的工具函数与跳转问题:
export function copyRouteQuery (query) { let newQuery = {} let keys = Object.keys(query) keys.forEach((v) => { newQuery[v] = query[v] }) return newQuery }
<template> <el-breadcrumb separator-class="el-icon-arrow-right"> <el-breadcrumb-item v-for="n in breadcrumbList.length" :key="n"> <router-link :to="{ path: activePath,query: query }" v-if="n===1">{{ breadcrumbList[n-1] }}</router-link> <span v-if="n>1">{{ breadcrumbList[n-1] }}</span> </el-breadcrumb-item> </el-breadcrumb> </template> <script> import {copyRouteQuery} from '@/utils' export default { props: { breadcrumb: { type: String, default: '一级目录' + '>' + '二级目录' + '>' + '三级目录' } }, computed: { query () { return copyRouteQuery(this.$route.query) || {} }, breadcrumbList () { return this.breadcrumb.split('>') || [] }, activePath () { const index = this.$route.path.lastIndexOf('/') return this.$route.path.substring(0, index) || '' } } } </script>
this.$router.push({path:'/componentManage/personJar',params: { id: xxx}}); this.$router.push({ name:'xxxx组件',query: { type:'xxxxx',proj_id: xxxxx }}); this.$message.success('保存成功,1秒后跳转编辑页面(点击网址输入框右侧解除拦截)!') let query = {businessId: businessId, proj_id: projId, credid: credid} setTimeout(() => { let {href} = this.$router.resolve({ path: `/web/appManage/appEdit/appConfig`, query: query }) window.open(href, '_blank') }, 1000)
读取路由属性与监听路由变化:
computed: { businessId () { return this.$store.state.businessInfo.id || '' }, queryBusinessId () { return this.businessId === '0' } }, watch: { queryBusinessId: {// 初始化加载 immediate: true, handler () { if (this.$route.path && this.$route.path.split('/').length > 0) { this.activeName = this.$route.path.split('/')[3] } this.isGlobal = this.queryBusinessId } } }