vue入门之05-动态组件 & 插槽 & 自定义指令

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

1. 动态组件

1.1 什么是动态组件

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

1.2 如何实现动态组件渲染

vue 提供了一个内置的 <component> 组件,专门用来实现动态组件的渲染。示例代码如下:

App.vue

<template>
  <div class="app-container">
    <h1>App 根组件</h1>
    <hr />

    <button @click="comName = 'Left'">展示 Left</button>
    <button @click="comName = 'Right'">展示 Right</button>

    <div class="box">
      <!-- 渲染 Left 组件和 Right 组件 -->
      <!-- 1. component 标签是 vue 内置的,作用:组件的占位符 -->
      <!-- 2. is 属性的值,表示要渲染的组件的名字 -->
      <!-- 3. is 属性的值,应该是组件在 components 节点下的注册名称 -->
        <component :is="comName"></component>
    </div>
  </div>
</template>

<script>
import Left from '@/components/Left.vue'
import Right from '@/components/Right.vue'

export default {
  data() {
    return {
      // comName 表示要展示的组件的名字
      comName: 'Left'
    }
  },
  components: {
    // 如果在“声明组件”的时候,没有为组件指定 name 名称,则组件的名称默认就是“注册时候的名称”
    Left,
    Right
  }
}
</script>
<style lang="less">
.app-container {
  padding: 1px 20px 20px;
  background-color: #efefef;
}
.box {
  display: flex;
}
</style>

Left.vue

<template>
  <div class="left-container">
    <h3>Left 组件 --- {{ count }}</h3>
    <button @click="count += 1">+1</button>
  </div>
</template>

<script>
export default {
  name: 'MyLeft',
  data() {
    return {
      count: 0
    }
  },
  created() {
    console.log('Left 组件被创建了!')
  },
  destroyed() {
    console.log('Left 组件被销毁了~~~')
  },
}
</script>
<style lang="less">
.left-container {
  padding: 0 20px 20px;
  background-color: orange;
  min-height: 250px;
  flex: 1;
}
</style>

Right.vue

<template>
  <div class="right-container">
    <h3>Right 组件</h3>
  </div>
</template>
<script>
export default {
  // 当提供了 name 属性之后,组件的名称,就是 name 属性的值
  // 对比:
  // 1. 组件的 “注册名称” 的主要应用场景是:以标签的形式,把注册好的组件,渲染和使用到页面结构之中
  // 2. 组件声明时候的 “name” 名称的主要应用场景:结合 <keep-alive> 标签实现组件缓存功能;以及在调试工具中看到组件的 name 名称
  name: 'MyRight'
}
</script>

<style lang="less">
.right-container {
  padding: 0 20px 20px;
  background-color: lightskyblue;
  min-height: 250px;
  flex: 1;
}
</style>

实验结果 发现当你轮流点击俩个按钮时 无法保存组件的状态 组件不会被缓存
在这里插入图片描述

1.3 使用 keep-alive 保持状态

默认情况下,切换动态组件时无法保持组件的状态。此时可以使用 vue 内置的 组件保持动态组
件的状态。示例代码如下:

App.vue

在这里插入图片描述

在left.vue中添加几个函数进行验证 (跟created同级别)

在这里插入图片描述

实验结果

在这里插入图片描述

结论

.keep-alive 对应的生命周期函数
当组件被缓存时,会自动触发组件的 deactivated 生命周期函数
当组件被激活时,会自动触发组件的 activated生命周期函数。

1.4 keep-alive 的include属性

include 属性用来指定:只有名称匹配的组件会被缓存。多个组件名之间使用英文的逗号分隔:

在这里插入图片描述

1.5 动态组件的适用范围

可以进行导航栏的切换以及移动端网页的切换

点击left 显示left组件

点击right 显示right组件内容

在这里插入图片描述

2. 插槽

2.1 什么是插槽

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

可以把插槽认为是组件封装期间,为用户预留的内容的占位符

2.2 插槽的基本用法

在封装组件时,可以通过 元素定义插槽,从而为用户预留内容占位符。示例代码如下:

在这里插入图片描述

右边这个组件中留了一个slot插槽

在左边使用这个组件时,中间用户自定义添加的东西加入到右边这个插槽中

注意

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

2.3 后备内容

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

