分享一个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实现弹出层遮罩效果的简单实例
Mar 03 Javascript
在AngularJS应用中实现一些动画效果的代码
Jun 18 Javascript
深入理解JavaScript的React框架的原理
Jul 02 Javascript
IE8 内存泄露(内存一直增长 )的原因及解决办法
Apr 06 Javascript
一起学写js Calender日历控件
Apr 14 Javascript
Angularjs中$http以post请求通过消息体传递参数的实现方法
Aug 05 Javascript
vue实现文章内容过长点击阅读全文功能的实例
Dec 28 Javascript
angular5 httpclient的示例实战
Mar 12 Javascript
JavaScript中join()、splice()、slice()和split()函数用法示例
Aug 24 Javascript
微信小程序实现单列下拉菜单效果
Apr 25 Javascript
webpack 处理CSS资源的实现
Sep 27 Javascript
angular异步验证防抖踩坑实录
Dec 01 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
初级的用php写的采集程序
2007/03/16 PHP
PHP 获取MySQL数据库里所有表的实现代码
2011/07/13 PHP
解析CI的AJAX分页 另类实现方法
2013/06/27 PHP
php随机显示指定文件夹下图片的方法
2015/07/13 PHP
Flash+XML滚动新闻代码 无图片 附源码下载
2007/11/22 Javascript
jQuery1.9.1针对checkbox的调整方法(prop)
2014/05/01 Javascript
流量统计器如何鉴别C#:WebBrowser中伪造referer
2015/01/07 Javascript
14个有用的Jquery技巧分享
2015/01/08 Javascript
JavaScript插件化开发教程 (二)
2015/01/27 Javascript
js仿黑客帝国字母掉落效果代码分享
2020/11/08 Javascript
jQuery封装的屏幕居中提示信息代码
2016/06/08 Javascript
Ajax+FormData+javascript实现无刷新表单信息提交
2016/10/24 Javascript
Javascript 引擎工作机制详解
2016/11/30 Javascript
JavaScript之underscore_动力节点Java学院整理
2017/07/03 Javascript
详解基于Node.js的微信JS-SDK后端接口实现代码
2017/07/15 Javascript
jQuery remove()过滤被删除的元素(推荐)
2017/07/18 jQuery
解决Nodejs全局安装模块后找不到命令的问题
2018/05/15 NodeJs
在vue项目中引入高德地图及其UI组件的方法
2018/09/04 Javascript
vue+element 模态框表格形式的可编辑表单实现
2019/06/07 Javascript
[02:51]DOTA2 Supermajor小组分组对阵抽签仪式
2018/06/01 DOTA
Python中获取网页状态码的两个方法
2014/11/03 Python
用Python编写简单的定时器的方法
2015/05/02 Python
Python冲顶大会 快来答题!
2018/01/17 Python
ubuntu安装sublime3并配置python3环境的方法
2018/03/15 Python
详解安装mitmproxy以及遇到的坑和简单用法
2019/01/21 Python
Python可变对象与不可变对象原理解析
2020/02/25 Python
python输出国际象棋棋盘的实例分享
2020/11/26 Python
What's the difference between Debug and Trace class? (Debug类与Trace类有什么区别)
2013/09/10 面试题
如何进行Linux分区优化
2013/02/12 面试题
工作态度检讨书
2014/02/11 职场文书
机关工会开展学习雷锋活动总结
2014/03/01 职场文书
诉前财产保全担保书
2014/05/20 职场文书
物理分数没达标检讨书
2014/09/13 职场文书
素质拓展训练感想
2015/08/07 职场文书
php引用传递
2021/04/01 PHP
JS实现数组去重的11种方法总结
2022/04/04 Javascript