几个你不知道的技巧助你写出更优雅的vue.js代码


Posted in Javascript onJune 11, 2018

几个你不知道的技巧助你写出更优雅的vue.js代码

1. watch 与 computed 的巧妙结合

如上图,一个简单的列表页面。

你可能会这么做:

created(){
  this.fetchData()
 },
 
 watch: {
  keyword(){
   this.fetchData()
  }
 }

如果参数比较多,比如上图

  • 关键字筛选,
  • 区域筛选,
  • 设备ID筛选,
  • 分页数,
  • 每页几条数据,

可能会是这样:

data(){
 return {
  keyword:'',
  region:'',
  deviceId:'',
  page:1
 }
},
methods:{
 fetchData(paramrs={
  keyword:this.keyword,
  region:this.region,
  deviceId:this.deviceId,
  page:this.page,
 }){
  this.$http.get("/list",paramrs).then("do some thing")
 }
},
created(){
 this.fetchData()
},
watch: {
 keyword(data){
  this.keyword=data
  this.fetchData()
 },
 region(data){
  this.region=data
  this.fetchData()
 },
 deviceId(data){
  this.deviceId=data
  this.fetchData()
 },
 page(data){
  this.page=data
  this.fetchData()
 },
 requestParams(params){
  this.fetchData(params)
 }
}

不过这么写,明显有问题,主要是watch了很多参数,而且函数的处理都差不多,可以修改一下,通过methods处理

data(){
 return {
  keyword:'',
  region:'',
  deviceId:'',
  page:1
 }
},
methods:{
 paramsChange(paramsName,paramsValue){
  this[paramsName]=paramsValue
  this.fetchData()
 },
 fetchData(paramrs={
  keyword:this.keyword,
  region:this.region,
  deviceId:this.deviceId,
  page:this.page,
 }){
  this.$http.get("/list",paramrs).then("do some thing")
 }
},
created(){
 this.fetchData()
}

当然这么写,需要在模板里面每个参数change的地方绑定事件,并传递参数值,比如分页change时:

<el-pagination
 layout="total, prev, pager, next, jumper"
 :total="total"
 prev-text="上一页"
 next-text="下一页"
 @current-change="paramsChange('page',$event)"
 >
</el-pagination>

相比上面的各种watch,代码明显少了很多,但是还有一个问题,那就是要在template的很多地方绑定change事件。

最后,当然是使用我们重点推荐的computed + watch

data(){
 return {
  keyword:'',
  region:'',
  deviceId:'',
  page:1
 }
},
computed:{
 requestParams() {
  return {
   page: this.page,
   region: this.region,
   id: this.deviceId,
   keyword: this.keyword
  }
 }
},
methods:{
 fetchData(paramrs={
  keyword:this.keyword,
  region:this.region,
  deviceId:this.deviceId,
  page:this.page,
 }){
  this.$http.get("/list",paramrs).then("do some thing")
 }
},
watch: {
 requestParams: {
  handler: 'fetchData',
  immediate: true
 }
},

通过增加一个computed属性,watch这个属性并设置immediate为true,无需再手动绑定事件,相比之上的方法都要简洁。当然,缺点就是对性能稍微有些影响,不过问题不大。

2. 使用mixin提取公共部分

很多列表页其实使用的很多属性都是一样的,比如

  • 分页 page
  • 数量 size
  • 搜索关键 字keyword
  • 表格数据 tableData

这些公共的部分其实可以通过mixin来提取出来

/**
 * mixin/table.js
 */
export default {
 data() {
  return {
   keyword: '',
   requestKeyword: '',
   pages: 1,
   size: 10,
   total: 0,
   tableData: []
  }
 }
}

在要用到的页面

