Vue2全家桶 - Vue2 - 【3】组件进阶【动态组件、组件缓存、组件激活和非激活、插槽、自定义指令】

一、动态组件(了解)

  • Vue3已经废除了动态组件,包括Vue2的过滤器也废掉了;
  • 定义
    • 多个组件 使用 同一个挂载点 ,并 动态切换
  • 使用场景
    • 同一个挂载点 切换 不同组件 显示;
  • 原理
    • v-if + v-else-if(只用v-if也是可以的)
  • 实现步骤
    1. 设置 数据属性 ,来承载要显示的组件名:
      • 注意点
        • 数据属性属性值 === 组件名;
    2. 设置 挂载点<component :is="Vue数据属性"></component>,使用 is 来设置要 显示哪个组件
      • 注意点
        • <component>是 Vue内置组件;
        • 使用 v-bindis属性 动态赋值
    3. 根据需求,切换数据属性值

二、组件缓存

  • 使用 <component> 频繁切换组件 存在的问题:

    • 使用<component>内置组件频繁切换会导致组件一直在被创建和销毁性能低(会将该组件所有的代码执行一遍),影响用户体验(如果有Ajax请求还会浪费用户流量);
    • 解决方法:⬇
  • 语法:

    js 复制代码
    <keep-alive>
        <component :is="Vue数据属性"></component>
    </keep-alive>
  • 原理

    • 使用Vue内置的keepAlive组件,包裹要频繁切换的组件,将其缓存起来 ,在切换的时候,不会再去创建,直接从缓存中获取(纯属废话了,原理这块可以去问问度娘,后面我会补充);
  • 组件缓存的好处

    • 缓存组件的状态(数据不丢失);
    • 提高性能(可以避免组件切来切去发起无效请求);
    • 提升用户体验;

三、组件激活和非激活

  • 配合 <keep-alive> 使用:
    • 使用了该标签,activated 钩子替换 createddeactivated 钩子替换 activated钩子;
  • 2个新的生命周期钩子函数
    • 作用:
      • 知道 缓存组件出现还是消失;
      • activated : 激活时 自动触发 (类似于created()钩子);
      • deactivated : 停用时 触发(类似于destroyed()钩子)

❗ 四、组件插槽

  • 作用:
    • 通过 slot 标签,让 组件内 可以 接收 不同的标签结构 显示 不同的效果 (使用slot标签进行占位,要显示什么就直接插入到组件标签里面);
    • 解决了 组件内 标签 不确定 的问题;
  • Vue2官网 - 插槽

4.1 匿名插槽

  • 步骤: (先占位再分发)

    1. 组件内 标签不确定地方 使用 <slot></slot> 占位;
    2. 使用组件 时,在 组件标签内 插入 要显的 标签 即可(插入的标签 替换 slot标签 );
  • 原理

    • 使用 组件标签 内的 标签结构 去替换 slot标签
  • 语法:

    • 写法1

      html 复制代码
      <!-- 父组件 - 直接传递标签结构,不写template标签 -->
      <组件标签>
          要传递的标签结构
      </组件标签>
      
      <!-- 子组件 -->
      <!-- 使用 slot 标签占位 -->
      <slot></slot>
    • 写法2

      html 复制代码
      <!-- 父组件 - 将传递的标签结构包裹在template中进行传递 -->
      <组件标签>
          <template>
              要传递的标签结构
          </template>
      </组件标签>
      
      -------------------------
      
      <!-- 子组件: -->
      <!-- 使用 slot 标签占位 -->
      <slot></slot>
    • 写法3

      • <slot> 不加 name属性Vue 会 自动添加 name属性default
      • template标签v-solt 属性值就是 default
      html 复制代码
      <!-- 父组件 - 将传递的标签结构包裹在template中,并给template添加 v-slot:default 进行传递 -->
      <组件标签>
          <!-- 不使用简写 -->
          <template v-slot:default></template>
          
          <!-- v-slot: 简写  -->
          <template #default></template>
      </组件标签>
      
      -------------------------
      
      <!-- 子组件: -->
      <slot name="default"></slot>
  • 示例展示:

  • 总结

    • 对比上面展示的效果图,得知 三种写法之间存在 优先级;
    • 第三种写法的优先级最高;
    • 第一种写法和第二种写法一样;
    • 如果三种语法同时存在,只显示有v-slot:default#default 的结构;

4.2 插槽默认内容

  • <slot> 内放置内容,作为插槽的 默认内容

    • <slot> 中夹着的 所有标签文字 都属于 默认内容
    html 复制代码
        <slot> 默认内容(可以是任意的) </slot>
  • 在组件标签内传递了标签结构,就显示传递的;否则就显示默认的;

4.3 具名插槽

  • 使用步骤:
    1. 子组件内 使用 slot标签 占位添加 name属性(属性值自定义);
    2. 父组件内子组件标签 内部, 用 template标签 包裹 要传递的标签结构 ,并给 template标签 添加 v-slot指令指令的属性值 === slot标签的 name 属性值 )标明要替换的slot标签(slot标签template标签相对应 的);
      • template:Vue内置的组件,只起包裹作用,不会渲染到页面上;
  • 注意
    • v-slot语法

      html 复制代码
      <!-- 不使用简写 -->
      <template v-slot:slot标签的name属性值> </template>
      
      <!-- 简写语法 -->
      <template #slot标签的name属性值> </template>
    • slot标签的name属性值 === templte标签v-slot指令的值

    • 任何没有被包裹在带有 v-slot<template> 中的内容都会被视为默认插槽的内容;

  • 示例展示:

