Vue进阶难点总结

257 阅读3分钟

一、$nextTick相关知识

1.为什么需要nextTick?

Vue是异步修改DOM的,因此不鼓励开发者直接接触DOM,但有时候业务需要必须对数据更改--刷新后的DOM做相应的处理,这时候就可以使用Vue.nextTick(callback)这个api了。

2.理解nextTick原理

首先要知道事件循环中的宏任务和微任务这两个概念。 常见的宏任务有:scrip,setTimeout,setInterval,setImmediate,I/o,UI rendering

常见的微观任务有: process.nextTick(Nodejs),Promise.then(), MutationObserver;

nextTick 的原理正是 vue 通过异步队列控制 DOM 更新和 nextTick 回调函数先后执行的方式。

3.使用场景

1)当视图更新之后,DOM是异步的,因此数据会有延迟,拿不到最新数据,为了拿到最新的数据,基于新的视图进行操作用this.$nextTick()来操作。

2)第三方插件,在vue生成的某些dom动态发生变化时重新应用该插件。

二、ref与refs

利用 ref 和 $refs 可以用于获取 dom 元素

如: <h1 id="h" ref="myH">小狗狗,想要拿到h1标签的内容,除了可以用document.getElementById("h")之外,还可以this.$refs.myH的方法,这就是利用了ref和$refs的属性,正是这个原理可以获取到组件对象,调用组件里的方法。

ref定义值, 通过$refs.值 来获取组件对象, 就能继续调用组件内的变量

三、插槽

vue提供组件插槽能力, 允许开发者在封装组件时,把不确定的部分定义为插槽

1.基础语法

概念:子组件使用 <slot></slot> 接收父组件传过来的HTML结构。

口诀:

  1. 组件内用占位
  2. 使用组件时夹着的地方, 传入标签替换slot 父组件:<myComp><div></div></myComp>

子组件:<slot></slot>

默认值:<slot>default value</slot>

组件内容分发技术, slot占位, 使用组件时传入替换slot位置的标签

2.具名插槽

概念:一个组件里,可以设置多个插槽,然后在父组件里可以写多个<template>来填充这些插槽(当一个组件内有2处以上需要外部传入标签的地方)

口诀:

  1. 子组件, 在slot上绑定属性和子组件内的值
  2. 使用组件, 传入自定义标签, 用template和v-slot="自定义变量名"
  3. scope变量名自动绑定slot上所有属性和值

父组件:<template v-slot:header=“scope”>(可以简写为<template #header=“scope”>,v-slot简写为#) 子组件:<slot name="header">

组件内变量绑定在slot上, 然后使用组件v-slot="变量" 变量上就会绑定slot身上属性和值

作用域插槽的用法有点像Vue组件通信中的子传父,但是子传父只能穿数据,而作用域不仅能传数据还能将标签结构一起传过来,经常与<template><template/>及其他标签搭配使用,便于代码优化和后期维护。

例如:父组件中

image.png 子组件中

image.png

出来的效果例一是图片地址,例二是正常显示的图片

四、自定义指令

除了核心功能默认内置的指令 (v-modelv-show),Vue 也允许注册自定义指令。 v-xxx

1.全局自定义指令

全局自定义指令任意的VUE文件都可以使用,在mian.js中定义,定义方法为:

   Vue.directive("自定义指令名", {
          inserted(el){
            el: 表示使用指令时的标签
          }
        })
   自定义指令传参:     
        Vue.directive('color',{
  inserted(el,binding){
    el.style.color = binding.value
  },
  update(el,binding){
    el.style.color = binding.value

  }
})
使用方法:<input v-focus  />

什么时候用update?

inserted相当于mounted挂载到页面中触发,只挂载一次,如果进行修改后浏览器没反应,这时候就需要用update来重新更新,所以如果指令后期修改就需要用Update更新。

2.局部自定义指令

局部自定义指令需要在父组件中注册后才能使用。 局部(组件中注册)定义为:

directives:{
          "自定义指令名": {
            inserted(el){
              el: 表示使用指令时的标签
            }
          }
        }

3.生命周期函数

directive也是有生命周期的,但是指令生命周期名字和组件生命周期名字的不一样。

inserted 相当于 mounted
update 相当于 updated

生命周期函数接受两个参数 绑定形式:v-color="red"

el:DOM元素
binding: 传递的属性值
获取hello方法:binding.value
    

五、说一下你在vue中踩过的坑(必会)

1、第一个是给对象添加属性的时候,直接通过给data里面的对象添加属性然后赋值,新添加的属性不是响应式的

【解决办法】通过Vue.set(对象,属性,值)这种方式就可以达到,对象新添加的属性是响应式的

2、 在created操作dom的时候,是报错的,获取不到dom,这个时候实例vue实例没有挂载

【解决办法】通过:Vue.nextTick(回调函数进行获取)

六、 $route$router的区别?

$route是路由信息对象,包括‘path,hash,query,fullPath,matched,name’等路由信息参数; $router是路由实例对象,包括了路由的跳转方法,实例对象等