简述Vue中容易被忽视的知识点


Posted in Javascript onDecember 09, 2019

前言

Vue的学习成本和难度不高,这除了和框架本身的设计理念有关之外,还和Vue完善的官方文档有着密不可分的关系,相信有很多的开发者和我一样,很长时间没有仔细去看过官方文档了,最近花时间仔细看了一下官方文档,将里面一些容易忽视的点整理出来和大家分享。

容易忽视的点

箭头函数的使用

ES6的普及使得箭头函数的使用更加频繁,但是在Vue中不要在选项属性或者回调上使用箭头函数,举个例子:

new Vue({
 el: '#app',
 data: {
  show: true
 },
 created: () => {
  console.log(this.show)
 },
})

将created钩子写成箭头函数,这里的this将不再指向Vue对象,在浏览器中将会指向window对象,这是因为箭头函数并没有this,this会作为变量一直向上级词法作用域查找,直到找到为止

指令动态参数

Vue从2.6.0开始,可以用方括号括起来的JavaScript表达式作为一个指令参数,举个例子:

<div id="app">
 <input v-on:[event] = "doSomething">
 <button v-on:click="event = 'focus'">change</button>
</div>
new Vue({
 el: '#app',
 data() {
  return {
   event: 'input'
  }
 },
 methods: {
  doSomething () {
   console.log('sss')
  }
 },
})

这里将input的事件监听设置为一个动态的参数event,默认是监听点击事件,当点击change的时候,改为监听focus事件,动态参数预期会求出一个字符串,异常情况下值为null,null值可以用于移除绑定,任何其他非字符串类型的值都会触发一个警告

template中使用方法

methods中提供的方法大多数时候都是用来给其他方法调用的,但是它其实也可以像computed计算属性一样直接写在模版里,举个例子:

<div id="app">{{reversedMessage('hello')}}</div>
var app = new Vue({
 el: '#app',
 methods: {
  reversedMessage: function (message) {
   return message.split('').reverse().join('')
  }
 },
})

有了computed计算属性,为什么还要用methods呢?计算属性是基于响应式依赖进行缓存的,只在相关依赖发生改变时才会重新求值,而methods每次调用都会重新计算,调用methods时可以传参,进行指定计算,但是computed不行,这在遍历数组时十分有用

用key管理可复用元素

Vue会尽可能高效地渲染元素,通常会复用已有元素而不是从头开始渲染。这么做会使 Vue变得非常快,举个例子:

<div id="app">
  <template v-if="loginType === 'username'">
   <label>Username</label>
   <input placeholder="Enter your username">
  </template>
  <template v-else>
   <label>Email</label>
   <input placeholder="Enter your email address">
  </template>
  <button @click="change">change</button>
</div>
var app = new Vue({
 el: '#app',
 data() {
  return {
   loginType: 'username'
  }
 },
 methods: {
  change () {
   this.loginType = this.loginType === 'username' ? 'email' : 'username'
  }
 }
})

上面代码中切换loginType将不会清除用户已经输入的内容,因为两个模版使用了相同的元素,如果不想复用也很简单,只需要添加一个具有唯一值的key属性即可:

<template v-if="loginType === 'username'">
 <label>Username</label>
 <input key="username" placeholder="Enter your username">
</template>
<template v-else>
 <label>Email</label>
 <input key="email" placeholder="Enter your email address">
</template>
<button @click="change">change</button>

现在切换,每次都会重新渲染,但是label元素还是会被复用,因为它没有加唯一key值

v-if与v-for一起使用

Vue的风格指南不推荐同时使用v-if与v-for,当项目中的eslint继承了@vue/standard时,同时使用就会编译报错,但是可以通过在模版上加<!-- eslint-disable -->进行忽略,同时当它们处于同一节点,v-for的优先级比v-if更高,这意味着v-if 将分别重复运行于每个v-for循环中

对象变更检测

在Vue中对于已经创建的实例,不允许动态添加根级别的响应式属性,但是我们知道可以通过Vue.set(object, propertyName, value)方法向嵌套对象添加响应式属性,那如果需要为已有对象赋值多个新属性呢?举个例子:

