分享一个vue项目“脚手架”项目的实现步骤


Posted in Javascript onMay 26, 2019

搭建缘由

源于公司每次新启动一个由多人协同开发的项目都由负责人初始化项目之后,每个人再去从私服pull一下项目才开始开发。但是每次初始化工程都是一步步的造轮子,一个个依赖去安装,新建一个个不同功能的文件夹,而每个负责人所初始化的项目目录、以及模块引入方式参差不齐,以至于开发中后期因每个人开发风格的不同导致git提交时总会产生各种各样的“冲突”,也会产生后期代码维护成本增加,所以就有必要考虑一下做一个统一的类似“脚手架”的功能了,用来给团队开发带来便捷的、统一的、易扩展的项目基础。

预实现的功能

  • 公共样式统一管理,全局sass的友好引入
  • 公共js统一管理
  • 解决vue脚手架初始化的部分问题
  • 路由形式、接口统一管理
  • store模块化管理
  • 定义vue前端项目必用的方法
  • 修改好统一的config配置
  • 全局混入/指令的封装

必要的依赖项

  • node-sass sass sass-resources sass-loader sass-recources-loader
  • vuex vuex-persistedstate
  • axios
  • babel-polyfill

项目目录如下

分享一个vue项目“脚手架”项目的实现步骤

配置公共sass

目录assets>scss文件形式

mixin.scss内容详见mixin公共sass函数

common.scss内容如下

@import './mixin.scss'; // 公共函数
@import './icomoon.css'; //字体图标
@import './wvue-cli.scss'; //项目公共样式

修改utils.js引入commom.css,就不用在main.js 或其他项目中的页面引入了

//57行开始
function resolveResouce(name) {
  return path.resolve(__dirname, '../src/assets/scss/' + name);
 }
 function generateSassResourceLoader() {
   var loaders = [
  cssLoader,
  // 'postcss-loader',
  'sass-loader',
  {
    loader: 'sass-resources-loader',
    options: {
     // it need a absolute path
     resources: [resolveResouce('common.scss')]  
    }
  }
   ];
   if (options.extract) {
  return ExtractTextPlugin.extract({
   use: loaders,
   fallback: 'vue-style-loader'
  })
   } else {
  return ['vue-style-loader'].concat(loaders)
   }
 }
 // 注意这里
 return {
  css: generateLoaders(),
  postcss: generateLoaders(),
  less: generateLoaders('less'),
  sass: generateSassResourceLoader(),
  scss: generateSassResourceLoader(),
  stylus: generateLoaders('stylus'),
  styl: generateLoaders('stylus')
 }

接口统一管理

js目录下的urlConfig.js

// 开发环境用config下proxyTable的代理地址
var BASE_URL = '/api';
var isPro = process.env.NODE_ENV === 'production'
if(isPro){
  BASE_URL= 'http://113.113.113.113:8011' //生产环境下的地址
}

const UrlConfig = {
 getUserInfo:BASE_URL +'user/getinfo', //获取用户信息
}
export default {
 UrlConfig
};

页面使用方式例如:

this.$http.post(this.URL_CONFIG.UrlConfig.getUserInfo,datas)
.then(res =>{
  console.log(res)
}).catch(error =>{
  console.log(error)
})
// URL_CONFIG见全局混入中的方法

全局混入管理

全局混入主要用于项目中每个页面或模块都会用到的函数方法、计算属性、过滤方法等。

文件所属components>common>mixins>index.js

//以下只是其中一种思路
import URL_CONFIG from '@/assets/js/urlConfig.js';
const mixin = {
   data(){
   return {
    URL_CONFIG:URL_CONFIG
   },
   methods: {
   //像时间戳转换这种方法大多数项目都能用的到,可以写在filter里也可以写在computed里,取决于运用场景
   formatDate(date, fmt) {
     if (/(y+)/.test(fmt)) {
       fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length));
     }
     let o = {
       'M+': date.getMonth() + 1,
       'd+': date.getDate(),
       'h+': date.getHours(),
       'm+': date.getMinutes(),
       's+': date.getSeconds()
     };
     for (let k in o) {
       if (new RegExp(`(${k})`).test(fmt)) {
         let str = o[k] + '';
         fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? str : this.padLeftZero(str));
       }
     }
     return fmt;
   },
   padLeftZero(str) {
     return ('00' + str).substr(str.length);
   },
   loadPage(path,params){
    this.$router.push({
     path:path,
     query:params
    })
   }
  }
}
export default mixin

在main.js中引入

//自定义全局mixin
import mixins from '@/components/common/mixins'
Vue.mixin(mixins)

