Vue.js最佳实践

第一招:化繁为简的Watchers

场景还原:

created(){this.fetchPostList()
},watch: {searchInputValue(){this.fetchPostList()}
}

组件创建的时候我们获取一次列表,同时监听input框,每当发生变化的时候重新获取一次筛选后的列表这个场景很常见,有没有办法优化一下呢?

招式解析:

首先,在watchers中,可以直接使用函数的字面量名称;其次,声明immediate:true表示创建组件时立马执行一次。

watch: {searchInputValue:{handler: 'fetchPostList',immediate: true}
}

第二招:一劳永逸的组件注册

场景还原:

created(){this.fetchPostList()
},watch: {searchInputValue(){this.fetchPostList()}
}
<BaseInputv-model="searchText"@keydown.enter="search"
/><BaseButton @click="search"><BaseIcon name="search"/>
</BaseButton>

我们写了一堆基础UI组件,然后每次我们需要使用这些组件的时候,都得先import,然后声明components,很繁琐!秉持能偷懒就偷懒的原则,我们要想办法优化!

招式解析:

我们需要借助一下神器webpack,使用 require.context() 方法来创建自己的(模块)上下文,从而实现自动动态require组件。这个方法需要3个参数:要搜索的文件夹目录,是否还应该搜索它的子目录,以及一个匹配文件的正则表达式。

我们在components文件夹添加一个叫global.js的文件,在这个文件里借助webpack动态将需要的基础组件统统打包进来。