<div id="app">{{user.name}}-{{user.age}}-{{user.sex}}</div>
var app = new Vue({
 el: '#app',
 data() {
  return {
   user: {
    name: 'xxx'
   }
  }
 },
 created() {
  this.user = Object.assign({}, this.user, {
   age: 18,
   sex: 'name'
  })
 },
})

可以用Object.assign为这个对象重新赋值,这样就能添加多个新的响应式属性

内联方法访问原始DOM事件

有时在模版中调用方法时,我们需要向方法中传参数,但是同时又要传递原始的DOM事件,怎么处理呢?举个例子:

<div id="app">
 <button @click="share('share info', $event)">share</button>
</div>
var app = new Vue({
 el: '#app',
 data() {
  return {
   user: {
    name: 'xxx'
   }
  }
 },
 methods: {
  share (info, event) {
   console.log(info, event)
  }
 },
})

如例子所示,可以用特殊变量$event把它传入方法

once、passive事件修饰符

Vue中提供了多个事件修饰符, once、passive是后面新增的两个,once用于限定事件只触发一次,passive用于修饰的事件发生后立即触发,用于提升移动端性能

表单输入修饰符

.lazy

在默认情况下,v-model在每次input事件触发后将输入框的值与数据进行同步,可以添加lazy修饰符,从而转变为使用change事件进行同步,举个例子:

<input placeholder="lazy" v-model.lazy="msg" @input="input" @change="change">

.number

如果想自动将用户的输入值转为数值类型,可以给v-model添加number修饰符,这通常很有用,因为即使在type="number"时,HTML输入元素的值也总会返回字符串。如果这个值无法被 parseFloat()解析,则会返回原始的值,举个例子:

<input placeholder="number" v-model.number="age" @input="input">

.trim

如果要自动过滤用户输入的首尾空白字符,可以给v-model添加trim修饰符,举个例子:

<input placeholder="trim" v-model.trim="trim" @input="input">

子组件替换/合并已有的特性

在Vue中对于绝大多数特性来说,从外部提供给组件的值会替换掉组件内部设置好的值。所以如果传入type="text"就会替换掉 type="date"并把它破坏!庆幸的是,class和 style特性会稍微智能一些,即两边的值会被合并起来,从而得到最终的值,举个例子:

<div id="app">
 <base-input type="text" class="out"></base-input>
</div>
Vue.component('base-input', {
 template: `<input type="date" placeholder="replace" class="default">`
})
new Vue({
 el: '#app',
})

在上例中input的type值为date,class为deafault,在使用子组件时,向子组件中传入type="text" class="out",此时input的type值会被替换为text,class值会被合并为"default out",那么如果想要禁用属性继承怎么办呢?可以在组件的选项中设置inheritAttrs:false,举个例子:

Vue.component('base-input', {
 inheritAttrs: false,
 template: `<input type="date" placeholder="replace" class="default">`
})

但是inheritAttrs:false选项不会影响style和class的绑定,因此style和class还是会合并

.sync修饰符

在有些情况下,可能需要对一个 prop进行“双向绑定”。不幸的是,真正的双向绑定会带来维护上的问题,因为子组件可以修改父组件,且在父组件和子组件都没有明显的改动来源,因此Vue提供了sync修饰符,举个例子:

<div id="app">
 <span>{{title}}</span>
 <text-document v-bind:title.sync="title"></text-document>
</div>
Vue.component('text-document', {
 props: ['title'],
 template: `<button @click="change">change</button>`,
 methods: {
  change () {
   this.$emit('update:title', 'change')
  }
 },
})
new Vue({
 el: '#app',
 data() {
  return {
   title: 'default'
  }
 }
})

当调用this.$emit('update:title', 'change'),父组件中的title就会改变

总结