全局指令管理

全局指令主要用于各个项目中由于vue指令不能满足需求,自定义的指令形式,在页面编写过程中可以带来很多的便利。

文件所属components>common>directive>index.js

//以下只是一种思路,主要目的是分享自定义指令的方法
let mydirective = {}
mydirective.install = function (Vue) {
 //背景颜色
 Vue.directive('bg', {
  bind(el, binding) {
    el.style.color = '#f6f6f6';
  }
 }),
 //主题色
 Vue.directive('color', {
  bind(el, binding) {
    el.style.color = '#42E5D3';
  }
 }),
 Vue.directive('theme',function(el){
  el.style.color = '#42E5D3'
  el.style.background = '#f6f6f6'
 }),
 // 图片未加载完之前先用随机背景色占位
 Vue.directive('img', {
 inserted:function (el, binding) {
  var color = Math.floor(Math.random()*1000000);
  el.style.backgroundColor = "#" + color;
  var img = new Image();
  img.src = binding.value;
  img.onload = function(){
   el.style.backgroundImage = 'url('+ binding.value +')'
  }
 }
 })
}

export default mydirective;

在main.js中引入

//自定义全局指令
import directive from '@/components/common/directive'
Vue.use(directive)

store 模块化管理

store模块化管理主要是满足不同开发人员的需求、避免使用单一store文件导致命名冲突。同时在main里定义了统一的模块文件满足大多数项目开发的场景需求。

文件所属store>main.js

import Vue from 'vue'
import Vuex from 'vuex'
import router from '@/router'
import Axios from 'axios'
import createPersistedState from 'vuex-persistedstate'

import baseInfo_store from './baseInfo'
Vue.use(Vuex)

const store = new Vuex.Store({
// 用不同的模块管理vuex存储数据
 modules: {
  baseInfoStore: baseInfo_store, //userInfo模块
 },
 plugins: [createPersistedState({
   storage: window.sessionStorage 
 })]
})
//切换页面一般需要的loading动画状态
store.registerModule('pageSwitch', {
 state: {
  isLoading: false
 },
 mutations: {
  updateLoadingStatus (state, payload) {
   state.isLoading = payload.isLoading
  }
 }
})
//切换路由的同时切换title
router.beforeEach(function (to, from, next) {
 if(to.meta.title){
  document.title = to.meta.title
 }
 store.commit('updateLoadingStatus', {isLoading: true})
 next()
})

router.afterEach(function (to) {
 store.commit('updateLoadingStatus', {isLoading: false})
})
//ajax请求的动画状态
store.registerModule('ajaxSwitch', {
 state: {
  ajaxIsLoading: false,
  ajaxIsPrompt: false,
 },
 mutations: {
  ajaxStar (state) {
   state.ajaxIsLoading = true
  },
  ajaxEnd (state) {
   state.ajaxIsLoading = false
  },
  ajaxPromptShow (state) {
   state.ajaxIsPrompt = true
  },
  ajaxPromptHide (state) {
   state.ajaxIsPrompt = false
  }
 },
 getter : {
  ajaxIsLoading: state => state.ajaxIsLoading
 }
})
//请求拦截
Axios.interceptors.request.use(config => {
 store.commit('ajaxStar')
 return config;
})
//响应拦截
Axios.interceptors.response.use(config => {
 //需要拦截的请求头
 return config
})
export default store;

在main.js引入

import store from '@/store/main.js';

main.js的最终形式

import Vue from 'vue'
import App from './App'
import router from './router'

import axios from 'axios';
import "babel-polyfill";
import store from '@/store/main.js';
//自定义全局mixin
import mixins from '@/components/common/mixins'
Vue.mixin(mixins)
//自定义全局指令
import directive from '@/components/common/directive'
Vue.use(directive)

Vue.config.productionTip = false
Vue.prototype.$http = axios;
/* eslint-disable no-new */
new Vue({
 el: '#app',
 router,
 store,
 components: { App },
 template: '<App/>'
})

解决vue-cli 初始配置的打包路径问题

其实这个在上面文件中已经有体现了,在这里再次提及一下。

步骤1:修改config>index.js文件

将build{ }下的assetsPublicPath改为如下

assetsPublicPath: './',

步骤2:修改build>utils.js文件

找到 fallback: 'vue-style-loader',在其下加入下面这一行

publicPath: '../../'

结语

至此,一个基本完备的vue项目“脚手架”就完成了,以后每次初始化项目都可以按照这套方案来进行,省去了很多协作开发的交流环节,形成了能够满足大多数项目的目录及文件构成形式,将此项目托管至私服每次初始化项目只需拉取这个“脚手架”便能省区不少初始化项目的时间,岂不美哉!

