基于vue-cli3的vue项目框架

一个vue项目

前言

  • 基于vue-cli3
  • 麻雀虽小,五脏六腑俱全
  • Vue常用属性与方法
  • 集成vue-router、vuex、axios及element-ui等插件
  • 自定义指令、全局过滤器
  • 封装全局使用.svg图标的组件
  • 源码

预览

封装Icon组件

src/components/IconSvg.vue

<template>
  <svg class="svg-icon" aria-hidden="true">
    <use :xlink:href="iconName"></use>
  </svg>
</template>

<script>
export default {
  props: {
    iconClass: {
      type: String,
      required: true
    }
  },
  computed: {
    iconName () {
      return `#icon-${this.iconClass}`
    }
  }
}
</script>

<style lang="less" scoped>
.svg-icon {
   1em;
  height: 1em;
  fill: currentColor;
  overflow: hidden;
  vertical-align: -0.15em;
}
</style>

src/icons/index.js

import Vue from 'vue'
import IconSvg from '@/components/IconSvg'

const requireAll = requireContext => requireContext.keys().map(requireContext)
// 引入相对路径svg文件夹下所有.svg文件
const req = require.context('./svg', false, /.svg$/)
requireAll(req)

Vue.component('icon-svg', IconSvg)

在vue.config.js配置svg-sprite-loader

const path = require('path')

module.exports = {
  chainWebpack: config => {
    // svg-config
    const svgRule = config.module.rule('svg')
    svgRule.uses.clear()
    svgRule.exclude.add(/node_modules/)
    svgRule
      .test(/.svg$/)
      .use('svg-sprite-loader')
      .loader('svg-sprite-loader')
      .options({
        symbolId: 'icon-[name]'
      })

    // 修改images loader 添加svg处理
    const imagesRule = config.module.rule('images')
    imagesRule.exclude.add(path.resolve('src/icons')) // 必须
    imagesRule
      .test(/.(png|jpe?g|gif|svg)(?.*)?$/)
  }
}

在main.js引入 import './icons'

使用组件

<icon-svg iconClass='edit'></icon-svg>

自定义指令

src/directive/waves/index.js

export default {
  bind: (el, binding) => {
    // 此处内容较多 详情参见源码   
  }
}

在main.js注册所有自定义指令

import Vue from 'vue'
import directives from '../src/directive'

// 指令
for (const key of Object.keys(directives)) {
  Vue.directive(key, directives[key])
}

定义全局过滤器

定义和注册与自定义指令类似,详情参见源码

路由

import Vue from 'vue'
import Router from 'vue-router'
import NProgress from 'nprogress' // 页面加载进度条
import 'nprogress/nprogress.css'

Vue.use(Router)

const constantRoutes = [
  {
    path: '/404',
    component: () => import('@/views/ErrorPage')
  },
  {
    path: '*',
    redirect: '/404'
  },
  {
    path: '/login',
    name: '登录',
    component: () => import('@/views/Login')
  },
  {
    path: '/',
    name: '首页',
    icon: 'home',
    component: () => import('@/views/Home')
  }
]

export const asyncRoutes = [
  ...constantRoutes,
  {
    path: '/svgIcon',
    name: 'svg图标',
    icon: '',
    component: () => import('@/views/IconView')
  },
  {
    path: '/computedAndWatch',
    name: '计算与侦听',
    icon: '',
    component: () => import('@/views/ComputedWatch')
  },
  {
    path: '/directives',
    name: '自定义指令',
    icon: '',
    component: () => import('@/views/MyDirective')
  },
  {
    path: '/filters',
    name: '过滤器',
    icon: '',
    component: () => import('@/views/MyFilter')
  },
  {
    path: '/vuex',
    name: 'Vuex',
    icon: '',
    component: () => import('@/views/VuexView')
  }
]

const router = new Router({
  routes: asyncRoutes
})

// 导航首位,可在此做路由权限过滤
router.beforeEach((to, form, next) => {
  NProgress.start()
  next()
})

router.afterEach(() => {
  NProgress.done()
})

export default router

vuex基本结构

src/store/index.js

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

const store = new Vuex.Store({
  state: {
    count: 1,
    user: window.localStorage.getItem('user') || '',
    token: window.localStorage.getItem('token') || ''
  },
  getters: {
    // 类似computed属性
    double: state => {
      return state.count * 2
    },
    isAuth: state => !!state.token
  },
  mutations: {
    increment (state) {
      state.count++
    },
    login (state, payload) {
      const { userName, token } = payload
      state.user = userName
      state.token = token
      window.localStorage.setItem('user', userName)
      window.localStorage.setItem('token', token)
    },
    logout (state) {
      state.user = ''
      state.token = ''
      window.localStorage.removeItem('user')
      window.localStorage.removeItem('token')
    }
  },
  actions: {
    // 异步函数
    login ({ commit }, payload) {
      commit('login', payload)
    },
    logout ({ commit }) {
      commit('logout')
    }
  }
})

export default store

组建内使用store

// 使用辅助函数
<script>
import { mapGetters, mapActions } from 'vuex'

export default {
  computed: {
    ...mapGetters([
      'isAuth'
    ])
  },
  data () {
  },
  methods: {
    ...mapActions([
      'login',
      'logout'
    ]),
    handleLogin () {
     this.login({...loginMsg})
    },
    handleLogout () {
      this.logout()
    }
  }
}
</script>
原文地址:https://www.cnblogs.com/lshilin/p/10445219.html