几个你不知道的技巧助你写出更优雅的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 相关文章推荐
?牟┛途W扣了一??效果出?? target=
May 27 Javascript
js Flash插入函数免激活代码
Mar 31 Javascript
js实现简洁的滑动门菜单(选项卡)效果代码
Sep 04 Javascript
安装使用Mongoose配合Node.js操作MongoDB的基础教程
Mar 01 Javascript
JS组件系列之使用HTML标签的data属性初始化JS组件
Sep 14 Javascript
JS实现动画兼容性的transition和transform实例分析
Dec 13 Javascript
jquery与ajax获取特殊字符实例详解
Jan 08 Javascript
基于jQuery实现滚动刷新效果
Jan 09 Javascript
Element-UI Table组件上添加列拖拽效果实现方法
Apr 14 Javascript
vue + any-touch实现一个iscroll 实现拖拽和滑动动画效果
Apr 08 Javascript
vue实现微信分享链接添加动态参数的方法
Apr 29 Javascript
js new Date()实例测试
Oct 31 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 图像处理类1
2009/06/15 PHP
浅析PHP程序设计中的MVC编程思想
2014/07/28 PHP
Opcache导致php-fpm崩溃nginx返回502
2015/03/02 PHP
PHP实现批量修改文件后缀名的方法
2015/07/30 PHP
PHP网站建设的流程与步骤分享
2015/09/25 PHP
使用xampp搭建运行php虚拟主机的详细步骤
2015/10/21 PHP
yii2.0使用Plupload实现带缩放功能的多图上传
2015/12/22 PHP
javascript 日期常用的方法
2009/11/11 Javascript
javascript 二分法(数组array)
2010/04/24 Javascript
分享20多个很棒的jQuery 文件上传插件或教程
2011/09/04 Javascript
取得元素的左和上偏移量的方法
2014/09/17 Javascript
基于jQuery 实现bootstrapValidator下的全局验证
2015/12/07 Javascript
jquery动态切换背景图片的简单实现方法
2016/05/14 Javascript
解决给dom元素绑定click等事件无效问题的方法
2017/02/17 Javascript
Node.js中使用mongoose操作mongodb数据库的方法
2017/09/12 Javascript
详解vue-admin和后端(flask)分离结合的例子
2018/02/12 Javascript
Angular CLI 使用教程指南参考小结
2019/04/10 Javascript
JS实现可切换图片的幻灯切换效果示例
2019/05/24 Javascript
Element-ui upload上传文件限制的解决方法
2021/01/22 Javascript
vue-router路由懒加载及实现的3种方式
2021/02/28 Vue.js
Python os模块中的isfile()和isdir()函数均返回false问题解决方法
2015/02/04 Python
Python调用命令行进度条的方法
2015/05/05 Python
Python中的条件判断语句与循环语句用法小结
2016/03/21 Python
python编程实现希尔排序
2017/04/13 Python
PyQt5每天必学之事件与信号
2018/04/20 Python
浅谈python的深浅拷贝以及fromkeys的用法
2019/03/08 Python
python实现递归查找某个路径下所有文件中的中文字符
2019/08/31 Python
印尼穆斯林时尚购物网站:Hijabenka
2016/12/10 全球购物
Surfdome西班牙:世界上最受欢迎的生活方式品牌
2019/02/13 全球购物
老师自我鉴定范文
2013/12/25 职场文书
总账会计岗位职责
2014/03/13 职场文书
事业单位个人查摆问题及整改措施
2014/10/28 职场文书
乡镇2014法制宣传日活动总结
2014/11/01 职场文书
公务员岗前培训心得体会
2016/01/08 职场文书
小学音乐课歌曲《堆雪人》教学反思
2016/02/18 职场文书
Redis 哨兵机制及配置实现
2022/03/25 Redis