4.4 作用域插槽

  • 使用步骤
    1. 子组件内 ,在 <slot>标签绑定自定义属性设置属性值
      • 属性名
        • 自定义
      • 属性值
        • Vue数据属性(data中的数据);
      • 绑定的值
        • 字符串:不需要使用指令;
        • 变量:要使用 v-bind 指令(使用简写);
    2. 父组件内 ,先导入子组件,再使用该组件,传入自定义标签结构,用 template标签 包裹 要传入的内容设置 v-slot:xxx = "子组件内slot上的自定义变量名"
    3. 自定义变量名 自动绑定 slot标签所有属性 和 值
  • 🔺 注意两种写法的区别
    • v-slot:子组件内slot标签name属性值具名插槽
    • v-slot:子组件内slot标签name属性值="子组件内slot标签的自定义变量名"作用域插槽
      • 对上面的简写:
        • #子组件内slot标签name属性值="子组件内slot标签的自定义变量名"
  • 作用域插槽
    • 带数据的插槽,带的是子组件内部的数据,带给父组件,父组件接收到子组件的数据,并且可以通过插槽回传给子组件;
  • 作用域插槽是插槽的终极版
    • 普通插槽只能做到给子组件分发内容,不能获取子组件的数据;
    • 作用域插槽不仅可以给子组件分发内容还能拿到子组件的数据,再回传给子组件;
  • 使用场景
    • 插槽内容能够访问子组件内的数据;
  • 示例展示:
    • 作用域插槽是根据匿名插槽或具名插槽演变而来;
  • 作用域插槽细节
    • v-slot:名字名字 需要与 slot标签的name属性值 保持一致
    • v-slot: ➡ 可以简写成 #
    • 因为接收到的数据是对象,为了今后使用方便,可以在原地进行解构;

4.5 插槽总结

  • 作用
    • 解决组件内标签内容不确定的问题;
  • 分类 :(3类)
    1. 匿名 / 默认插槽
      • 作用
        • 解决 组件内 只有一处 标签不确定 的 问题;
      • 使用步骤
        • 先占位 + 再分发内容(只分发内容,有三种写法):
        • 写法1:不写 template
        • 写法2:写 template,不写 #
        • 写法3:写 template + #default
    2. 具名插槽
      • 作用
        • 解决 组件内 有 两处及以上 标签不确定 的 问题;
      • 使用步骤
        • 先占位并添加name属性 + 分发内容并添加#slot的name属性值
    3. 作用域插槽
      • 作用
        • 标签不确定的问题 + 插槽内容使用子组件数据;
      • 使用步骤:
        • 传数据(slot上自定义属性名,属性值为传递的数据) + 接数据(template #slot的name属性值 = "变量名");
        • 使用的时候,可以对对象进行解构。

五、自定义指令

  • 普通DOM元素 进行 原生操作

    • ref;
    • 自定义指令;
  • 关于自定义指令的参数,请移步Vue2官网 - 自定义指令

  • 全局注册:

    • 目标文件:main.js
    html 复制代码
    // 所有的 Vue. 都要写在 new Vue 前面
    // 定义 的时候 不加v-,使用 的时候必须 加v-
    Vue.directive('指令名', {
      // inserted:指令的钩子函数之一,表示指令所在DOM元素插入到真实DOM中自动 触发一次
      // el:当前指令所在的DOM元素
      inserted (el) { 
        // 可以对el标签扩展额外功能
      }
    })
    
    ------------
    
    // 携带数据
    Vue.directive ('指令名', {
      // binding:记录了指令相关信息的对象
      // 就关心binding.value这个属性值,里面记录的使指令后面表达式的值
      inserted (el, binding) {
      }
    })
    
    --------------
    
    // update()也是指令钩子函数之一,表示指令所在组件数据变了的时候,每次都会执行一次
    Vue.directive ('指令名', {
      inserted (el, binding) { 相同代码 },
      undate (el, binding) { 相同代码 }
    })
  • 局部注册:

    • 目标文件:某个.vue文件;
    html 复制代码
    export dafault {
        directives: {
            focus: {
                // 指令的定义
                inserted: function (el) {
                    el.focus()
                }
            }
        }
    }
  • 自定义指令的使用

    • 全局注册
      • 该项目中任何 .vue 文件都是可以使用;
    • 局部注册
      • 只能在当前 .vue 文件中使用;
  • 🔺 注意

    • 定义 的时候 不加v-,使用 的时候必须 加v-
  • 代码展示:

    • 全局定义:
    • 使用:
    • 传数据并且可以修改数据:
相关推荐
NoloveisGod17 分钟前
Vue的基础使用
前端·javascript·vue.js
GISer_Jing19 分钟前
前端系统设计面试题(二)Javascript\Vue
前端·javascript·vue.js
海上彼尚1 小时前
实现3D热力图
前端·javascript·3d
杨过姑父1 小时前
org.springframework.context.support.ApplicationListenerDetector 详细介绍
java·前端·spring
理想不理想v1 小时前
使用JS实现文件流转换excel?
java·前端·javascript·css·vue.js·spring·面试
惜.己1 小时前
Jmeter中的配置原件(四)
java·前端·功能测试·jmeter·1024程序员节
EasyNTS1 小时前
无插件H5播放器EasyPlayer.js网页web无插件播放器vue和react详细介绍
前端·javascript·vue.js
老码沉思录1 小时前
React Native 全栈开发实战班 - 数据管理与状态之Zustand应用
javascript·react native·react.js
poloma1 小时前
五千字长文搞清楚 Blob File ArrayBuffer TypedArray 到底是什么
前端·javascript·ecmascript 6
老码沉思录1 小时前
React Native 全栈开发实战班 :数据管理与状态之React Hooks 基础
javascript·react native·react.js