几个你不知道的技巧助你写出更优雅的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优缺点分析说明
Apr 10 Javascript
jQuery中的.bind()、.live()和.delegate()之间区别分析
Jun 08 Javascript
教你如何在 Javascript 文件里使用 .Net MVC Razor 语法
Jul 23 Javascript
详解AngularJS中的依赖注入机制
Jun 17 Javascript
jQuery实现百叶窗焦点图动画效果代码分享(附源码下载)
Mar 14 Javascript
Vue 父子组件、组件间通信
Mar 08 Javascript
关于bootstrap日期转化,bootstrap-editable的简单使用,bootstrap-fileinput的使用详解
May 12 Javascript
react-router4 嵌套路由的使用方法
Jul 24 Javascript
webstorm+vue初始化项目的方法
Oct 18 Javascript
vue微信分享出来的链接点开是首页问题的解决方法
Nov 28 Javascript
微信小程序canvas开发水果老虎机的思路详解
Feb 07 Javascript
JavaScript类的继承多种实现方法
May 30 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和ACCESS写聊天室(二)
2006/10/09 PHP
很好用的PHP数据库类
2009/05/27 PHP
php set_time_limit(0) 设置程序执行时间的函数
2010/05/26 PHP
并发下常见的加锁及锁的PHP具体实现代码
2010/10/12 PHP
用PHP来计算某个目录大小的方法
2014/04/01 PHP
五款PHP代码重构工具推荐
2014/10/14 PHP
PHP配置把错误日志以邮件方式发送方法(Windows系统)
2015/06/23 PHP
PHP数组生成XML格式数据的封装类实例
2016/11/10 PHP
php str_getcsv把字符串解析为数组的实现方法
2017/04/05 PHP
laravel 中某一字段自增、自减的例子
2019/10/11 PHP
Nginx+php配置文件及原理解析
2020/12/09 PHP
javascript 类型判断代码分析
2010/03/28 Javascript
动态加载js、css等文件跨iframe实现
2014/02/24 Javascript
基于原生JS实现图片裁剪
2016/08/01 Javascript
利用vue.js插入dom节点的方法
2017/03/15 Javascript
微信小程序仿抖音短视频切换效果的实例代码
2020/06/24 Javascript
[02:34]DOTA2亚洲邀请赛 BG战队出场宣传片
2015/03/09 DOTA
用Python编写一个国际象棋AI程序
2014/11/28 Python
Python编程之字符串模板(Template)用法实例分析
2017/07/22 Python
python list删除元素时要注意的坑点分享
2018/04/18 Python
解决Matplotlib图表不能在Pycharm中显示的问题
2018/05/24 Python
python3第三方爬虫库BeautifulSoup4安装教程
2018/06/19 Python
python自动化测试之DDT数据驱动的实现代码
2019/07/23 Python
利用setuptools打包python程序的方法步骤
2020/01/18 Python
python实时监控logstash日志代码
2020/04/27 Python
Rockport乐步美国官网:风靡美国的白宫鞋
2016/11/24 全球购物
美国第二大连锁药店:Rite Aid
2019/04/03 全球购物
.NET初级开发工程师面试题(包括Javascript)
2012/08/22 面试题
大学毕业生的自我鉴定
2013/11/30 职场文书
大学学习生活感言
2014/01/18 职场文书
2014基层党员批评与自我批评范文
2014/09/24 职场文书
加强机关作风建设心得体会
2014/10/22 职场文书
销售会议开幕词
2015/01/28 职场文书
农民工工资支付承诺书
2015/05/04 职场文书
2019最新企业员工考勤管理制度(通用版)!
2019/07/02 职场文书
Python序列化与反序列化相关知识总结
2021/06/08 Python