路由与公共组件——规划命名与文件目录

背景:节俭的、清晰的代码目录结构,可维护性、复用性高的公共组件是开发时良好的习惯;

一、文件目录结构设计:

├── 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
      }
    }
  }

 

posted @ 2019-08-20 12:31  桥南小院  阅读(465)  评论(0编辑  收藏  举报