动态组件 & 插槽 & 自定义指令

一、动态组件

1. 什么是动态组件

动态组件指的是动态切换组件的显示与隐藏

2. 如何实现动态组件渲染

vue 提供了一个内置的 <component> 组件,专门用来实现动态组件的渲染
示例代码如下:
在这里插入图片描述
可以认为<component>是一个占位符,给组件占位,它的is属性指定哪个组件的名称,就把哪个组件渲染到它所在的位置。

3. 使用 keep-alive 保持状态

默认情况下,切换动态组件时无法保持组件的状态,会被销毁,此时可以使用 vue 内置的 <keep-alive> 组件保持动态组件的状态。
示例代码如下:
使用 keep-alive 保持状态

4. keep-alive 对应的生命周期函数

当组件被缓存时,会自动触发组件的 deactivated 生命周期函数。
当组件被激活时,会自动触发组件的 activated 生命周期函数。
在这里插入图片描述
当组件第一次被创建的时候,既会执行created生命周期(先),又会执行activated生命周期(后)。但组件被激活的时候只会触发activated生命周期,不再触发created,因为组件没有被创建。

只有在使用<keep-alive>时才能使用activated和deactivated生命周期

5. keep-alive 的 include 属性

include 属性用来指定:只有名称匹配的组件会被缓存。多个组件名之间使用英文的逗号分隔:
在这里插入图片描述
补充:还使用exclude属性指定不需要被缓存的组件,与include只能用其中之一,不能同时使用。

补充:如果在“声明组件”的时候没有为组件指定name名称,则组件的名称默认就是“注册时候的名称”。

如果声明了,当提供了name属性之后,组件的名称,就是name属性的值。

export default {
  name: MyRight
}

这时<keep-alive>中的include或者exclude属性值应当换成相应的组件名称

实际开发中建议都给组件添加name属性起组件名。

对比一下:

  1. 组件的“注册名称”主要应用场景是:以标签的形式,把注册好的组件,渲染和使用到页面结构中;

  2. 组件声明时候的“name名称”的主要应用场景:结合标签实现组件缓存功能,以及在调试工具中看到组件的name名称。

二、插槽

1. 什么是插槽

插槽(Slot)是 vue 为组件的封装者提供的能力。允许开发者在封装组件时,把不确定的、希望由用户指定的部分定义为插槽。

在这里插入图片描述
可以把插槽认为是组件封装期间,为用户预留的内容的占位符

2. 体验插槽的基础用法

在封装组件时,可以通过<slot>元素定义插槽,从而为用户预留内容占位符。示例代码如下:
在这里插入图片描述
实际上每个插槽都应该有name属性,来指定当前插槽的名称,如果省略了slot的name值,默认为default。默认情况下,在使用组件的时候提供的内容都会被填充到名字为default的插槽中。

