分享一个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 相关文章推荐
自动检查并替换文本框内的字符
Jun 30 Javascript
jquery 清空file域示例(兼容个浏览器)
Oct 11 Javascript
详解JS 比较两个Json对象的值是否相等的实例
Nov 20 Javascript
使用jQuery和PHP实现类似360功能开关效果
Feb 12 Javascript
封装好的js判断操作系统与浏览器代码分享
Jan 09 Javascript
JavaScript实现数组在指定位置插入若干元素的方法
Apr 06 Javascript
JavaScript中数据结构与算法(一):栈
Jun 19 Javascript
jQuery实现背景滑动菜单
Dec 02 Javascript
JS求解三元一次方程组值的方法
Jan 03 Javascript
详解使用Vue.Js结合Jquery Ajax加载数据的两种方式
Jan 10 Javascript
token 机制和实现方式
Dec 15 Javascript
Vue+scss白天和夜间模式切换功能的实现方法
Jan 05 Vue.js
使用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
php反弹shell实现代码
2009/04/22 PHP
dhtmlxTree目录树增加右键菜单以及拖拽排序的实现方法
2013/04/26 PHP
浅析PHP编程中10个最常见的错误
2014/08/08 PHP
php密码生成类实例
2014/09/24 PHP
Yii2.0多文件上传实例说明
2017/07/24 PHP
Laravel如何使用数据库事务及捕获事务失败后的异常详解
2017/10/23 PHP
PHP中使用mpdf 导出PDF文件的实现方法
2018/10/22 PHP
php curl获取https页面内容,不直接输出返回结果的设置方法
2019/01/15 PHP
laravel框架中间件简单使用方法示例
2020/01/25 PHP
浅析PHP反序列化中过滤函数使用不当导致的对象注入问题
2020/02/15 PHP
Div自动滚动到末尾的代码
2008/10/26 Javascript
使用jquery mobile做幻灯播放效果实现步骤
2013/01/04 Javascript
JS动态添加Table的TR,TD实现方法
2015/01/28 Javascript
js判断图片加载完成后获取图片实际宽高的方法
2016/02/25 Javascript
浅谈jquery上下滑动的注意事项
2016/10/13 Javascript
js实现右键菜单功能
2016/11/28 Javascript
JavaScript组成、引入、输出、运算符基础知识讲解
2016/12/08 Javascript
vue mintui-Loadmore结合实现下拉刷新和上拉加载示例
2017/10/12 Javascript
详解mpvue小程序中怎么引入iconfont字体图标
2018/10/01 Javascript
微信小程序实现禁止分享代码实例
2019/10/19 Javascript
在VUE中使用lodash的debounce和throttle操作
2020/11/09 Javascript
原生JS实现pc端轮播图效果
2020/12/21 Javascript
python分割和拼接字符串
2013/11/01 Python
python在windows下创建隐藏窗口子进程的方法
2015/06/04 Python
Python实现按照指定要求逆序输出一个数字的方法
2018/04/19 Python
Python3非对称加密算法RSA实例详解
2018/12/06 Python
在PyCharm中遇到pip安装 失败问题及解决方案(pip失效时的解决方案)
2020/03/10 Python
澳洲健康食品网上商店:Aussie Health Products
2018/06/15 全球购物
送温暖献爱心活动总结
2014/07/08 职场文书
研究生就业推荐表导师评语
2014/12/31 职场文书
环境建议书
2015/02/04 职场文书
学生犯错保证书
2015/05/09 职场文书
毕业论文答辩演讲稿
2015/06/23 职场文书
教师节简报
2015/07/20 职场文书
python自动化调用百度api解决验证码
2021/04/13 Python
Java 多态分析
2022/04/26 Java/Android