<div class="left-container">
    <h3>Left 组件</h3>
    <hr />
    <!-- 声明一个插槽区域 -->
    <!-- vue 官方规定:每一个 slot 插槽,都要有一个 name 名称 -->
    <!-- 如果省略了 slot 的 name 属性,则有一个默认名称叫做 default -->
    <slot name="default">
      <h6>这是 default 插槽的后备内容</h6>
    </slot>
  </div>

App.vue

 <Left>
        默认情况下,在使用组件的时候,提供的内容都会被填充到名字为 default 的插槽之中
     1. 如果要把内容填充到指定名称的插槽中,需要使用 v-slot: 这个指令
     2. v-slot: 后面要跟上插槽的名字 -->
     3. v-slot: 指令不能直接用在元素身上,必须用在 template 标签上 -->
     4. template 这个标签,它是一个虚拟的标签,只起到包裹性质的作用,但是,不会被渲染为任何实质性的 html 元素 
     5. v-slot: 指令的简写形式是 # 
     // 用户自定义的内容会寻找一个名字未default的slot中, 进行插槽
        <template #default>
          <p>这是在 Left 组件的内容区域,声明的 p 标签</p>
      
      </Left>

2.4 具名插槽

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

在这里插入图片描述

注意:没有指定 name 名称的插槽,会有隐含的名称叫做 “default”

向具体的插槽添加内容

在这里插入图片描述

2.5 作用域插槽

在封装组件的过程中,可以为预留的 插槽绑定 props 数据,这种带有 props 数据的 叫做“作用域插槽”。示例代码如下:

父组件中

在这里插入图片描述

子组件

在这里插入图片描述

父组件中可以通过v-slot=content的缩写#content="msg"来接收子组件的msg数值

2.6 解构插槽

假如

子组件中有俩个值进行传送

<slot v-for="item in items" :user="item"></slot>

父组件

<template v-slot:default="{user}">

</template>

指定接收user的值 不接收items的数值

3 自定义指令

3.1 什么是自定义指令

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

3.2 自定义指令的分类

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

  • 私有自定义指令
  • 全局自定义指令

3.3 私有自定义指令

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

// 私有自定义指令的节点
  directives: {
    // 定义名为 color 的指令,指向一个配置对象
    color: {
      // 当指令第一次被绑定到元素上的时候,会立即触发 bind 函数
      // 形参中的 el 表示当前指令所绑定到的那个 DOM 对象
      bind(el, binding) {
        console.log('触发了 v-color 的 bind 函数')
        el.style.color = binding.value
      },
    
    } 
   
  }
3.3.1 使用自定义指令

在使用自定义指令时,需要加上v-前缀。示例代码如下:

在这里插入图片描述

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

在 template 结构中使用自定义指令时,可以通过等号(=)的方式,为当前指令动态绑定参数值

在这里插入图片描述

3.3.3通过 binding 获取指令的参数值

在声明自定义指令时,可以通过形参中的第二个参数,来接收指令的参数值:

在这里插入图片描述

3.3.4 update 函数

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

在这里插入图片描述

3.3.5 全局自定义指令

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

全局指令放在App.vue中

在这里插入图片描述

4 自定义事件

4.1 什么是自定义事件

在封装组件时,为了让组件的使用者可以监听到组件内状态的变化,此时需要用到组件的自定义事件

在这里插入图片描述

4.2 自定义事件的 3 个使用步骤

在封装组件时:
声明自定义事件
触发自定义事件

在使用组件时:
监听自定义事件

4.2.1 声明自定义事件

开发者为自定义组件封装的自定义事件,必须事先在 emits 节点中声明,示例代码如下:

在这里插入图片描述

4.2.2 触发自定义事件

在 emits 节点下声明的自定义事件,可以通过 this.$emit(‘自定义事件的名称’) 方法进行触发,示例代码如下

在这里插入图片描述

4.2.3 监听自定义事件

在使用自定义的组件时,可以通过 v-on 的形式监听自定义事件。示例代码如下:

在这里插入图片描述

4.3 自定义事件传参

在调用 this.$emit() 方法触发自定义事件时,可以通过第 2 个参数为自定义事件传参,示例代码如下:

在这里插入图片描述

  • 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、付费专栏及课程。

余额充值