美文网首页
iveiw admin 2.0实战心得

iveiw admin 2.0实战心得

作者: 时光机器01 | 来源:发表于2019-07-10 11:49 被阅读0次

    前言:iview admin是基于Vue.js和iview组件库的开发的后台管理系统,基于它可以快速搭建一套UI简介、排版清晰的后台管理系统
    iveiw admin介绍和代码
    nodejs介绍
    iview组件

    image.png

    1 核心文件

    1.1 src/main.js

    // The Vue build version to load with the `import` command
    // (runtime-only or standalone) has been set in webpack.base.conf with an alias.
    import Vue from 'vue'
    import App from './App'
    import router from './router'
    import store from './store'
    import iView from 'iview'
    import i18n from '@/locale'
    import importDirective from '@/directive'
    import axios from '@/libs/axios'
    // import 'iview/dist/styles/iview.css'
    import '@/assets/icons/iconfont.css'
    import './index.less'
    
    Vue.use(iView, {
      i18n: (key, value) => i18n.t(key, value)
    }) //国际化
    Vue.config.productionTip = false
    
    Object.defineProperty(Vue.prototype, '$get', { value: axios.get }) //全局自定义
    Object.defineProperty(Vue.prototype, '$post', { value: axios.post })
    /**
     * 注册vue指令
     */
    importDirective(Vue)
    if (process.env.NODE_ENV !== 'production') require('@/mock')
    /* eslint-disable no-new */
    new Vue({
      el: '#app',
      router,
      i18n,
      store,
      render: h => h(App)
    })
    

    1.1.1 国际化

    Vue.use(iView, {
      i18n: (key, value) => i18n.t(key, value)
    }) //国际化
    

    1.1.2 全局自定义

    Object.defineProperty(Vue.prototype, '$get', { value: axios.get }) //全局自定义
    Object.defineProperty(Vue.prototype, '$post', { value: axios.post })
    

    1.1.3 注册vue指令

    importDirective(Vue)
    

    1.1.4 mock数据
    mock数据模拟

    if (process.env.NODE_ENV !== 'production') require('@/mock') //根据环境mock
    

    具体mock的路由在src/mock/index.js中
    1.1.5 加载vue页面入口

    new Vue({
      el: '#app',
      router,
      i18n,
      store,
      render: h => h(App)
    })
    

    1.2 路由src/router

    详细参考下面文档
    vue router介绍
    vue-router hash和history模式
    vue router api

    1.2.1 路由入口index.js

    每次路由跳转都会首先走到index.js代码中,这里面定义了路由模式以及路由前后的处理

    import Vue from 'vue'
    import Router from 'vue-router'
    import routes from './routers'
    import store from '@/store'
    import iView from 'iview'
    // import { canTurnTo } from '@/libs/util'
    
    Vue.use(Router)
    const router = new Router({
      routes,
      mode: 'history'
    })  //路由模式
    
    router.beforeEach((to, from, next) => {
      iView.LoadingBar.start()
      store.dispatch('getUserInfo').then(user => {
        console.log(user)
        next()
        // 拉取用户信息,通过用户权限和跳转的页面的name来判断是否有权限访问;access必须是一个数组,如:['super_admin'] ['super_admin', 'admin']
        // if (canTurnTo(to.name, user.access, routes)) next() // 有权限,可访问
        // else next({ replace: true, name: 'error_401' }) // 无权限,重定向到401页面
      })
    })  //路由跳转前一些公共处理
    
    router.afterEach(to => {
      iView.LoadingBar.finish()
      window.scrollTo(0, 0)
    }) //路由加载页面后一些公共处理
    
    export default router
    
    

    1.2.1 路由具体配置router.js

    router.js文件中定义了个人uri路由对应前端加载渲染的vue组件前端页面。以及多级菜单的结构

    import Main from '@/components/main'
    import parentView from '@/components/parent-view'
    
    /**
     * iview-admin中meta除了原生参数外可配置的参数:
     * meta: {
     *  title: { String|Number|Function }
     *         显示在侧边栏、面包屑和标签栏的文字
     *         使用'{{ 多语言字段 }}'形式结合多语言使用,例子看多语言的路由配置;
     *         可以传入一个回调函数,参数是当前路由对象,例子看动态路由和带参路由
     *  hideInBread: (false) 设为true后此级路由将不会出现在面包屑中,示例看QQ群路由配置
     *  hideInMenu: (false) 设为true后在左侧菜单不会显示该页面选项
     *  notCache: (false) 设为true后页面在切换标签后不会缓存,如果需要缓存,无需设置这个字段,而且需要设置页面组件name属性和路由配置的name一致
     *  access: (null) 可访问该页面的权限数组,当前路由设置的权限会影响子路由
     *  icon: (-) 该页面在左侧菜单、面包屑和标签导航处显示的图标,如果是自定义图标,需要在图标名称前加下划线'_'
     *  beforeCloseName: (-) 设置该字段,则在关闭当前tab页时会去'@/router/before-close.js'里寻找该字段名对应的方法,作为关闭前的钩子函数
     * }
     */
    
    export default [
      {
        path: '/login',
        name: 'login',
        meta: {
          title: 'Login - 登录',
          hideInMenu: true
        },
        component: () => import('@/view/login/login.vue')
      },
      {
        path: '/',
        name: '_home',
        redirect: '/home',
        component: Main,
        meta: {
          hideInMenu: true,
          notCache: true
        },
        children: [
          {
            path: '/home',
            name: 'home',
            meta: {
              hideInMenu: true,
              title: '首页',
              notCache: true,
              icon: 'md-home'
            },
            component: () => import('@/view/single-page/home')
          }
        ]
      },
      {
        path: '',
        name: 'doc',
        meta: {
          title: '文档',
          href: 'https://lison16.github.io/iview-admin-doc/#/',
          icon: 'ios-book'
        }
      },
      {
        path: '/join',
        name: 'join',
        component: Main,
        meta: {
          hideInBread: true
        },
        children: [
          {
            path: 'join_page',
            name: 'join_page',
            meta: {
              icon: '_qq',
              title: 'QQ群'
            },
            component: () => import('@/view/join-page.vue')
          }
        ]
      },
      {
        path: '/message',
        name: 'message',
        component: Main,
        meta: {
          hideInBread: true,
          hideInMenu: true
        },
        children: [
          {
            path: 'message_page',
            name: 'message_page',
            meta: {
              icon: 'md-notifications',
              title: '消息中心'
            },
            component: () => import('@/view/single-page/message/index.vue')
          }
        ]
      },
      {
        path: '/components',
        name: 'components',
        meta: {
          icon: 'logo-buffer',
          title: '组件'
        },
        component: Main,
        children: [
          {
            path: 'tree_select_page',
            name: 'tree_select_page',
            meta: {
              icon: 'md-arrow-dropdown-circle',
              title: '树状下拉选择器'
            },
            component: () => import('@/view/components/tree-select/index.vue')
          },
          {
            path: 'count_to_page',
            name: 'count_to_page',
            meta: {
              icon: 'md-trending-up',
              title: '数字渐变'
            },
            component: () => import('@/view/components/count-to/count-to.vue')
          },
          {
            path: 'drag_list_page',
            name: 'drag_list_page',
            meta: {
              icon: 'ios-infinite',
              title: '拖拽列表'
            },
            component: () => import('@/view/components/drag-list/drag-list.vue')
          },
          {
            path: 'drag_drawer_page',
            name: 'drag_drawer_page',
            meta: {
              icon: 'md-list',
              title: '可拖拽抽屉'
            },
            component: () => import('@/view/components/drag-drawer')
          },
          {
            path: 'org_tree_page',
            name: 'org_tree_page',
            meta: {
              icon: 'ios-people',
              title: '组织结构树'
            },
            component: () => import('@/view/components/org-tree')
          },
          {
            path: 'tree_table_page',
            name: 'tree_table_page',
            meta: {
              icon: 'md-git-branch',
              title: '树状表格'
            },
            component: () => import('@/view/components/tree-table/index.vue')
          },
          {
            path: 'cropper_page',
            name: 'cropper_page',
            meta: {
              icon: 'md-crop',
              title: '图片裁剪'
            },
            component: () => import('@/view/components/cropper/cropper.vue')
          },
          {
            path: 'tables_page',
            name: 'tables_page',
            meta: {
              icon: 'md-grid',
              title: '多功能表格'
            },
            component: () => import('@/view/components/tables/tables.vue')
          },
          {
            path: 'split_pane_page',
            name: 'split_pane_page',
            meta: {
              icon: 'md-pause',
              title: '分割窗口'
            },
            component: () => import('@/view/components/split-pane/split-pane.vue')
          },
          {
            path: 'markdown_page',
            name: 'markdown_page',
            meta: {
              icon: 'logo-markdown',
              title: 'Markdown编辑器'
            },
            component: () => import('@/view/components/markdown/markdown.vue')
          },
          {
            path: 'editor_page',
            name: 'editor_page',
            meta: {
              icon: 'ios-create',
              title: '富文本编辑器'
            },
            component: () => import('@/view/components/editor/editor.vue')
          },
          {
            path: 'icons_page',
            name: 'icons_page',
            meta: {
              icon: '_bear',
              title: '自定义图标'
            },
            component: () => import('@/view/components/icons/icons.vue')
          }
        ]
      },
      {
        path: '/update',
        name: 'update',
        meta: {
          icon: 'md-cloud-upload',
          title: '数据上传'
        },
        component: Main,
        children: [
          {
            path: 'update_table_page',
            name: 'update_table_page',
            meta: {
              icon: 'ios-document',
              title: '上传Csv'
            },
            component: () => import('@/view/update/update-table.vue')
          },
          {
            path: 'update_paste_page',
            name: 'update_paste_page',
            meta: {
              icon: 'md-clipboard',
              title: '粘贴表格数据'
            },
            component: () => import('@/view/update/update-paste.vue')
          }
        ]
      },
      {
        path: '/excel',
        name: 'excel',
        meta: {
          icon: 'ios-stats',
          title: 'EXCEL导入导出'
        },
        component: Main,
        children: [
          {
            path: 'upload-excel',
            name: 'upload-excel',
            meta: {
              icon: 'md-add',
              title: '导入EXCEL'
            },
            component: () => import('@/view/excel/upload-excel.vue')
          },
          {
            path: 'export-excel',
            name: 'export-excel',
            meta: {
              icon: 'md-download',
              title: '导出EXCEL'
            },
            component: () => import('@/view/excel/export-excel.vue')
          }
        ]
      },
      {
        path: '/tools_methods',
        name: 'tools_methods',
        meta: {
          hideInBread: true
        },
        component: Main,
        children: [
          {
            path: 'tools_methods_page',
            name: 'tools_methods_page',
            meta: {
              icon: 'ios-hammer',
              title: '工具方法',
              beforeCloseName: 'before_close_normal'
            },
            component: () => import('@/view/tools-methods/tools-methods.vue')
          }
        ]
      },
      {
        path: '/i18n',
        name: 'i18n',
        meta: {
          hideInBread: true
        },
        component: Main,
        children: [
          {
            path: 'i18n_page',
            name: 'i18n_page',
            meta: {
              icon: 'md-planet',
              title: 'i18n - {{ i18n_page }}'
            },
            component: () => import('@/view/i18n/i18n-page.vue')
          }
        ]
      },
      {
        path: '/error_store',
        name: 'error_store',
        meta: {
          hideInBread: true
        },
        component: Main,
        children: [
          {
            path: 'error_store_page',
            name: 'error_store_page',
            meta: {
              icon: 'ios-bug',
              title: '错误收集'
            },
            component: () => import('@/view/error-store/error-store.vue')
          }
        ]
      },
      {
        path: '/error_logger',
        name: 'error_logger',
        meta: {
          hideInBread: true,
          hideInMenu: true
        },
        component: Main,
        children: [
          {
            path: 'error_logger_page',
            name: 'error_logger_page',
            meta: {
              icon: 'ios-bug',
              title: '错误收集'
            },
            component: () => import('@/view/single-page/error-logger.vue')
          }
        ]
      },
      {
        path: '/directive',
        name: 'directive',
        meta: {
          hideInBread: true
        },
        component: Main,
        children: [
          {
            path: 'directive_page',
            name: 'directive_page',
            meta: {
              icon: 'ios-navigate',
              title: '指令'
            },
            component: () => import('@/view/directive/directive.vue')
          }
        ]
      },
      {
        path: '/multilevel',
        name: 'multilevel',
        meta: {
          icon: 'md-menu',
          title: '多级菜单'
        },
        component: Main,
        children: [
          {
            path: 'level_2_1',
            name: 'level_2_1',
            meta: {
              icon: 'md-funnel',
              title: '二级-1'
            },
            component: () => import('@/view/multilevel/level-2-1.vue')
          },
          {
            path: 'level_2_2',
            name: 'level_2_2',
            meta: {
              access: ['super_admin'],
              icon: 'md-funnel',
              showAlways: true,
              title: '二级-2'
            },
            component: parentView,
            children: [
              {
                path: 'level_2_2_1',
                name: 'level_2_2_1',
                meta: {
                  icon: 'md-funnel',
                  title: '三级'
                },
                component: () => import('@/view/multilevel/level-2-2/level-2-2-1.vue')
              },
              {
                path: 'level_2_2_2',
                name: 'level_2_2_2',
                meta: {
                  icon: 'md-funnel',
                  title: '三级'
                },
                component: () => import('@/view/multilevel/level-2-2/level-2-2-2.vue')
              }
            ]
          },
          {
            path: 'level_2_3',
            name: 'level_2_3',
            meta: {
              icon: 'md-funnel',
              title: '二级-3'
            },
            component: () => import('@/view/multilevel/level-2-3.vue')
          }
        ]
      },
      {
        path: '/argu',
        name: 'argu',
        meta: {
          hideInMenu: true
        },
        component: Main,
        children: [
          {
            path: 'params/:id',
            name: 'params',
            meta: {
              icon: 'md-flower',
              title: route => `{{ params }}-${route.params.id}`,
              notCache: true,
              beforeCloseName: 'before_close_normal'
            },
            component: () => import('@/view/argu-page/params.vue')
          },
          {
            path: 'query',
            name: 'query',
            meta: {
              icon: 'md-flower',
              title: route => `{{ query }}-${route.query.id}`,
              notCache: true
            },
            component: () => import('@/view/argu-page/query.vue')
          }
        ]
      },
      {
        path: '/401',
        name: 'error_401',
        meta: {
          hideInMenu: true
        },
        component: () => import('@/view/error-page/401.vue')
      },
      {
        path: '/500',
        name: 'error_500',
        meta: {
          hideInMenu: true
        },
        component: () => import('@/view/error-page/500.vue')
      },
      {
        path: '*',
        name: 'error_404',
        meta: {
          hideInMenu: true
        },
        component: () => import('@/view/error-page/404.vue')
      }
    ]
    

    1.3 配置src/config

    1.4 静态资源src/asset

    1.5 后端接口调用或者mock接口src/api

    资源

    iView资源:https://www.iviewui.com/docs/guide/install

    路由

    vue router介绍:https://router.vuejs.org/zh/guide/#javascript
    vue-router hash和history模式:https://juejin.im/post/5a61908c6fb9a01c9064f20a
    vue router api:https://router.vuejs.org/zh/api/#router-link

    语法

    vue.js:https://lison16.github.io/iview-admin-doc/#/%E5%BF%AB%E9%80%9F%E5%BC%80%E5%A7%8B

    打包

    webpack:https://www.webpackjs.com/concepts/

    'use strict'
    const path = require('path')
    const utils = require('./utils')
    const config = require('../config')
    const vueLoaderConfig = require('./vue-loader.conf')
    
    function resolve (dir) {
      return path.join(__dirname, '..', dir)
    }
    
    const createLintingRule = () => ({
    })
    
    module.exports = {
      context: path.resolve(__dirname, '../'),
      entry: {
        app: './src/main.js'
      },
      output: {
        path: config.build.assetsRoot,
        filename: '[name].js',
        publicPath: process.env.NODE_ENV === 'production'
          ? config.build.assetsPublicPath
          : config.dev.assetsPublicPath
      },
      resolve: {
        extensions: ['.js', '.vue', '.json'],
        alias: {
          'vue$': 'vue/dist/vue.esm.js',
          '@': resolve('src'),
          '_c': resolve('src/components'),
          '_conf': resolve('config')
        }
      },
      module: {
        rules: [
          ...(config.dev.useEslint ? [createLintingRule()] : []),
          {
            test: /\.vue$/,
            loader: 'vue-loader',
            options: vueLoaderConfig
          },
          {
            test: /\.js$/,
            loader: 'babel-loader',
            include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')]
          },
          {
            test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
            loader: 'url-loader',
            options: {
              limit: 10000,
              name: utils.assetsPath('img/[name].[hash:7].[ext]')
            }
          },
          {
            test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
            loader: 'url-loader',
            options: {
              limit: 10000,
              name: utils.assetsPath('media/[name].[hash:7].[ext]')
            }
          },
          {
            test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
            loader: 'url-loader',
            options: {
              limit: 10000,
              name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
            }
          }
        ]
      },
      node: {
        // prevent webpack from injecting useless setImmediate polyfill because Vue
        // source contains it (although only uses it if it's native).
        setImmediate: false,
        // prevent webpack from injecting mocks to Node native modules
        // that does not make sense for the client
        dgram: 'empty',
        fs: 'empty',
        net: 'empty',
        tls: 'empty',
        child_process: 'empty'
      }
    }
    
    

    webpack全局定义路径别名

      resolve: {
        extensions: ['.js', '.vue', '.json'],
        alias: {
          'vue$': 'vue/dist/vue.esm.js',
          '@': resolve('src'),
          '_c': resolve('src/components'),
          '_conf': resolve('config')
        }
      },
    

    请求

    Axios:https://www.kancloud.cn/yunye/axios/234845

    Promise

    http://liubin.org/promises-book/

    脚本解析器

    nodejs:https://nqdeng.github.io/7-days-nodejs/#1.1
    https://www.runoob.com/nodejs/nodejs-tutorial.html

    包管理

    npm介绍:https://www.runoob.com/nodejs/nodejs-npm.html
    npm仓库:https://www.npmjs.com/

    相关文章

      网友评论

          本文标题:iveiw admin 2.0实战心得

          本文链接:https://www.haomeiwen.com/subject/titfkctx.html