此“脚手架”项目已开源至github,欢迎大家提出建议和互相交流,同时也可随意将项目拉下来进行使用。

A scaffolding based on vue.js

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
Jquery 表单取值赋值的一些基本操作
Oct 11 Javascript
jQuery 1.5最新版本的改进细节分析
Jan 19 Javascript
用jQuery中的ajax分页实现代码
Sep 20 Javascript
基于SVG的web页面图形绘制API介绍及编程演示
Jun 28 Javascript
基于MVC3方式实现下拉列表联动(JQuery)
Sep 02 Javascript
跟我学习javascript的call(),apply(),bind()与回调
Nov 16 Javascript
简单的JS时钟实例讲解
Jan 13 Javascript
基于jQuery的select下拉框选择触发事件实例分析
Nov 18 Javascript
如何在 Vue.js 中使用第三方js库
Apr 25 Javascript
用js将long型数据转换成date型或datetime型的实例
Jul 03 Javascript
详解无限滚动插件vue-infinite-scroll源码解析
May 12 Javascript
使用axios请求时,发送formData请求的示例
Oct 29 Javascript
使用JS判断页面是首次被加载还是刷新
May 26 #Javascript
Node.js 多进程处理CPU密集任务的实现
May 26 #Javascript
小程序封装路由文件和路由方法(5种全解析)
May 26 #Javascript
vue2.0 实现富文本编辑器功能
May 26 #Javascript
富文本编辑器vue2-editor实现全屏功能
May 26 #Javascript
vue中$refs, $emit, $on, $once, $off的使用详解
May 26 #Javascript
我要点爆”微信小程序云开发之项目建立与我的页面功能实现
May 26 #Javascript
You might like
使用GROUP BY的时候如何统计记录条数 COUNT(*) DISTINCT
2011/04/23 PHP
PHP+MySQL删除操作实例
2015/01/21 PHP
浅析PHP7 的垃圾回收机制
2019/09/06 PHP
Laravel自动生成UUID,从建表到使用详解
2019/10/24 PHP
JavaScript 匿名函数(anonymous function)与闭包(closure)
2011/10/04 Javascript
JavaScript中常用的运算符小结
2012/01/18 Javascript
纯JS实现动态时间显示代码
2014/02/08 Javascript
jquery如何判断表格同一列不同行input数据是否重复
2014/05/14 Javascript
javascript常用的正则表达式实例
2014/05/15 Javascript
jQuery遍历之next()、nextAll()方法使用实例
2014/11/08 Javascript
jQuery实现购物车表单自动结算效果实例
2015/08/10 Javascript
AngularJS利用Controller完成URL跳转
2016/08/09 Javascript
jQuery学习笔记——jqGrid的使用记录(实现分页、搜索功能)
2016/11/09 Javascript
JavaScript中附件预览功能实现详解(推荐)
2017/08/15 Javascript
使用JavaScript实现点击循环切换图片效果
2017/09/03 Javascript
ES6入门教程之变量的解构赋值详解
2019/04/13 Javascript
Vue 刷新当前路由的实现代码
2019/09/26 Javascript
python+VTK环境搭建及第一个简单程序代码
2017/12/13 Python
解决python2 绘图title,xlabel,ylabel出现中文乱码的问题
2019/01/29 Python
Win下PyInstaller 安装和使用教程
2019/12/25 Python
np.random.seed() 的使用详解
2020/01/14 Python
Python实现打包成库供别的模块调用
2020/07/13 Python
Python+Opencv身份证号码区域提取及识别实现
2020/08/25 Python
检测浏览器是否支持html5视频的代码
2013/03/28 HTML / CSS
兰蔻加拿大官方网站:Lancome加拿大
2016/08/05 全球购物
信息部岗位职责
2013/11/12 职场文书
2013年研究生毕业感言
2014/02/06 职场文书
教师自我剖析材料(群众路线)
2014/09/29 职场文书
2014年材料员工作总结
2014/11/19 职场文书
2015年保育员个人工作总结
2015/05/13 职场文书
贫困证明怎么写
2015/06/16 职场文书
新学期主题班会
2015/08/17 职场文书
学习社交礼仪心得体会
2016/01/22 职场文书
浅谈Redis的几个过期策略
2021/05/27 Redis
Python装饰器详细介绍
2022/03/25 Python
CSS中calc(100%-100px)不加空格不生效
2023/05/07 HTML / CSS