1. watch 与 computed 的巧妙结合

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

你可能会这么做:

  1. created(){
  2. this.fetchData()
  3. },
  4. watch: {
  5. keyword(){
  6. this.fetchData()
  7. }
  8. }

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

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

可能会是这样:

  1. data(){
  2. return {
  3. keyword:'',
  4. region:'',
  5. deviceId:'',
  6. page:1
  7. }
  8. },
  9. methods:{
  10. fetchData(paramrs={
  11. keyword:this.keyword,
  12. region:this.region,
  13. deviceId:this.deviceId,
  14. page:this.page,
  15. }){
  16. this.$http.get("/list",paramrs).then("do some thing")
  17. }
  18. },
  19. created(){
  20. this.fetchData()
  21. },
  22. watch: {
  23. keyword(data){
  24. this.keyword=data
  25. this.fetchData()
  26. },
  27. region(data){
  28. this.region=data
  29. this.fetchData()
  30. },
  31. deviceId(data){
  32. this.deviceId=data
  33. this.fetchData()
  34. },
  35. page(data){
  36. this.page=data
  37. this.fetchData()
  38. },
  39. requestParams(params){
  40. this.fetchData(params)
  41. }
  42. }

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

  1. data(){
  2. return {
  3. keyword:'',
  4. region:'',
  5. deviceId:'',
  6. page:1
  7. }
  8. },
  9. methods:{
  10. paramsChange(paramsName,paramsValue){
  11. this[paramsName]=paramsValue
  12. this.fetchData()
  13. },
  14. fetchData(paramrs={
  15. keyword:this.keyword,
  16. region:this.region,
  17. deviceId:this.deviceId,
  18. page:this.page,
  19. }){
  20. this.$http.get("/list",paramrs).then("do some thing")
  21. }
  22. },
  23. created(){
  24. this.fetchData()
  25. }

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

  1. <el-pagination
  2. layout="total, prev, pager, next, jumper"
  3. :total="total"
  4. prev-text="上一页"
  5. next-text="下一页"
  6. @current-change="paramsChange('page',$event)"
  7. >
  8. </el-pagination>

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

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

  1. data(){
  2. return {
  3. keyword:'',
  4. region:'',
  5. deviceId:'',
  6. page:1
  7. }
  8. },
  9. computed:{
  10. requestParams() {
  11. return {
  12. page: this.page,
  13. region: this.region,
  14. id: this.deviceId,
  15. keyword: this.keyword
  16. }
  17. }
  18. },
  19. methods:{
  20. fetchData(paramrs={
  21. keyword:this.keyword,
  22. region:this.region,
  23. deviceId:this.deviceId,
  24. page:this.page,
  25. }){
  26. this.$http.get("/list",paramrs).then("do some thing")
  27. }
  28. },
  29. watch: {
  30. requestParams: {
  31. handler: 'fetchData',
  32. immediate: true
  33. }
  34. },

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

2. 使用mixin提取公共部分

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

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

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

  1. /**
  2. * mixin/table.js
  3. */
  4. export default {
  5. data() {
  6. return {
  7. keyword: '',
  8. requestKeyword: '',
  9. pages: 1,
  10. size: 10,
  11. total: 0,
  12. tableData: []
  13. }
  14. }
  15. }

