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

前言

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中一些容易忽视的点进行了简单的总结,希望看完之后能对大家有所帮助。也希望大家多多支持我们。

(0)

相关推荐

  • Vue面试题及Vue知识点整理

    看面试题,只是为了查漏补缺,看看自己那些方面还不懂.切记不要以为背了面试题,就万事大吉了,最好是理解背后的原理,这样面试的时候才能侃侃而谈.不然,稍微有水平的面试官一看就能看出,是否有真才实学还是刚好背中了这道面试题.(都是一些基础的vue面试题,大神不用浪费时间往下看) 一.对于MVVM的理解? MVVM 是 Model-View-ViewModel 的缩写.Model代表数据模型,也可以在Model中定义数据修改和操作的业务逻辑.View 代表UI 组件,它负责将数据模型转化成UI 展现出来

  • vuex进阶知识点巩固

    一. Getter 我们先回忆一下上一篇的代码 computed:{ getName(){ return this.$store.state.name } } 这里假设现在逻辑有变,我们最终期望得到的数据(getName),是基于 this.$store.state.name 上经过复杂计算得来的,刚好这个getName要在好多个地方使用,那么我们就得复制好几份. vuex 给我们提供了 getter,请看代码 (文件位置 /src/store/index.js) import Vue from

  • Vue.js在使用中的一些注意知识点

    本文介绍的Vue.js在使用中的一些注意知识点,对大家具有一定的参考价值,下面来看看详细的介绍吧. 每个 Vue 实例都会代理其 data 对象里所有的属性. 注意只有这些被代理的属性是响应的.如果在实例创建之后添加新的属性到实例上,它不会触发视图更新. 除了 data 属性,Vue实例暴露了一些有用的实例属性与方法.这些属性与方法都有前缀 $,以便与代理的 data 属性区分. 模板语法 Vue.js 使用了基于HTML的模版语法,允许开发者声明式地将 DOM 绑定至底层 Vue 实例的数据.

  • Vue组件通信中非父子组件传值知识点总结

    前言: 如果想要了解非父子关系的组件传值,最好是在了解父传子和子传父的基础上在来了解非父子传值可能会有更透彻的思路. 因为非父子传值是通过定义事件总线来代理实现父传子+子传父从而实现的传值方式. 这是我总结的父子传值相关的知识,可供参考:  https://www.jb51.net/article/121806.htm 然后大概回顾一下父子传值的过程: 根据上述信息可知,如果两个组件需要传递值那么需要这两个组件之间是父子关系才能传递数据. 那么如果有这样一个组件,既可以帮你传递数据,又可以帮你接

  • 关于vue.js弹窗组件的知识点总结

    首先在开发时需要考虑以下三点: 1.进入和弹出的动画效果. 2.z-index 的控制 3.overlay 遮盖层 关于动画 vue 对于动画的处理相对简单,给组件加入css transition 动画即可 <template> <div class="modal" transition="modal-scale"> <!--省略其它内容--> </div> </template> <script&g

  • Vue.js进阶知识点总结

    对大部分人来说,掌握Vue.js基本的几个API后就已经能够正常地开发前端网站.但如果你想更加高效地使用Vue来开发,成为Vue.js大师,那下面我要传授的这五招你一定得认真学习一下了. 第一招:化繁为简的Watchers 场景还原: created(){ this.fetchPostList() }, watch: { searchInputValue(){ this.fetchPostList() } } 组件创建的时候我们获取一次列表,同时监听input框,每当发生变化的时候重新获取一次筛

  • vue项目前端知识点整理【收藏】

    微信授权后还能通过浏览器返回键回到授权页 在导航守卫中可以在 next({}) 中设置 replace: true 来重定向到改路由,跟 router.replace() 相同 router.beforeEach((to, from, next) => { if (getToken()) { ... } else { // 储存进来的地址,供授权后跳回 setUrl(to.fullPath) next({ path: '/author', replace: true }) } }) 路由切换时页

  • vue路由拦截器和请求拦截器知识点总结

    路由拦截器 已路由为导向 router.beforeEach((to,from,next)=>{ if(to.path=='/login' || localStorage.getItem('token')){ next(); }else{ alert('请重新登录'); next('/login'); } }) 请求拦截器 当发送请求时才会触发此功能 axios.interceptors.request.use(function (config) { let token = window.loc

  • vue双向数据绑定知识点总结

    1.原理 vue的双向数据绑定的原理相信大家都十分了解:主要是通过ES5的Object对象的defineProperty属性:重写data的set和get函数来实现的 所以接下来不使用ES6进行实际的代码开发:过程中如果函数使用父级this的情况:还是使用显示缓存中间变量和闭包来处理:原因是箭头函数没有独立的执行上下文this:所以箭头函数内部出现this对象会直接访问父级:所以也能看出箭头函数是无法完全替代function的使用场景的:比如我们需要独立的this或者argument的时候 1.

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

    前言 Vue的学习成本和难度不高,这除了和框架本身的设计理念有关之外,还和Vue完善的官方文档有着密不可分的关系,相信有很多的开发者和我一样,很长时间没有仔细去看过官方文档了,最近花时间仔细看了一下官方文档,将里面一些容易忽视的点整理出来和大家分享. 容易忽视的点 箭头函数的使用 ES6的普及使得箭头函数的使用更加频繁,但是在Vue中不要在选项属性或者回调上使用箭头函数,举个例子: new Vue({ el: '#app', data: { show: true }, created: () =

  • Vue中使用计算属性的知识点总结

    计算属性 有些时候,我们在模板中放入了过多的逻辑,从而导致模板过重,且难以维护.例如: <div id="app"> {{ message.split('').reverse().join('') }} </div> 碰到这样的情况,我们必须看一段时间才能意识到,这里是想要显示变量message的翻转字符串,而且,一旦我们想要在模板中多次使用翻转字符串时,会更加麻烦. 所以,当我们处理复杂逻辑时,都应该使用计算属性. 基础用法 计算属性是Vue配置对象中的属性,

  • 简述vue中的config配置

    在webpack.base.conf文件中配置别名以及扩展名 resolve: { extensions: ['.js', '.vue', '.json', '.styl'], alias: { 'vue$': 'vue/dist/vue.esm.js', '@': resolve('src'), 'src': path.resolve(__dirname, '../src'), 'common': path.resolve(__dirname, '../src/common'), 'compo

  • Vue中jsx不完全应用指南小结

    前言:文章不介绍任务背景知识,没有原理说明,偏向于实践的总结和经验分享. 文章所有的代码是基于Vue CLI 3.x版本,不会涉及到一步步通过Webpack来配置JSX所需要的知识点. 在使用Vue开发项目时绝大多数情况下都是使用模板来写HTML,但是有些时候页面复杂又存在各种条件判断来显示/隐藏和拼凑页面内容,或者页面中很多部分存在部分DOM结构一样的时候就略显捉襟见肘,会写大量重复的代码,会出现单个.vue文件过长的情况,这个时候我们就需要更多的代码控制,这时候可以使用渲染函数. 渲染函数想

  • vue中对虚拟dom的理解知识点总结

    本质是一个普通的js对象,用于描述视图界面结构的, 在mouted的回调中,可以输出_vnode, 通过图可以知道,_vnode中有以下几个主要的属性: tag:组件的标签名, data: 组件的属性, children: 组件的子标签 parent: 父级元素 render函数: 作用:创建虚拟dom, 每个组件都有虚拟dom,并且虚拟dom都是由render函数创建的: 使用虚拟dom树的目的:提高渲染效率 在vue中,当渲染视图时候会调用render函数.这种渲染不仅发生在组件创建时候,还

  • vue中的虚拟dom知识点总结

    目录 一.简介 二.为什么VUE引入了虚拟DOM? 三.vnode 1.vnode的类型 四.虚拟dom的核心——patch 1.patch的过程 新增节点 删除节点 更新节点 静态节点 新虚拟节点有文本属性 新虚拟节点无文本属性 五.更新子节点的优化策略 一.简介 虚拟dom是随着时代发展而诞生的产物. 命令式操作dom: 简单易用 程序中的状态很难管理,代码中的逻辑也很混乱. 现在三大主流框架都是声明式操作DOM.通过描述状态和DOM之间的映射关系,就可以将状态渲染成视图.状态可以是JS 中

  • Vue中this.$router.push参数获取方法

    传递参数的方法: 1.Params 由于动态路由也是传递params的,所以在 this.$router.push() 方法中path不能和params一起使用,否则params将无效.需要用name来指定页面. 及通过路由配置的name属性访问 在路由配置文件中定义参数: 通过name获取页面,传递params: 在目标页面通过this.$route.params获取参数: 2.Query 页面通过path和query传递参数,该实例中row为某行表格数据 在目标页面通过this.$route

  • Vue中的methods、watch、computed的区别

    看到这个标题就知道这篇文章接下来要讲的内容,我们在使用vue的时候methods.watch.computed这三个特性一定经常使用,因为它们是非常的有用,但是没有彻底的理解它们的区别和各自的使用场景,也很难用好它们,希望接下来的介绍为你答疑解惑. computed 我们先来看计算属性:computed,光看名字也知道是用来干什么的,计算属性当然是用来计算的,但是是怎么计算的呢?计算属性有两个显著的特点: 计算属性计算时所依赖的属性一定是响应式依赖,否则计算属性不会执行 计算属性是基于依赖进行缓

  • vue中的v-if和v-show的区别详解

    v-if和v-show的区别是前端面试中常问的基础知识点,v-if.v-show顾名思义就是用来判断视图层展示效果的.那么具体是怎么展示呢?v-if和v-show的区别又是什么呢? 首先我们可以来看一下Vue中文社区说明文档的介绍: Vue中文社区说明文档中简单来说是:初始渲染的时候进行条件判断展示: 在实际开发中我们会经常使用到v-if和v-show来进行判断展示,我们可以这么理解: <div class="tc" v-if="pload && lis

  • vue中npm包全局安装和局部安装过程

    全局安装是将npm包安装在你的node安装目录下的node_modules文件夹中.在windows和mac中,全局安装的默认路径是不同的.在mac中默认是安装到 /usr/locla/lib 中.在windows默认安装目录是 C:\Program Files\nodejs ,当然你也可以通过一下命令来查看全局安装路径. // 查看全局安装路径 npm root -g // 查看npm的基础设置 npm config ls // 查看安装目录路径 npm config get prefix 全

随机推荐