几个你不知道的技巧助你写出更优雅的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 相关文章推荐
JavaScript 计算当天是本年本月的第几周
Mar 22 Javascript
客户端js性能优化小技巧整理
Nov 05 Javascript
关于Javascript作用域链的八点总结
Dec 06 Javascript
点击A元素触发B元素的事件在IE8下会识别成A元素
Sep 04 Javascript
Node.js中的模块机制学习笔记
Nov 04 Javascript
基于jquery ui的alert,confirm方案(支持换肤)
Apr 03 Javascript
Jquery zTree 树控件异步加载操作
Feb 25 Javascript
Javascript基础_嵌入图像的简单实现
Jun 14 Javascript
整理关于Bootstrap排版的慕课笔记
Mar 29 Javascript
bootstrap多层模态框滚动条消失的问题
Jul 21 Javascript
WebStorm ES6 语法支持设置&amp;babel使用及自动编译(详解)
Sep 08 Javascript
element-ui表格合并span-method的实现方法
May 21 Javascript
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中$_SERVER的详细参数与说明
2008/07/29 PHP
PHP学习之正则表达式
2011/04/17 PHP
php去除HTML标签实例
2013/11/06 PHP
PHP根据传入参数合并多个JS和CSS文件的简单实现
2014/06/13 PHP
php去除html标记的原生函数详解
2015/01/27 PHP
最准确的php截取字符串长度函数
2015/10/29 PHP
php邮箱地址正则表达式验证
2015/11/13 PHP
基于jquery的无刷新分页技术
2011/06/11 Javascript
JQuery each打印JS对象的方法
2013/11/13 Javascript
用javascript替换URL中的参数值示例代码
2014/01/27 Javascript
基于BootStrap栅格栏系统完成网站底部版权信息区
2016/12/23 Javascript
JS中使用gulp实现压缩文件及浏览器热加载功能
2017/07/12 Javascript
js判断数组是否包含某个字符串变量的实例
2017/11/24 Javascript
node.js中路由,中间件,ge请求和post请求的参数详解
2017/12/26 Javascript
jQuery基于闭包实现的显示与隐藏div功能示例
2018/06/09 jQuery
关于vue状态过渡transition不起作用的原因解决
2019/04/09 Javascript
JavaScript实现像雪花一样的Hexaflake分形
2020/07/07 Javascript
关于Python中空格字符串处理的技巧总结
2017/08/10 Python
使用Python实现简单的服务器功能
2017/08/25 Python
python sorted函数原理解析及练习
2020/02/10 Python
Python socket连接中的粘包、精确传输问题实例分析
2020/03/24 Python
Python xlrd模块导入过程及常用操作
2020/06/10 Python
python工具——Mimesis的简单使用教程
2021/01/16 Python
详解CSS的border边框属性及其在CSS3中的新特性
2016/05/10 HTML / CSS
CSS3实现各种图形的示例代码
2016/10/19 HTML / CSS
将n个数按输入顺序的逆序排列,用函数实现
2012/11/14 面试题
学生周末长期请假条
2014/02/15 职场文书
公安局副政委班子个人对照检查材料
2014/10/04 职场文书
党员查摆剖析材料
2014/10/10 职场文书
装饰施工员岗位职责
2015/04/11 职场文书
2015年电厂工作总结范文
2015/05/13 职场文书
小学体育组工作总结
2015/08/13 职场文书
如何让vue长列表快速加载
2021/03/29 Vue.js
Python3 使用pip安装git并获取Yahoo金融数据的操作
2021/04/08 Python
Django使用redis配置缓存的方法
2021/06/01 Redis
Python图像处理库PIL详细使用说明
2022/04/06 Python