• 基于vue2.0的一个系统


    前言

    这是一个用vue做的单页面管理系统,这里只是介绍架子搭建思路

    前端架构

    沿用Vue全家桶系列开发,主要技术栈:vue2.x+vue-router+vuex+element-ui1.x+axios

    工程目录

     

    项目浅析

    webpack打包配置

    webpack的配置主要是vue-cli生成的,经过一些简化修改如下

    webpack.config

      1 const path = require('path');
      2 const webpack = require('webpack');
      3 const cssnext = require('postcss-cssnext');
      4 const atImport = require('postcss-import');
      5 const cssvariables = require('postcss-css-variables');
      6 const ExtractTextPlugin = require('extract-text-webpack-plugin');
      7 const HtmlWebpackPlugin = require('html-webpack-plugin');
      8 const CopyWebpackPlugin = require('copy-webpack-plugin');
      9 
     10 const devSrc = 'http://localhost:8099/static/';
     11 const devOutputPath = '../dist/static';
     12 const prodSrc = './static/';
     13 const prodOutputPath = '../dist/static';
     14 
     15 const Util = require('./util')
     16 
     17 const PATH_DIST = {
     18     font: 'font/',
     19     img: 'image/',
     20     css: 'css/',
     21     js: 'js/'
     22 };
     23 const isProduction = process.env.NODE_ENV === 'production';   //环境,dev、production
     24 console.log('isProduction',isProduction)
     25 const host = isProduction ? prodSrc : devSrc;
     26 const outputPath = isProduction ? prodOutputPath : devOutputPath;
     27 const extractElementUI = new ExtractTextPlugin(PATH_DIST.css + 'element.css' + (isProduction ? '?[contenthash:8]' : ''));
     28 const extractCSS = new ExtractTextPlugin(PATH_DIST.css + 'app.css' + (isProduction ? '?[contenthash:8]' : ''));
     29 
     30 module.exports = function (env) {
     31     let Config = {
     32         entry: {
     33             element: ['element-ui'],
     34             vue: ['vue', 'axios', 'vue-router', 'vuex'],
     35             app: './src/main.js'
     36         },
     37         output: {
     38             path: path.resolve(__dirname, outputPath),
     39             publicPath: host,
     40             filename: PATH_DIST.js + '[name].js' + (isProduction ? '?[chunkhash:8]' : '')
     41         },
     42         module: {
     43             rules: [
     44                 {
     45                     test: /.vue$/,
     46                     loader: 'vue-loader',
     47                     options: {
     48                         loaders: {
     49                             scss:Util.generateSassResourceLoader(),
     50                             sass:Util.generateSassResourceLoader(),
     51                             css: extractCSS.extract({
     52                                 use: 'css-loader!postcss-loader',
     53                                 fallback: 'vue-style-loader'
     54                             })
     55                         }
     56                     }
     57                 },
     58                 {
     59                     test: function (path) {
     60                         if (/.css$/.test(path) && (/element-ui/).test(path)) {
     61                             return true;
     62                         } else {
     63                             return false;
     64                         }
     65                     },
     66                     loader: extractElementUI.extract({
     67                         use: 'css-loader!postcss-loader'
     68                     })
     69                 },
     70                 {
     71                     test: function (path) {
     72                         if (/.css$/.test(path) && !(/element-ui/).test(path)) {
     73                             return true;
     74                         } else {
     75                             return false;
     76                         }
     77                     },
     78                     loader: extractCSS.extract({
     79                         use: 'css-loader!postcss-loader'
     80                     })
     81                 },
     82                 {
     83                     test: /.js$/,
     84                     loader: 'babel-loader',
     85                     exclude: /node_modules/
     86                 },
     87                 {
     88                     test: /.(woff|svg|eot|ttf)??.*$/,  //字体文件
     89                     loader: 'file-loader',
     90                     options: {
     91                         publicPath:'../font/',
     92                         outputPath:PATH_DIST.font,
     93                         name: '[name].[ext]'
     94                     }
     95                 },
     96                 {
     97                     test: /.(gif|jpg|png)??.*$/,  //图片
     98                     loader: 'file-loader',
     99                     options: {
    100                         name: PATH_DIST.img + '[name].[ext]'
    101                     }
    102                 },
    103                 {
    104                     test: /.scss$/,
    105                     use: Util.generateSassResourceLoader()
    106                 },
    107                 {
    108                     test: /.sass/,
    109                     use: Util.generateSassResourceLoader()
    110                 },
    111 
    112             ]
    113         },
    114         plugins: [
    115             new webpack.optimize.CommonsChunkPlugin({
    116                 name: ['element', 'vue']
    117             }),
    118             extractElementUI,
    119             extractCSS,
    120             new webpack.LoaderOptionsPlugin({
    121                 options: {
    122                     postcss: function () {
    123                         return [atImport({
    124                             path: [path.resolve(__dirname, '../src')]
    125                         }), cssnext, cssvariables];
    126                     }
    127                 },
    128                 minimize: isProduction
    129             }),
    130             new HtmlWebpackPlugin({
    131                 title: 'JD唯品会运营后台',
    132                 template: 'index.html',
    133                 filename: '../index.html',
    134                 inject: false,
    135                 chunks: ['element', 'vue', 'app']
    136             }),
    137             new webpack.DefinePlugin({
    138                 'process.env.NODE_ENV': isProduction ? '"production"' : '"development"'
    139             })
    140         ],
    141         performance: {
    142             hints: isProduction ? 'warning' : false
    143         },
    144         devtool: isProduction ? false : '#eval-source-map',
    145         resolve: {
    146             alias: {
    147                 'src': path.resolve(__dirname, '../src'),
    148                 'scss':path.resolve(__dirname,'../src/scss/'),
    149                 'config':path.resolve(__dirname, '../src/config/'),
    150             }
    151         }
    152     };
    153 
    154     if (isProduction) {
    155         Config.plugins = Config.plugins.concat([
    156             new webpack.optimize.UglifyJsPlugin({
    157                 sourceMap: true,
    158                 compress: {
    159                     warnings: false
    160                 }
    161             })
    162         ]);
    163     } else {
    164         Config.devServer = {
    165             historyApiFallback: true,
    166             publicPath: '/static/',
    167             disableHostCheck: true,
    168             noInfo: true,
    169             hot: true,
    170             host: 'localhost',
    171             port: 8099,
    172             watchOptions: {
    173                 poll: false,
    174                 ignored: ['node_modules/**', 'config/**', 'common/**', 'dist/**']
    175             },
    176             headers: {
    177                 'Access-Control-Allow-Origin': '*'
    178             }
    179         };
    180     }
    181     return Config;
    182 };
    View Code

    config用到的util

     1 let path = require('path')
     2 let ExtractTextPlugin = require('extract-text-webpack-plugin')
     3 function resolveResouce(name) {
     4   let src  = path.resolve(__dirname, '../src/assets/' + name);
     5   return src;
     6 }
     7 let cssLoader = {
     8   loader: 'css-loader',
     9   options: {
    10     minimize: process.env.NODE_ENV === 'production',
    11     sourceMap: process.env.NODE_ENV !== 'production'
    12   }
    13 }
    14 exports.generateSassResourceLoader = function (options) {
    15 
    16   let loaders = [
    17     'css-loader',
    18     'postcss-loader',
    19     'sass-loader', {
    20       loader: 'sass-resources-loader',
    21       options: {
    22         // it need a absolute path
    23         resources: [resolveResouce('mixin.scss')]
    24       }
    25     }
    26   ];
    27   return ExtractTextPlugin.extract({
    28       use: loaders,
    29       fallback: 'vue-style-loader'
    30     })
    31 }
    View Code

     src文件夹下的confg放一些东西

    ajax.js配置axios

     1 import axios from 'axios'
     2 import qs from 'qs'
     3 import store from './../store'
     4 import { Message } from 'element-ui'
     5 
     6 
     7 function getCookie(name) {
     8     var arr, reg = new RegExp("(^| )" + name + "=([^;]*)(;|$)");
     9     if (arr = document.cookie.match(reg)){
    10         return unescape(arr[2]);
    11     }
    12     else{
    13         return null;
    14     }
    15 }
    16 
    17 const X_CSRF_TOKEN = getCookie("pmsTp_token");
    18 
    19 const service = axios.create({
    20   timeout: 30000,                  // 请求超时时间
    21 })
    22 
    23 service.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded '; 
    24 
    25 //请求拦截
    26 service.interceptors.request.use((config) => {
    27   if (config.data&&config.data.noLoading) {
    28     delete config.data.noLoading;
    29   }else{    
    30     store.commit(STORE_TYPE.IS_LOADING,true);
    31   }
    32     //config.headers.X_CSRF_TOKEN  = X_CSRF_TOKEN
    33     //在发送请求之前做某件事
    34     if(config.method  === 'post'){
    35         config.data = qs.stringify(config.data);
    36     }
    37     return config;
    38 },(error) =>{
    39      console.log("错误的传参", 'fail');
    40     return Promise.reject(error);
    41 });
    42 //返回拦截
    43 service.interceptors.response.use((res) =>{
    44     store.commit(STORE_TYPE.IS_LOADING,false);
    45     if (res.data.code ==-300) {
    46       window.VM&&VM.$router.push({name:'redownload'});
    47       return Promise.reject(res);
    48     }
    49     //对响应数据做些事
    50     if(res.data.code<0){
    51       if (res.data&&res.data.msg) {
    52            Message({
    53             message: res.data.msg,
    54             type: 'error',
    55             showClose:true,
    56             duration: 5 * 1000
    57           })
    58 
    59         return Promise.reject(res);   
    60         }
    61     }
    62     return res;
    63 }, (error) => {
    64     store.commit(STORE_TYPE.IS_LOADING,false);
    65     console.log("网络异常", 'fail');
    66     return Promise.reject(error);
    67 });
    68 
    69 export default service
    View Code

    directive.js 一些自定义指令(暂时只是权限控制)

     1 let install = (Vue, options= {}) => {
     2 
     3     //权限指令
     4     Vue.directive("permission", {
     5         bind:  function(el, binding) {
     6             let permission = binding.value
     7             let btnCodeList = localStorage.getItem('btnCodeList') || [];  
     8             if (btnCodeList.indexOf(permission) < 0 ) {
     9                 el.remove() 
    10             }
    11         } 
    12     });
    13 
    14 }
    15 
    16 export default {
    17     install
    18 }
    View Code

    mixin.js 只是定义一些全局用的方法

     1 let jqMixin = {
     2     methods: {
     3         goto(path) {
     4             if (path && typeof path === 'string') {
     5                 if (/^//.test(path)) {
     6                     this.$router.push(path);
     7                 } else {
     8                     this.$router.push([this.$route.fullPath, path].join('/'));
     9                 }
    10             } else if (typeof path === 'number') {
    11                 this.$router.go(path);
    12             }
    13         },
    14         logout(){
    15              window.location.href = window.location.protocol + '//' + window.location.host + '/' + "logout";
    16          },
    17         login(){
    18               window.location.reload();            
    19          },
    20         queryVauleByMap(map, value, returnKey = "name", key = "id") {
    21             for (var i = map.length - 1; i >= 0; i--) {
    22                 if (map[i][key] == value) {
    23                     return map[i][returnKey]
    24                 }
    25             }
    26         },
    27         formatDate(val, format) {
    28             if (!val) return '';
    29             let d;
    30             if (typeof val == 'number') {
    31                 d = new Date(val);
    32             } else if (val instanceof Date) {
    33                 d = val;
    34             }
    35             var o = {
    36                 "m+": d.getMonth() + 1, //月份
    37                 "d+": d.getDate(), //
    38                 "h+": d.getHours(), //小时
    39                 "i+": d.getMinutes(), //
    40                 "s+": d.getSeconds(), //
    41                 "q+": Math.floor((d.getMonth() + 3) / 3), //季度
    42                 "S": d.getMilliseconds() //毫秒
    43             };
    44             if (/(y+)/.test(format))
    45                 format = format.replace(RegExp.$1, (d.getFullYear() + "").substr(4 - RegExp.$1.length));
    46             for (var k in o)
    47                 if (new RegExp("(" + k + ")").test(format))
    48                     format = format.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
    49             return format;
    50         },
    51         getStringfy(obj) {
    52             let str = '';
    53             for (let key in obj) {
    54                 str += ('&' + key + '=' + obj[key]);
    55             }
    56             return str.substr(1);
    57         },
    58         copyObj(obj) {
    59             var o = {}
    60             for (var i in obj) {
    61                 if (Object.prototype.toString.call(obj[i]) == '[object Object]' || Object.prototype.toString.call(obj[i]) == '[object Array]' ) {
    62                     o[i] = this.copyObj(obj[i]);
    63                 }else{
    64                     o[i] = obj[i];
    65                 }
    66             }
    67             return o;
    68         }, 
    69         handleSizeChange(val) {
    70             this.$store.commit(this.paramType,{
    71               pageIndex:1,
    72               pageSize:val,
    73             });
    74             this.$store.dispatch(this.queryType);
    75           },
    76         handleCurrentChange(val) {
    77               this.$store.commit(this.paramType,{
    78                 pageIndex:val,
    79               });
    80               this.$store.dispatch(this.queryType);
    81           },
    82         clear() {
    83             for (let key in this.queryParam) {
    84                 if (typeof this.queryParam[key] == "string") {
    85                     this.queryParam[key] = ""
    86                 } else {
    87                     this.queryParam[key] = -1
    88                 }
    89             }
    90         },
    91     },
    92 }
    93 let install = (Vue, options = {}) => {
    94     Vue.mixin(jqMixin);
    95 };
    96 
    97 export default {
    98     install
    99 };
    View Code

    constant.js 一些定死的枚举值

    1 const CONSTANT = {
    2     
    3 }
    4 export default CONSTANT
    View Code

     src文件夹下的router放路由配置

    structure.js 定义路由

     1 const structure = [{
     2     path: '/index',
     3     name: 'index',
     4     // redirect: '/scheduleList', //默认重定向跳转配置,暂时不开启 
     5     title: '首页',
     6     icon: 'fa-home',
     7     component: require('./../page/index/index.vue'),
     8     children: []
     9 },{
    10     path: '/redownload',
    11     name: 'redownload',
    12     // redirect: '/scheduleList', //默认重定向跳转配置,暂时不开启 
    13     title: '重新登录',
    14     icon: 'fa-home',
    15     component: require('./../page/redownload.vue'),
    16     children: []
    17 }, {
    18     path: '',
    19     name: 'promotions',
    20     title: '促销活动',
    21     children: [{
    22         path: '/promotions/fullMinus',
    23         name: 'promotions/fullMinus',
    24         title: '满减促销活动',
    25         component: require('./../page/promotions/list.vue'),
    26         children: [{
    27             path: '/viewPromotions/fullMinus/:actId/:actNo',
    28             name: 'viewPromotions/fullMinus',
    29             title: '查看满减促销活动',
    30             component: require('./../page/promotions/view.vue')
    31         }]
    32     },{
    33         path: '/promotions/discount',
    34         name: 'promotions/discount',
    35         title: '折扣促销活动',
    36         component: require('./../page/promotions/list.vue'),
    37         children: [{
    38             path: '/viewPromotions/discount/:actId/:actNo',
    39             name: 'viewPromotions/discount',
    40             title: '查看折扣促销活动',
    41             component: require('./../page/promotions/view.vue')
    42         }]
    43     },{
    44         path: '/promotions/buyFree',
    45         name: 'promotions/buyFree',
    46         title: '买免促销活动',
    47         component: require('./../page/promotions/list.vue'),
    48         children: [{
    49             path: '/viewPromotions/buyFree/:actId/:actNo',
    50             name: 'viewPromotions/buyFree',
    51             title: '查看买免促销活动',
    52             component: require('./../page/promotions/view.vue')
    53         }]
    54     },{
    55         path: '/promotions/nOptional',
    56         name: 'promotions/nOptional',
    57         title: 'N元任选促销活动',
    58         component: require('./../page/promotions/list.vue'),
    59         children: [{
    60             path: '/viewPromotions/nOptional/:actId/:actNo',
    61             name: 'viewPromotions/nOptional',
    62             title: '查看N元任选促销活动',
    63             component: require('./../page/promotions/view.vue')
    64         }]
    65     },{
    66         path: '/promotions/syncAct',
    67         name: 'promotions/syncAct',
    68         title: '同步结果页',
    69         component: require('./../page/promotions/syncAct.vue'),
    70         children: []
    71     },{
    72         path: '/promotions/innerpro',
    73         name: 'promotions/innerpro',
    74         title: '内部工具页面',
    75         component: require('./../page/promotions/innerpro.vue'),
    76         children: []
    77     }]
    78 }];
    79 export default {
    80     structure: structure
    81 };
    View Code

    受之前angular的配置影响,这里配置的children属性是基于业务逻辑下的子页面,并不是vue-router的children含义,因此需要遍历structure对象将路由配置全部提取出来

    因此有个index.js

     index.js生成配置路由

     1 import Vue from 'vue'
     2 import VueRouter from 'vue-router'
     3 import structure from './structure.js';
     4 import store from './../store';
     5 
     6 Vue.use(VueRouter)
     7 let getRoutes = ((items = [], fbreadcrumbs = []) => {
     8     let routes = [];
     9     let structureRoutes = [];
    10     items.forEach(item => {
    11         let route = {}
    12         let breadcrumbs = item.title ? fbreadcrumbs.concat({
    13             title: item.title,
    14             path: item.path,
    15         }) : fbreadcrumbs;
    16         if (item.path || item.path === '') {
    17             route.path = item.path;
    18             route.name = item.name;
    19             route.title = item.title;
    20             route.meta = {
    21                 breadcrumbs: breadcrumbs,
    22             };
    23             if (item.component) {
    24                 route.component = item.component;
    25             }
    26             if (item.redirect) {
    27                 route.redirect = item.redirect;
    28             }
    29             if (item.children && item.children.length) {
    30                 routes = routes.concat(getRoutes(item.children, breadcrumbs));
    31             }
    32             routes.push(route);
    33         } else {
    34             if (item.children && item.children.length) {
    35                 routes = routes.concat(getRoutes(item.children, breadcrumbs));
    36             }
    37         }
    38 
    39     });
    40     return routes;
    41 })
    42 
    43 const router = new VueRouter()
    44 router.afterEach(route => {
    45     store.commit(STORE_TYPE.COMMON_BREADCRUMBS_UPDATE, route.meta.breadcrumbs);
    46 });
    47 let routerData = getRoutes(structure.structure);
    48 router.addRoutes(routerData)
    49 export default {
    50     router: router
    51 }
    View Code

     src文件夹下的store放公共或者自己喜欢放的数据

    type.js 一些行为的事件名字(很鸡肋)

     1 let STORE_TYPE = {
     2     IS_LOADING: 'IS_LOADING',
     3     COMMON_PERMISSION: 'COMMON_PERMISSION',
     4     COMMON_BREADCRUMBS_UPDATE: 'COMMON_BREADCRUMBS_UPDATE',
     5     DEPT_LIST: 'DEPT_LIST',
     6     USER_INFO: 'USER_INFO',
     7     USER_CSRF_TOKEN: 'USER_CSRF_TOKEN',
     8     USER_PERMISSION: 'USER_PERMISSION',
     9     /*
    10         promotions
    11     */
    12     PROMOTIONS_DATA_INIT: 'PROMOTIONS_DATA_INIT',
    13     PROMOTIONS_PARAM: 'PROMOTIONS_PARAM',
    14     PROMOTIONS_PARAM_START: 'PROMOTIONS_PARAM_START',
    15     PROMOTIONS_CACHEPARAM: 'PROMOTIONS_CACHEPARAM',
    16     PROMOTIONS_LISTDATA: 'PROMOTIONS_LISTDATA',
    17     PROMOTIONS_REMOVE: 'PROMOTIONS_REMOVE',
    18     PROMOTIONS_ACTIVITYINFO: 'PROMOTIONS_ACTIVITYINFO',
    19     PROMOTIONS_GOODSINFO: 'PROMOTIONS_GOODSINFO',
    20     PROMOTIONS_GOODSPARAM: 'PROMOTIONS_GOODSPARAM',
    21     PROMOTIONS_SYNCSTATUS: 'PROMOTIONS_SYNCSTATUS',
    22     PROMOTIONS_SYNC: 'PROMOTIONS_SYNC',
    23     PROMOTIONS_BATCHSYNC: 'PROMOTIONS_BATCHSYNC',
    24     PROMOTIONS_SYNCACT: 'PROMOTIONS_SYNCACT',
    25 
    26 
    27 };
    28 if (window && !window.STORE_TYPE) {
    29     window.STORE_TYPE = STORE_TYPE;
    30 }
    31 export default {
    32     STORE_TYPE
    33 };
    View Code

    index.js 暴露给外部的vuex对象

     1 import Vue from 'vue'
     2 import Vuex from 'vuex'
     3 import './types'
     4 import common from './modules/common'
     5 import user from './modules/user'
     6 import promotions from './modules/promotions'
     7 
     8 Vue.use(Vuex)
     9 
    10 export default new Vuex.Store({
    11   modules: {
    12     common,
    13     user,
    14     promotions,
    15   }
    16 })
    View Code

    modules 放置各个vuex对象定义的文件夹

    这儿只帖个common.js的定义吧

     1 import axios from 'config/ajax.js'
     2 
     3 const state = {
     4     isLoading: false,
     5     permission: {},
     6     dept_list:[],
     7     breadcrumbs: [],
     8 }
     9 
    10 const getters = {
    11 }
    12 
    13 const mutations = {
    14     [STORE_TYPE.COMMON_PERMISSION](state, data) {
    15         if (JSON.stringify(state.permission) == '{}') {
    16             state.permission = data;
    17         }
    18     },
    19     [STORE_TYPE.IS_LOADING](state, data) {
    20         state.isLoading = data;
    21     },
    22     [STORE_TYPE.DEPT_LIST](state, data) {
    23         state.dept_list = data;
    24     },
    25     [STORE_TYPE.COMMON_BREADCRUMBS_UPDATE](state, breadcrumbs) {
    26         state.breadcrumbs = breadcrumbs;
    27     },
    28 }
    29 
    30 const actions = {  
    31     [STORE_TYPE.COMMON_PERMISSION]({
    32         commit
    33     }) {
    34         return axios.get("/common/getUserPermissions").then(res => {
    35             if (res.data.data) {
    36                 commit(STORE_TYPE.COMMON_PERMISSION, res.data.data);
    37                 return res.data.data;
    38             }
    39         });
    40     },
    41   
    42     [STORE_TYPE.DEPT_LIST]({
    43         commit
    44     }) {
    45         return axios.get("/common/getDepartment").then(res => {
    46             if (res.data.data) {
    47                 commit(STORE_TYPE.DEPT_LIST, res.data.data.children);
    48                 return res.data.data.children;
    49             }
    50         });
    51     },
    52   
    53 }
    54 
    55 export default {
    56     state,
    57     getters,
    58     mutations,
    59     actions
    60 }
    View Code

    全局vue对象模板 app.vue

     1 <template>
     2   <div id="app">
     3       <div id="loading" v-show="isLoading">
     4           <i class="loading-icon fa fa-spinner fa-spin"></i>
     5       </div>
     6       <bread></bread>
     7       <router-view class="mainInfor__inner"></router-view>  
     8     </div>
     9 </template>
    10 
    11 <script>
    12 import bread from './common/bread.vue'
    13 export default {
    14   name: 'app',
    15   data() {
    16     return {
    17       
    18     }
    19   },
    20   computed: {
    21     isLoading() {
    22       return this.$store.state.common.isLoading
    23     }
    24   },
    25   mounted() {
    26     window.store = this.$store;
    27   },
    28   components:{
    29     bread
    30   }
    31 
    32 }
    33 </script>
    34 
    35 <style rel="stylesheet/scss" lang="scss" scoped>
    36 #loading{ 
    37   position: fixed;
    38    100%;
    39   height: 100%;
    40   z-index: 10000;
    41   top: 0;
    42   left: 0;
    43   .loading-icon{
    44     height: 100px;
    45      100px; 
    46     display: block;
    47     top: 50%;
    48     left: 50%;
    49     margin-top: -50px;
    50     margin-left: -50px;
    51     font-size: 80px;
    52     color: #0072c5;
    53     position: fixed;
    54   }
    55 }
    56 </style>
    View Code

    废话了这么多,下面就来生成vue对象吧

    main.js如下

    import Vue from 'vue'
    import App from './App.vue'
    import store from './store/index.js'
    import router from './router/index.js'
    import ElementUI from 'element-ui'
    
    
    import jqMixin from './config/mixin.js'
    import jqDirective from './config/directive.js'
    import LazyRender from 'vue-lazy-render'
    import './config/constant.js'
    import './config/ajax.js'
    
    import '../element-ui/index.css' //element-ui默认主题UI 
    import '../font-awesome/css/font-awesome.min.css' //font-awesome字体插件: http://fontawesome.io/icons/
    import './assets/ui.scss'
    Vue.config.devtools = true;
    Vue.config.productionTip = false;
    
    
    Vue.use(ElementUI)
    Vue.use(jqMixin)
    Vue.use(jqDirective)
    Vue.use(LazyRender)
    localStorage.removeItem('newRoutePath');
    localStorage.removeItem('oldRoutePath');
    store.dispatch(STORE_TYPE.COMMON_PERMISSION).then((user) => {
        localStorage.setItem('btnCodeList', user.btnCodeList);
        window.VM = new Vue({
            el: '#app',
            store: store,
            router: router.router,
            render: h => h(App),
            watch:{
                $route:function (newVal,val) {
                    localStorage.setItem('newRoutePath',newVal.path);
                    localStorage.setItem('oldRoutePath',val.path);
                }
            }
        })
    },(data)=>{
        window.VM = new Vue({
            el: '#app',
            store: store,
            router: router.router,
            render: h => h(App),
        })
        // VM.$router.push({name:'redownload'})
    
    }).catch(e=>{
        console.log(e);
    })

    剩下的就是page文件夹放置各个页面的业务代码了,这儿就贴了

    源码都在这https://github.com/houpeace/vueProject 喜欢就去看看吧,记得加星哟~

  • 相关阅读:
    圆上的整点
    学习笔记:用线性筛算不太常见的函数
    解题报告: luogu P1972
    解题报告: luogu P3907
    替罪羊树详解
    解题报告:luogu P2787
    解题报告:luogu P4170
    解题报告:luogu P4933
    10、.运维就是一场没有硝烟的战争
    九、模板层(三)
  • 原文地址:https://www.cnblogs.com/peace1/p/vueProjectSystem.html
Copyright © 2020-2023  润新知