这篇文章对Vue中一些容易忽视的点进行了简单的总结,希望看完之后能对大家有所帮助。也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
C#中TrimStart,TrimEnd,Trim在javascript上的实现
Jan 17 Javascript
Jquery getJSON方法详细分析
Dec 26 Javascript
文本域中换行符的替换示例
Mar 04 Javascript
jQuery中toggleClass()方法用法实例
Jan 05 Javascript
JavaScript事件代理和委托详解
Apr 08 Javascript
JavaScript中校验银行卡号的实现代码
Dec 19 Javascript
详解Javascript几种跨域方式总结
Feb 27 Javascript
浅谈jQuery的bind和unbind事件(绑定和解绑事件)
Mar 02 Javascript
React中如何引入Angular组件详解
Aug 09 Javascript
jQuery实现的鼠标拖动浮层功能示例【拖动div等任何标签】
Dec 29 jQuery
AJAX XMLHttpRequest对象创建使用详解
Aug 20 Javascript
Vue实现开关按钮拖拽效果
Sep 22 Javascript
vue路由传参三种基本方式详解
Dec 09 #Javascript
vue使用nprogress实现进度条
Dec 09 #Javascript
javascript数组元素删除方法delete和splice解析
Dec 09 #Javascript
vue vant Area组件使用详解
Dec 09 #Javascript
JS中的模糊查询功能
Dec 08 #Javascript
详解一些适用于Node.js的命名约定
Dec 08 #Javascript
微信域名检测接口调用演示步骤(含PHP、Python)
Dec 08 #Javascript
You might like
大师制作的中短波矿石收音机
2020/04/02 无线电
NOD32 v2.70.32 简体中文封装版 提供下载了
2007/02/27 PHP
PHP5中使用DOM控制XML实现代码
2010/05/07 PHP
php实现微信公众号无限群发
2015/10/11 PHP
javascript常用对话框小集
2013/09/13 Javascript
倒记时60刷新网页的js代码
2014/02/18 Javascript
jquery attr方法获取input的checked属性问题
2014/05/26 Javascript
JavaScript通过function定义对象并给对象添加toString()方法实例分析
2015/03/23 Javascript
Jquery 1.9.1源码分析系列(十二)之筛选操作
2015/12/02 Javascript
js实现数组冒泡排序、快速排序原理
2016/03/08 Javascript
JavaScript中的数组遍历forEach()与map()方法以及兼容写法介绍
2016/05/19 Javascript
js 用于检测类数组对象的函数方法
2017/05/02 Javascript
基于 webpack2 实现的多入口项目脚手架详解
2017/06/26 Javascript
浅析Javascript中双等号(==)隐性转换机制
2017/10/27 Javascript
Vue中v-show添加表达式的问题(判断是否显示)
2018/03/26 Javascript
vue.js使用v-model指令实现的数据双向绑定功能示例
2018/05/22 Javascript
一个Vue页面的内存泄露分析详解
2018/06/25 Javascript
Node.js操作系统OS模块用法分析
2019/01/04 Javascript
Vue3.0结合bootstrap创建多页面应用
2019/05/28 Javascript
js+canvas实现简单扫雷小游戏
2021/01/22 Javascript
如何使用 vue-cli 创建模板项目
2020/11/19 Vue.js
python实现实时监控文件的方法
2016/08/26 Python
对python中的float除法和整除法的实例详解
2019/07/20 Python
python读写csv文件并增加行列的实例代码
2019/08/01 Python
PyCharm上安装Package的实现(以pandas为例)
2020/09/18 Python
支持IE8的纯css3开发的响应式设计动画菜单教程
2014/11/05 HTML / CSS
贝玲妃英国官网:Benefit英国
2018/02/03 全球购物
涉外文秘个人求职的自我评价
2013/10/07 职场文书
行政副总岗位职责
2014/02/23 职场文书
2014年新生军训方案
2014/05/01 职场文书
80后婚前协议书范本
2014/10/24 职场文书
银行求职自荐信范文
2015/03/04 职场文书
2016年社区植树节活动总结
2016/03/16 职场文书
2016年学校禁毒宣传活动工作总结
2016/04/05 职场文书
餐厅营销的秘密:为什么老顾客会流水?
2019/08/08 职场文书
GO语言字符串处理函数之处理Strings包
2022/04/14 Golang