import Vue from 'vue'function capitalizeFirstLetter(string) {return string.charAt(0).toUpperCase()   string.slice(1)
}const requireComponent = require.context('.', false, /\.vue$///找到components文件夹下以.vue命名的文件

)requireComponent.keys().forEach(fileName => {const componentConfig = requireComponent(fileName)const componentName = capitalizeFirstLetter(fileName.replace(/^\.\//, '').replace(/\.\w $/, '')//因为得到的filename格式是: './baseButton.vue', 所以这里我们去掉头和尾,只保留真正的文件名
  )Vue.component(componentName, componentConfig.default || componentConfig)})

最后我们在main.js中import 'components/global.js',然后我们就可以随时随地使用这些基础组件,无需手动引入了。

第三招:釜底抽薪的router key

场景还原:

下面这个场景真的是伤透了很多程序员的心…先默认大家用的是Vue-router来实现路由的控制。

假设我们在写一个博客网站,需求是从/post-page/a,跳转到/post-page/b。然后我们惊人的发现,页面跳转后数据竟然没更新?!原因是vue-router”智能地”发现这是同一个组件,然后它就决定要复用这个组件,所以你在created函数里写的方法压根就没执行。通常的解决方案是监听$route的变化来初始化数据,如下:

data() {return {loading: false,error: null,post: null}
},watch: {'$route': {handler: 'resetData',immediate: true}
},methods: {resetData() {this.loading = falsethis.error = nullthis.post = nullthis.getPost(this.$route.params.id)},getPost(id){}
}

bug是解决了,可每次这么写也太不优雅了吧?秉持着能偷懒则偷懒的原则,我们希望代码这样写:

data() {return {loading: false,error: null,post: null}
},created () {this.getPost(this.$route.params.id)
},methods () {getPost(postId) {// ...
  }
}

招式解析:

那要怎么样才能实现这样的效果呢,答案是给router-view添加一个unique的key,这样即使是公用组件,只要url变化了,就一定会重新创建这个组件。(虽然损失了一丢丢性能,但避免了无限的bug)。同时,注意我将key直接设置为路由的完整路径,一举两得。

<router-view :key="$route.fullpath"></router-view>

第四招: 无所不能的render函数

场景还原:

vue要求每一个组件都只能有一个根元素,当你有多个根元素时,vue就会给你报错

<template><liv-for="route in routes":key="route.name"><router-link :to="route">{{ route.title }}</router-link></li>
</template>
 ERROR - Component template should contain exactly one root element.If you are using v-if on multiple elements, use v-else-ifto chain them instead.

招式解析:

那有没有办法化解呢,答案是有的,只不过这时候我们需要使用render()函数来创建HTML,而不是template。其实用js来生成html的好处就是极度的灵活功能强大,而且你不需要去学习使用vue的那些功能有限的指令API,比如v-for, v-if。(reactjs就完全丢弃了template)

functional: true,render(h, { props }) {return props.routes.map(route =><li key={route.name}><router-link to={route}>{route.title}</router-link></li>
  )
}

第五招:无招胜有招的高阶组件

划重点:这一招威力无穷,请务必掌握

当我们写组件的时候,通常我们都需要从父组件传递一系列的props到子组件,同时父组件监听子组件emit过来的一系列事件。举例子:

//父组件
<BaseInput:value="value"label="密码"placeholder="请填写密码"@input="handleInput"@focus="handleFocus>
</BaseInput>//子组件
<template><label>{{ label }}<input:value="value":placeholder="placeholder"@focus=$emit('focus', $event)"@input="$emit('input', $event.target.value)"></label>
</template>

有下面几个优化点:

1.每一个从父组件传到子组件的props,我们都得在子组件的Props中显式的声明才能使用。这样一来,我们的子组件每次都需要申明一大堆props, 而类似placeholer这种dom原生的property我们其实完全可以直接从父传到子,无需声明。方法如下:

<input:value="value"v-bind="$attrs"@input="$emit('input', $event.target.value)"
>

$attrs包含了父作用域中不作为 prop 被识别 (且获取) 的特性绑定 (class 和 style 除外)。当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定,并且可以通过 v-bind=”$attrs” 传入内部组件——在创建更高层次的组件时非常有用。

2.注意到子组件的@focus=$emit('focus', $event)"其实什么都没做,只是把event传回给父组件而已,那其实和上面类似,我完全没必要显式地申明:

<input:value="value"v-bind="$attrs"v-on="listeners"
>computed: {listeners() {return {...this.$listeners,input: event => this.$emit('input', event.target.value)}}
}

$listeners包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。它可以通过 v-on=”$listeners” 传入内部组件——在创建更高层次的组件时非常有用。

3.需要注意的是,由于我们input并不是BaseInput这个组件的根节点,而默认情况下父作用域的不被认作 props 的特性绑定将会“回退”且作为普通的 HTML 特性应用在子组件的根元素上。所以我们需要设置inheritAttrs:false,这些默认行为将会被去掉, 以上两点的优化才能成功。

更多专业前端知识,请上 【猿2048】www.mk2048.com

Vue.js最佳实践相关推荐

  1. Vue.js 最佳实践清单,照亮你的开发之路

    作者简介: 李中凯老师,8年前端开发,前端负责人,擅长JavaScript/Vue. 公众号:1024译站 掘金文章专栏:https://juejin.im/user/57c7cb8a0a2b5800 ...

  2. hook koa web 码云_Doodoo.js 发布 1.1.0,Koa.js+ Nuxt.js 最佳实践

    doodoo.js发布1.1.0 -- 中文最佳实践Node.js Web快速开发框架,支持Koa.js, Express.js中间件.包含多项功能改进,及Bug修复. 更新内容: 1.[新增]新增支 ...

  3. JS最佳实践——红皮书

    最佳实践 前言 1 可维护性 2 降低耦合 2.1 将css从js中抽离 2.2 模板文本写注释 2.3 应用逻辑 / 事件处理程序分离 2.3.1 概念 2.3.2 Demo 2.4 松散耦合原则 ...

  4. 前端开发工具vue.js开发实践总结

    最近有很长时间没有更新博客了,换了公司,全部的心思都放在项目上了.通过这次项目的上线,让我感受最深的是前后端分离后,前端页面的模块化管理,以及前端页面的数据邦定.在接触vue.js之前,我之前端要用到 ...

  5. 重构ElementUI解决DatePicker日期选择组件修改父组件placement参数问题[Vue.js项目实践: 新冠自检系统]

    新冠疫情自我检测系统网页设计开发文档 Sylvan Ding 的第一个基于 Vue.js 的项目. 本项目所提供的信息,只供参考之用,不保证信息的准确性.有效性.及时性和完整性,更多内容请查看国家卫健 ...

  6. Vue.js 开发实践:实现精巧的无限加载与分页功能

    小编推荐:Fundebug专注于JavaScript.微信小程序.微信小游戏,Node.js和Java实时BUG监控.真的是一个很好用的bug监控费服务,众多大佬公司都在使用. 本篇文章是一篇Vue. ...

  7. 前端干货之JS最佳实践

    持续更新地址 https://wdd.js.org/js-best-pr... 1. 风格 一千个读者有一千个哈姆雷特,每个人都有自己的code style.我也曾为了要不要加分号给同事闹个脸红脖子粗 ...

  8. 【开源】多多客发布 3.0.0-alpha.6,Koa+Vue+Taro最佳实践

    多多客(doodooke)是一款基于Koa+Vue+Taro开发,支持微信,百度,支付宝小程序的第三方SaaS平台. 本次重要更新 优化打赏不显示打赏人 新增登录的账号未绑定微信的情况下提示绑定微信 ...

  9. dropzonejs vue 使用_dropzone.js使用实践

    官网地址:http://www.dropzonejs.com/ 一,它是什么: DropzoneJS is an open source library that provides drag'n'dr ...

最新文章

  1. elasticsearch最大节点数_ElasticSearch这些概念要明白
  2. 52条SQL语句性能优化策略
  3. 内存管理,数据类型的基本使用与基本运算符(python2中与用户交互)
  4. rabbitmq多个消费者监听一个队列_RabbitMQ的六种工作模式
  5. 各大主流.Net的IOC框架性能测试比较
  6. 魔兽世界总是显示无法连接服务器,心得:launcher更新无法连接服务器如何解决...
  7. 黎明杀机手游未能连接服务器,黎明杀机无法连接在线服务及EAC绿条读完后无反应解决方法...
  8. java技术不行有复试怎么办_复试答不上来怎么办?记住这四点不慌!
  9. Javascript详解
  10. 如何将腾讯视频客户端下载的QLV视频格式转换成MP4格式
  11. PIXI+GSAP 防刹车动效
  12. 农民工看完都学会了!Android开发岗还不会这些问题,跳槽薪资翻倍
  13. 金蝶软件认证显示服务器异常,金蝶提示云服务器异常
  14. 数据结构初步(十二)- 插入排序与希尔排序超详细图解分析
  15. 搜索百度网盘资源的方法
  16. Win7系统组策略怎么打开 打开组策略的几种方法
  17. Verilog 综合练习 电子钟的实现
  18. 第2章 获得文本语料和词汇资源
  19. 重启计算机怎么一键还原系统还原,小编教你电脑怎么一键还原系统
  20. 微信点赞功能测试用例

热门文章

  1. android已经点击,【已解决】android中点击其他的(如Button等)但是EditText却没有失去焦点...
  2. 华工网络教育C语言校考答案,计算机应用基础(统考)随堂练习2017秋华工答案.docx...
  3. shell实战之tomcat看门狗
  4. laravel API开发,使用dingo/api
  5. 共享文件夹不能访问的问题解决
  6. poj1419 Graph Coloring 最大独立集(最大团)
  7. 芬兰高性能图表控件-免费试用并提供技术支持
  8. 简单的遮罩层加登录窗效果
  9. Proe Top-Down设计演示
  10. C# CheckedListBox控件的用法