简述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 相关文章推荐
jQuery中事件对象e的事件冒泡用法示例介绍
Apr 25 Javascript
浅谈javascript对象模型和function对象
Dec 26 Javascript
根据user-agent判断蜘蛛代码黑帽跳转代码(js版与php版本)
Sep 14 Javascript
Sort()函数的多种用法
Mar 20 Javascript
js实现各种复制到剪贴板的方法(分享)
Oct 27 Javascript
JS基于正则截取替换特定字符之间字符串操作示例
Feb 03 Javascript
基于Vue实现tab栏切换内容不断实时刷新数据功能
Apr 13 Javascript
微信小程序 动态绑定事件并实现事件修改样式
Apr 13 Javascript
详解Angular5路由传值方式及其相关问题
Apr 28 Javascript
vue如何通过id从列表页跳转到对应的详情页
May 01 Javascript
vue 解决form表单提交但不跳转页面的问题
Oct 30 Javascript
解决ant design vue中树形控件defaultExpandAll设置无效的问题
Oct 26 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
使用PHP实现微信摇一摇周边红包
2016/01/04 PHP
Yii框架用户登录session丢失问题解决方法
2017/01/07 PHP
javascript高亮效果的二种实现方法
2008/09/14 Javascript
jQuery判断密码强度实现思路及代码
2013/04/24 Javascript
js实现幻灯片效果(基于jquery插件)
2013/11/05 Javascript
javascript history对象(历史记录)使用方法(实现浏览器前进后退)
2014/01/07 Javascript
JQuery拖动表头边框线调整表格列宽效果代码
2014/09/10 Javascript
JS实现仿新浪微博发布内容为空时提示功能代码
2015/08/19 Javascript
详解JavaScript正则表达式之RegExp对象
2015/12/13 Javascript
Node.js本地文件操作之文件拷贝与目录遍历的方法
2016/02/16 Javascript
使用bootstrap实现多窗口和拖动效果
2016/09/22 Javascript
Jquery Easyui验证组件ValidateBox使用详解(20)
2016/12/18 Javascript
vue双向绑定的简单实现
2016/12/22 Javascript
除Console.log()外更多的Javascript调试命令
2018/01/24 Javascript
nodejs取得当前执行路径的方法
2018/05/13 NodeJs
vue-cli监听组件加载完成的方法
2018/09/07 Javascript
微信小程序转发事件实现解析
2019/10/22 Javascript
python网络编程学习笔记(四):域名系统
2014/06/09 Python
Python封装shell命令实例分析
2015/05/05 Python
HTML中使用python屏蔽一些基本功能的方法
2017/07/07 Python
python数据结构之链表详解
2017/09/12 Python
解决Scrapy安装错误:Microsoft Visual C++ 14.0 is required...
2017/10/01 Python
Python爬虫实例爬取网站搞笑段子
2017/11/08 Python
python 统计列表中不同元素的数量方法
2018/06/29 Python
python中多层嵌套列表的拆分方法
2018/07/02 Python
用python 实现在不确定行数情况下多行输入方法
2019/01/28 Python
Python多叉树的构造及取出节点数据(treelib)的方法
2019/08/09 Python
使用OpenCV实现仿射变换—平移功能
2019/08/29 Python
Django多个app urls配置代码实例
2020/11/26 Python
使用CSS3实现多列布局与多背景的技巧
2016/02/29 HTML / CSS
HTML5 video循环播放多个视频的方法步骤
2020/08/06 HTML / CSS
美国在线健康和美容市场:Pharmapacks
2018/12/05 全球购物
Hoover胡佛官网:美国吸尘器和洗地机品牌
2019/01/09 全球购物
保加利亚手表、香水、化妆品和珠宝购物网站:Brasty.bg
2020/04/22 全球购物
女大学生自我鉴定
2013/12/09 职场文书
学习十八届三中全会精神实施方案
2014/02/17 职场文书