如果要把指定内容填充到指定名称的插槽中,需要使用v-slot(简写为#)这个指令。v-slot后面要跟上插槽的名字,如v-slot:default,指令不能直接用在元素身上,必须用在<template>标签上,<template>它是一个虚拟的标签,只会起到包裹性质效果,不会渲染任何实质性的html元素。

2.1 没有预留插槽的内容会被丢弃

如果在封装组件时没有预留任何 插槽,则用户提供的任何自定义内容都会被丢弃。
在这里插入图片描述

2.2 后备内容

封装组件时,可以为预留的 <slot> 插槽提供后备内容(默认内容)。如果组件的使用者没有为插槽提供任何内容,则后备内容会生效。示例代码如下:
在这里插入图片描述

3. 具名插槽

如果在封装组件时需要预留多个插槽节点,则需要为每个 <slot> 插槽指定具体的 name 名称。这种带有具体名称的插槽叫做“具名插槽”。示例代码如下:

在这里插入图片描述

3.1 为具名插槽提供内容

在向具名插槽提供内容的时候,我们可以在一个 <template> 元素上使用 v-slot 指令,并以 v-slot 的参数的形式提供其名称。示例代码如下

在这里插入图片描述

3.2 具名插槽的简写形式

跟 v-on 和 v-bind 一样,v-slot 也有缩写,即把参数之前的所有内容 (v-slot:) 替换为字符 #。例如 v-slot:header可以被重写为 #header
在这里插入图片描述

总结:在子组件中封装插槽时slot节点用name属性定义插槽,在父组件使用插槽时template节点用v-slot命令指定内容渲染到哪个插槽里面。

4. 作用域插槽

在封装组件的过程中,可以为预留的 <slot> 插槽绑定 props 数据,这种带有 props 数据的 <slot> 叫做“作用域插槽”。示例代码如下:
在这里插入图片描述
在这里插入图片描述
在封装组件时,为预留的<slot>声明数据对象,提供属性对应的值,在使用插槽的时候接收该对象使用,这种用法叫作用域插槽。 建议将对象命名为scope(作用域)。

为插槽绑数据时可以直接写死也可以v-bind绑定数据源中的数据。

5.基于slot插槽重构购物车案例

5.1count渲染到slot插槽中

在这里插入图片描述

在这里插入图片描述

5.2父传子更方便了!

在这里插入图片描述
子组件Count
在这里插入图片描述
完成效果:
在这里插入图片描述

5.3实现增加减少功能

在这里插入图片描述
父组件
在这里插入图片描述
在这里插入图片描述

三、自定义指令

1. 什么是自定义指令

vue 官方提供了 v-text、v-for、v-model、v-if 等常用的指令。除此之外 vue 还允许开发者自定义指令。

2. 自定义指令的分类

vue 中的自定义指令分为两类,分别是:

⚫ 私有自定义指令(组件自己定义自己使用)

⚫ 全局自定义指令 (全局定义的其他所有组件都可以访问到)

3. 私有自定义指令

在每个 vue 组件中,可以在 directives 节点下声明私有自定义指令。
示例代码如下:

<h1 v-color>App 根组件</h1>

在这里插入图片描述
directives是自定义指令节点,里面包含了color自定义指令,指向一个配置的对象,里面有一个bind方法,bind方法的第一个形参是固定写法,是原生DOM对象,是指令绑定的元素
当指令被绑定到相应元素后,会立即触发指令中的bind方法。拿到el元素后就可以修改元素的颜色。

4. 使用自定义指令

在使用自定义指令时,需要加上 v- 前缀。
在这里插入图片描述

5. 为自定义指令动态绑定参数值

在 template 结构中使用自定义指令时,可以通过等号(=)的方式,为当前指令动态绑定参数值:
在这里插入图片描述

6. 通过 binding 获取指令的参数值

在声明自定义指令时,可以通过形参中的第二个参数,来接收指令的参数值:
在这里插入图片描述

<h1 v-color="color">App 根组件</h1>
<p v-color="'red'">测试</p> =====红色

其中value是使用的值,expression是用户写的v-color的值的表达式

7. update 函数

bind 函数只调用 1 次:当指令第一次绑定到元素时调用,当 DOM 更新时 bind 函数不会被触发update函数会在每次 DOM 更新时被调用
示例代码如下:

<h1 v-color="color">App 根组件</h1>
<p v-color="'red'">测试</p>
<button @click="color='green'">改变color的颜色值</button>
 directives: {
    // 定义名为color的自定义指令,指向一个配置对象
    color: {
      bind(el,binding) {
        el.style.color=binding.value
        console.log(binding);
      },
      // 在DOM更新的时候会触发update函数
      update(el,binding) {
        console.log("触发了v-color的update函数");
        el.style.color=binding.value
        console.log(binding);
      },
    }
  }

8. 函数简写

如果 bind和update 函数中的逻辑完全相同,则对象格式的自定义指令可以简写成函数格式
在这里插入图片描述

9. 全局自定义指令

全局共享的自定义指令需要通过“Vue.directive()”进行声明,示例代码如下:

/*
*main.js
*/
// 全局自定义指令
Vue.directives('color', function(el,binding){
  el.style.color = binding.value
})

(类似定义全局过滤器)这样其他组件都可以使用v-color指令。

实际开发中更常用全局自定义指令。

10.关于main.js中 的小提示

/*
*main.js
*/
Vue.config.productionTip = true

在这里插入图片描述

此时控制台信息。提示打包发布时要用生产模式。默认是false,无意义的!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
组件是 Vue.js 中最重要的概念之一。组件可以让我们将 UI 拆分为独立、可复用的部件,使得代码更加清晰、易于维护。在 Vue.js 中,组件可以分为全局组件和局部组件,其中全局组件可在任何地方使用,而局部组件只能在其父组件中使用。 定义组件时,需要使用 Vue.component() 方法,该方法需要传入两个参数:组件名称和组件配置对象。组件名称应该采用 kebab-case(短横线分隔命名)格式,以便在 HTML 中使用。 示例代码如下: ```javascript // 定义一个名为 button-counter 的新组件 Vue.component(&#39;button-counter&#39;, { data: function () { return { count: 0 } }, template: &#39;&lt;button v-on:click=&quot;count++&quot;&gt;You clicked me {{ count }} times.&lt;/button&gt;&#39; }) ``` 在上述代码中,我们定义了一个名为 button-counter 的组件,该组件包含一个计数器,每次点击按钮计数器加一。 在 HTML 中使用组件时,需要使用组件名称作为自定义标签来调用组件。示例代码如下: ```html &lt;div id=&quot;app&quot;&gt; &lt;button-counter&gt;&lt;/button-counter&gt; &lt;/div&gt; ``` 在上述代码中,我们调用了 button-counter 组件,并将其渲染到了 id 为 app 的 div 元素中。 除了组件的 data 和 template 属性外,还可以使用 props 属性来传递组件之间的数据。使用 props 时,需要在组件的配置对象中定义 props 属性,并在 HTML 中使用 v-bind 指令来传递数据。 示例代码如下: ```javascript // 定义一个名为 todo-item 的新组件 Vue.component(&#39;todo-item&#39;, { props: [&#39;todo&#39;], template: &#39;&lt;li&gt;{{ todo.text }}&lt;/li&gt;&#39; }) // 创建一个 Vue 实例 var app = new Vue({ el: &#39;#app&#39;, data: { groceryList: [ { id: 0, text: &#39;蔬菜&#39; }, { id: 1, text: &#39;水果&#39; }, { id: 2, text: &#39;奶酪&#39; } ] } }) ``` 在上述代码中,我们定义了一个名为 todo-item 的组件,并使用 props 属性定义了一个名为 todo 的 prop。在 HTML 中,我们使用 v-bind 指令将 groceryList 数组中的每个对象传递给了 todo-item 组件。示例代码如下: ```html &lt;div id=&quot;app&quot;&gt; &lt;ul&gt; &lt;todo-item v-for=&quot;item in groceryList&quot; v-bind:todo=&quot;item&quot; v-bind:key=&quot;item.id&quot;&gt;&lt;/todo-item&gt; &lt;/ul&gt; &lt;/div&gt; ``` 在上述代码中,我们使用 v-for 指令遍历 groceryList 数组,并使用 v-bind 指令将数组中的每个对象传递给了 todo-item 组件。注意,我们还需要使用 v-bind:key 指令来为每个列表项指定一个唯一的 key 值。 是 Vue.js 中另一个重要的概念。可以让父组件在子组件入任意的 HTML 内容,使得组件更加灵活、可复用。 在子组件中,使用 &lt;slot&gt; 标签来定义。在父组件中,使用子组件的自定义标签来调用组件,并在标签内部入 HTML 内容。示例代码如下: ```javascript // 定义一个名为 alert-box 的新组件 Vue.component(&#39;alert-box&#39;, { template: ` &lt;div class=&quot;alert-box&quot;&gt; &lt;strong&gt;Error!&lt;/strong&gt; &lt;slot&gt;&lt;/slot&gt; &lt;/div&gt; ` }) // 创建一个 Vue 实例 var app = new Vue({ el: &#39;#app&#39; }) ``` 在上述代码中,我们定义了一个名为 alert-box 的组件,并在组件定义了一个。在 HTML 中,我们调用了 alert-box 组件,并在标签内部入了一些 HTML 内容。示例代码如下: ```html &lt;div id=&quot;app&quot;&gt; &lt;alert-box&gt; &lt;p&gt;Something bad happened.&lt;/p&gt; &lt;/alert-box&gt; &lt;/div&gt; ``` 在上述代码中,我们调用了 alert-box 组件,并在标签内部入了一些 HTML 内容。该 HTML 内容会被入到 alert-box 组件中。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值