import mixin from '@/mixin/table'
export default {
 mixins: [mixin],
 data() {
  return {   
   selectRegion: '',
   selectDevice: '',
   deviceList: [],
  }
 }
 /* 其他代码 */
 ...

3. 自动注册全局组件

正常情况下,我们需要使用一个我们自己封装的组件时,需要先引入,再注册,最后才能在template模板中使用。

<template>
 <all-region :selectRegion="selectRegion" @region-change="selectRegion=$event"/>
</template>

<script>
import AllRegion from './baseButton'

export default {
 components: {
  AllRegion,
 }
}
</script>

当有多个页面需要用到这些组件时,那么就需要在每个需要的页面重复这些步骤。

为了简化这些步骤,可以考虑把这些组件作为全局组件来使用,这样每个页面需要时,就可以直接使用了。

不过还有一个问题,那就是需要我们手动的全局注册。

/* main.js */
import Component1 from '@/component/compenent1'
import Component2 from '@/component/compenent2'
import Component3 from '@/component/compenent3'

Vue.component('component1', Component1)
Vue.component('component2', Component2)
Vue.component('component3', Component3)

当组件多了以后,手动注册也变得繁琐起来,可以通过require.context()实现自动注册组件。

/**
 * main.js
 * 读取componetns下的vue文件并自动注册全局组件
 */
const requireComponent = require.context('./components', false, /\.vue$/)

requireComponent.keys().forEach(fileName => {

 const componentConfig = requireComponent(fileName)
 const componentName = fileName.replace(/^\.\//, '').replace(/\.vue/, '')

 Vue.component(componentName, componentConfig.default || componentConfig)
})

4. 自动注册vuex模块

之前我们是这么注册vuex模块的

/* module.js */

import alarm from './modules/alarm'
import history from './modules/history'
import factory from './modules/factory'
import contact from './modules/contact'
import company from './modules/company';
import deviceManage from './modules/device-manage'
import deviceModel from './modules/device-model'
import deviceActivation from './modules/device-activation'
import user from './modules/user'
import role from './modules/role'
import setAlarm from './modules/setAlarm'
import factoryMode from "./modules/factoryMode";
import ScreenDeviceWatch from './modules/screen-device-watch'
import ScreenDeviceForecast from './modules/screen-device-forecast'

export default {
 alarm,
 company,
 deviceManage,
 deviceModel,
 user,
 factory,
 contact,
 deviceActivation,
 history,
 role,
 setAlarm,
 factoryMode,
 ScreenDeviceWatch,
 ScreenDeviceForecast,
}

/* index.js */
import Vue from 'vue'
import Vuex from 'vuex'

import state from './state'
import getters from './getters'
import modules from './modules'
import actions from './actions'
import mutations from './mutations'

Vue.use(Vuex)
export default new Vuex.Store({
 state,
 getters,
 mutations,
 actions,
 modules
})

可以发现每个模块都要我们手动导入,然后加入到module里面,如此重复。当模块不多还好,假如项目大了,有50个模块,那就得要做很多重复的工作。

跟注册组件一样,我们还是利用require.context来实现。

/**
 * 读取./modules下的所有js文件并注册模块
 */
const requireModule = require.context('./modules', false, /\.js$/)
const modules = {}

requireModule.keys().forEach(fileName => {
 const moduleName = fileName.replace(/(\.\/|\.js)/g, '') 
 modules[moduleName] = {
  namespaced: true,
  ...requireModule(fileName).default
 }
})

export default modules

/* index.js */
import Vue from 'vue'
import Vuex from 'vuex'
import modules from './modules'

Vue.use(Vuex)
export default new Vuex.Store({
 state,
 getters,
 mutations,
 actions,
 modules
})

这篇关于如何写出更优雅的vue.js代码的文章就介绍到这了,希望大家以后多多支持三水点靠木。

Javascript 相关文章推荐
基于jquery的拖动布局插件
Nov 25 Javascript
网页防止tab键的使用快速解决方法
Nov 07 Javascript
JQuery插件Quicksand实现超炫的动画洗牌效果
May 03 Javascript
jQuery焦点图插件SaySlide
Dec 21 Javascript
JS中常用的正则表达式
Sep 29 Javascript
基于JavaScript实现右键菜单和拖拽功能
Nov 28 Javascript
基于Vue 2.0的模块化前端 UI 组件库小结
Dec 21 Javascript
vue 组件的封装之基于axios的ajax请求方法
Aug 11 Javascript
详解关于微信setData回调函数中的坑
Feb 18 Javascript
微信小程序动画组件使用解析,类似vue,且更强大
Aug 01 Javascript
vue使用axios实现excel文件下载的功能
Jul 16 Javascript
vue 给数组添加新对象并赋值
Apr 20 Vue.js
Vue.js 中取得后台原生HTML字符串 原样显示问题的解决方法
Jun 10 #Javascript
实例详解Node.js 函数
Jun 10 #Javascript
微信小程序实现倒计时调用相机自动拍照功能
Jun 10 #Javascript
深入浅析Vue中的Prop
Jun 10 #Javascript
vue项目部署上线遇到的问题及解决方法
Jun 10 #Javascript
js技巧之十几行的代码实现vue.watch代码
Jun 09 #Javascript
浅谈JS对象添加getter与setter的5种方法
Jun 09 #Javascript
You might like
php empty()与isset()区别的详细介绍
2013/06/17 PHP
php集成动态口令认证
2016/07/21 PHP
仿163填写邮件地址自动显示下拉(无优化)
2008/11/05 Javascript
jquery实现类似淘宝星星评分功能实例
2014/09/12 Javascript
《JavaScript DOM 编程艺术》读书笔记之JavaScript 图片库
2015/01/09 Javascript
浅谈jquery事件处理
2015/04/24 Javascript
js中unicode转码方法详解
2015/10/09 Javascript
jquery利用拖拽方式在图片上添加热链接
2015/11/24 Javascript
浅谈javascript 函数表达式和函数声明的区别
2016/01/05 Javascript
AngularJS 避繁就简的路由
2016/07/01 Javascript
解析jQueryEasyUI的使用
2016/11/22 Javascript
JQuery统计input和textarea文字输入数量(代码分享)
2016/12/29 Javascript
js Dom实现换肤效果
2017/10/21 Javascript
解决vue 更改计算属性后select选中值不更改的问题
2018/03/02 Javascript
vue项目引入Iconfont图标库的教程图解
2018/10/24 Javascript
基于Vue2-Calendar改进的日历组件(含中文使用说明)
2019/04/14 Javascript
解决vue中axios设置超时(超过5分钟)没反应的问题
2020/09/04 Javascript
[19:15]DK战队纪录片
2014/09/02 DOTA
Python中使用PyHook监听鼠标和键盘事件实例
2014/07/18 Python
python访问类中docstring注释的实现方法
2015/05/04 Python
python pickle存储、读取大数据量列表、字典数据的方法
2019/07/07 Python
在Python中利用pickle保存变量的实例
2019/12/30 Python
python求一个字符串的所有排列的实现方法
2020/02/04 Python
SEPHORA丝芙兰德国官方购物网站:化妆品、护肤品和香水
2020/01/21 全球购物
毕业生的自我评价范文
2013/12/31 职场文书
《绿色蝈蝈》教学反思
2014/03/02 职场文书
法律进企业活动方案
2014/03/04 职场文书
团结演讲稿范文
2014/05/23 职场文书
办理信用卡收入证明范例
2014/09/13 职场文书
学生检讨书范文
2014/10/30 职场文书
委托公证书样本
2015/01/23 职场文书
考察邀请函范文
2015/01/31 职场文书
七一建党节慰问信
2015/02/14 职场文书
导游词之太湖
2019/10/08 职场文书
Python 流媒体播放器的实现(基于VLC)
2021/04/28 Python
基于Java的MathML转图片的方法(示例代码)
2021/06/23 Java/Android