在要用到的页面

  1. import mixin from '@/mixin/table'
  2. export default {
  3. mixins: [mixin],
  4. data() {
  5. return {
  6. selectRegion: '',
  7. selectDevice: '',
  8. deviceList: [],
  9. }
  10. }
  11. /* 其他代码 */
  12. ...

3. 自动注册全局组件

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

  1. <template>
  2. <all-region :selectRegion="selectRegion" @region-change="selectRegion=$event"/>
  3. </template>
  4. <script>
  5. import AllRegion from './baseButton'
  6. export default {
  7. components: {
  8. AllRegion,
  9. }
  10. }
  11. </script>

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

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

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

  1. /* main.js */
  2. import Component1 from '@/component/compenent1'
  3. import Component2 from '@/component/compenent2'
  4. import Component3 from '@/component/compenent3'
  5. Vue.component('component1', Component1)
  6. Vue.component('component2', Component2)
  7. Vue.component('component3', Component3)

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

  1. /**
  2. * main.js
  3. * 读取componetns下的vue文件并自动注册全局组件
  4. */
  5. const requireComponent = require.context('./components', false, /\.vue$/)
  6. requireComponent.keys().forEach(fileName => {
  7. const componentConfig = requireComponent(fileName)
  8. const componentName = fileName.replace(/^\.\//, '').replace(/\.vue/, '')
  9. Vue.component(componentName, componentConfig.default || componentConfig)
  10. })

4. 自动注册vuex模块

之前我们是这么注册vuex模块的
```javascript
/* 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

})


  1. 可以发现每个模块都要我们手动导入,然后加入到module里面,如此重复。当模块不多还好,假如项目大了,有50个模块,那就得要做很多重复的工作。
  2. 跟注册组件一样,我们还是利用`require.context`来实现。
  3. ```javascript
  4. /**
  5. * 读取./modules下的所有js文件并注册模块
  6. */
  7. const requireModule = require.context('./modules', false, /\.js$/)
  8. const modules = {}
  9. requireModule.keys().forEach(fileName => {
  10. const moduleName = fileName.replace(/(\.\/|\.js)/g, '')
  11. modules[moduleName] = {
  12. namespaced: true,
  13. ...requireModule(fileName).default
  14. }
  15. })
  16. export default modules
  17. /* index.js */
  18. import Vue from 'vue'
  19. import Vuex from 'vuex'
  20. import modules from './modules'
  21. Vue.use(Vuex)
  22. export default new Vuex.Store({
  23. state,
  24. getters,
  25. mutations,
  26. actions,
  27. modules
  28. })

本文参考自油管上某个国外大神的公开演讲视频,学习了一下觉得很不错,所以在项目中也使用了这些不错的技巧。趁周末有空,写个博客记录一下。

几个你所不知道的技巧助你写出更优雅的vue.js代码的更多相关文章

  1. 10个小技巧助您写出高性能的ASP.NET Core代码

    今天这篇文章我们来聊一聊如何提升并优化ASP.NET Core应用程序的性能,本文的大部分内容来自翻译,当然中间穿插着自己的理解,希望对大家有所帮助!话不多说开始今天的主题吧! 我们都知道性能是公共网 ...

  2. 9条消除if...else的锦囊妙计,助你写出更优雅的代码

    前言 最近在做代码重构,发现了很多代码的烂味道.其他的不多说,今天主要说说那些又臭又长的if...else要如何重构. 在介绍更更优雅的编程之前,让我们一起回顾一下,不好的if...else代码 一. ...

  3. css文本换行你所不知道的技巧

    前言:这是最近翻译的一篇文章 我在header标签开头忘里边加入一个span标签的时候,有一点小问题.我总是想确保在span标签之前能够换行.明确地讲,在标签前边加入<br> 并没有什么错 ...

  4. 5款工具助你写出更好的Java代码

    1.FindBugs 顾名思义,FindBugs是一款帮助开发者发现bug的工具,它是一个开源项目,遵循GNU公共许可协议,运行的是Java字节码而不是源码. 它是一款静态分析工具,它检查类或者JAR ...

  5. 你所不知道的 CSS 滤镜技巧与细节

    承接上一篇你所不知道的 CSS 动画技巧与细节,本文主要介绍 CSS 滤镜的不常用用法,希望能给读者带来一些干货! OK,下面直接进入正文.本文所描述的滤镜,指的是 CSS3 出来后的滤镜,不是 IE ...

  6. 你所不知道的 CSS 阴影技巧与细节

    关于 CSS 阴影,之前已经有写过一篇,box-shadow 与 filter:drop-shadow 详解及奇技淫巧,介绍了一些关于 box-shadow 的用法. 最近一个新的项目,CSS-Ins ...

  7. 你所不知道的 CSS 阴影技巧与细节 滚动视差?CSS 不在话下 神奇的选择器 :focus-within 当角色转换为面试官之后 NPOI 教程 - 3.2 打印相关设置 前端XSS相关整理 委托入门案例

    你所不知道的 CSS 阴影技巧与细节   关于 CSS 阴影,之前已经有写过一篇,box-shadow 与 filter:drop-shadow 详解及奇技淫巧,介绍了一些关于 box-shadow  ...

  8. 你所不知道的SQL Server数据库启动过程,以及启动不起来的各种问题的分析及解决技巧

    目前SQL Server数据库作为微软一款优秀的RDBMS,其本身启动的时候是很少出问题的,我们在平时用的时候,很少关注起启动过程,或者很少了解其底层运行过程,大部分的过程只关注其内部的表.存储过程. ...

  9. 你所不知道的setTimeout

    JavaScript提供定时执行代码的功能,叫做定时器(timer),主要由setTimeout()和setInterval()这两个函数来完成.它们向任务队列添加定时任务.初始接触它的人都觉得好简单 ...

随机推荐

  1. java工程师

    java工程师 职位描述 1.参与产品后台需求和产品经理确定: 2.主导产品后台架构设计和前端通讯协议: 3.设计后台的架构,能支持大的并发量: 4.优化后台的性能,能保证接口的流畅性: 5.负责解决 ...

  2. jdk、tomcat、solr环境搭建

    环境概述 1)操作系统:windows7旗舰版(64位) 2)jdk:jdk-8u131-windows-x64: 3)tomcat:apache-tomcat-9.0.0.M21 4)solr:so ...

  3. JObject 用法 、JProperty 用法、JArray 用法 Linq 转 Json

    1.使用LINQ to JSON前,需要引用Newtonsoft.Json的dll和using Newtonsoft.Json.Linq的命名空间.LINQ to JSON主要使用到JObject, ...

  4. django多对多中间表详解

    我们都知道对于ManyToMany字段,Django采用的是第三张中间表的方式.通过这第三张表,来关联ManyToMany的双方.下面我们根据一个具体的例子,详细解说中间表的使用. 一.默认中间表 首 ...

  5. VSS_01

    1.设置 工作目录 右击 CSDRGis --> Set Working Folder.. --> D:\CSDRGis 2.下载 源码 右击 CSDRGis --> Get Las ...

  6. angular5 组件之间监听传值变化

    http://www.cnblogs.com/SLchuck/p/5904000.html https://i.cnblogs.com/EditPosts.aspx?postid=7995179&am ...

  7. Tomcat 中文乱码 设置UTF-8编码 问题解决办法

    在Java Web开发中,http请求带有中文字符的URI如果不处理容易出现乱码问题:这是因为Tomcat容器默认编码是iso-8859-1引起的,因此要避免出现乱码就要需要做相应的处理.解决办法如下 ...

  8. LeetCode--191--位1的个数

    问题描述: 编写一个函数,输入是一个无符号整数,返回其二进制表达式中数字位数为 ‘1’ 的个数(也被称为汉明重量). 示例 : 输入: 11 输出: 3 解释: 整数 11 的二进制表示为 00000 ...

  9. [NOI2018]你的名字(68pts)

    SAM真让人头秃. 题面 https://www.luogu.org/problemnew/show/P4770 首先考虑 l=1,r=∣S∣的做法 如果对于ION2018的子串不用判重的话,对ION ...

  10. python-day33--互斥锁

    锁的意思就是:一个一个的执行 from multiprocessing import Process,Lock import os import time def work(mutex): mutex ...