几个你不知道的技巧助你写出更优雅的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 click([data],fn)使用方法实例介绍
Jul 08 Javascript
深入理解javascript中defer的作用
Dec 11 Javascript
JavaScript实现函数返回多个值的方法
Jun 09 Javascript
提高jQuery性能优化的技巧
Aug 03 Javascript
jquery实现鼠标悬浮停止轮播特效
Aug 20 Javascript
javascript冒泡排序小结
Apr 10 Javascript
jquery.qtip提示信息插件用法简单实例
Jun 17 Javascript
JavaScript的字符串方法汇总
Jul 31 Javascript
原生js实现addclass,removeclass,toggleclasss实例
Nov 24 Javascript
bootstrap-table组合表头的实现方法
Sep 07 Javascript
Vue父子组建的简单通信之控制开关Switch的实现
Jun 04 Javascript
bootstrap下拉框动态赋值方法
Aug 10 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脚本的10个技巧(8)
2006/10/09 PHP
一步一步学习PHP(1) php开发环境配置
2010/02/15 PHP
php explode函数实例代码
2012/02/27 PHP
php导入大量数据到mysql性能优化技巧
2014/12/29 PHP
laravel 5 实现模板主题功能(续)
2015/03/02 PHP
PHP curl 或 file_get_contents 获取需要授权页面的方法
2017/05/05 PHP
PhpStorm2020.1 安装 debug - Postman 调用的详细教程
2020/08/17 PHP
关于 文本框默认值 的操作js代码
2012/01/12 Javascript
JQuery获取与设置HTML元素的内容或文本的实现代码
2014/06/20 Javascript
jQuery中triggerHandler()方法用法实例
2015/01/19 Javascript
js实现class样式的修改、添加及删除的方法
2015/01/20 Javascript
JavaScript改变CSS样式的方法汇总
2015/05/07 Javascript
在JavaScript中正确引用bind方法的应用
2015/05/11 Javascript
Jquery检验手机号是否符合规则并根据手机号检测结果将提交按钮设为不同状态
2015/11/26 Javascript
学习JavaScript事件流和事件处理程序
2016/01/25 Javascript
基于BootStrap实现局部刷新分页实例代码
2016/08/08 Javascript
nodejs集成sqlite使用示例
2017/06/05 NodeJs
JS使用正则表达式验证身份证号码
2017/06/23 Javascript
webpack处理 css\less\sass 样式的方法
2017/08/21 Javascript
基于Cesium绘制抛物弧线
2020/11/18 Javascript
[00:59]PWL开团时刻DAY7——我在赶
2020/11/06 DOTA
Cython 三分钟入门教程
2009/09/17 Python
教你如何将 Sublime 3 打造成 Python/Django IDE开发利器
2014/07/04 Python
Python微信企业号开发之回调模式接收微信端客户端发送消息及被动返回消息示例
2017/08/21 Python
python探索之BaseHTTPServer-实现Web服务器介绍
2017/10/28 Python
Python PyQt5运行程序把输出信息展示到GUI图形界面上
2020/04/27 Python
全网最细 Python 格式化输出用法讲解(推荐)
2021/01/18 Python
Mountain Warehouse澳大利亚官网:欧洲家庭户外品牌倡导者
2016/11/20 全球购物
欧洲最大的滑雪假期供应商之一:Sunweb Holidays
2018/01/06 全球购物
英国马匹装备和马术用品购物网站:Equine Superstore
2019/03/03 全球购物
几道Java和数据库的面试题
2013/05/30 面试题
元旦晚会策划方案
2014/02/18 职场文书
小学生开学第一课活动方案
2014/03/27 职场文书
好媳妇事迹材料
2014/12/24 职场文书
2015年仓库管理员工作总结
2015/04/21 职场文书
2016年“六一儿童节”校园广播稿
2015/12/17 职场文书