主页

动态组件

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

vue 提供了一个内置的 <component> 组件,专门用来实现动态组件的渲染:

<-- 2. 通过 is 属性,动态指定要渲染的组件 -->
<component :is="comName = 'Left'"></component>

<-- 3. 点击按钮,动态切换组件的名称 -->
<button @click="comName = 'Left'">展示 Left 组件</button>
<button @click="comName = 'Right'">展示 Right 组件</button>

data() {
    // 1. 当前要渲染的组件名称
    return {
        comName: 'Left'
    }
}

使用 keep-alive 保持状态

默认情况下,切换动态组件时无法保持组件的状态;此时可以使用 vue 内置的 <keep-alive> 组件保持动态组件的状态:

<!-- keep-alive 可以把内部的组件进行缓存,而不是销毁组件 -->
<keep-alive>
    <component :is="comName"></component>
</keep-alive>

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

当组件被缓存时,会自动触发组件的 deactivated 生命周期函数
当组件被激活时,会自动触发组件的 activated 生命周期函数

export default {
    created() {
        console.log('组件被创建了')
    },
    destroyed() {
        console.log('组件被销毁了')
    },

    // 当组件第一次被创建的时候,即会执行 created 生命周期,也会执行 activated 生命周期
    activated() {
        console.log('Left 组件被激活了')
    },
    deactivated() {
        console.log('Left 组件被缓存了')
    },
}

keep-alive 的 include 属性

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

<keep-alive include="Left,Right">
    <component :is="comName"></component>
</keep-alive>
exclude 属性,指定的组件不被缓存
includeexclude 不能同时使用
// Right 组件
export default {
    // 当提供 name 属性之后,组件的名称,就是 name 属性的值
    // 组件的 “注册名称” 的主要应用场景是:以标签的形式,把注册好的组件,渲染和使用到页面结构之中
    // 组件生命时候的 “name” 名称的主要应用场景:结合 <keep-alive> 标签实现组件缓存功能;以及在调试工具中看到组件的 name 名称
    name: 'MyRight',
}

插槽

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

插槽基础语法

在封装组件时,可以通过 <slot> 元素定义插槽,从而为用户预留内置占位符:

// 封装组件 MyCom1
<template>
    <p>这是 MyCom1 组件的第 1 个 p 标签</p>
    <!-- 通过 slot 标签,为用户预留内容占位符(插槽),每一个插槽都要有一个 name 名称 -->
    <slot name="default"></slot>
    <p>这是 MyCom1 组件的第 2 个 p 标签</p>
</template>

// 使用组件 MyCom1
<MyCom1>
    <!-- 在使用 MyCom1 组件时,为插槽指定具体的内容 -->
    <template v-slot:default>
        <p>~~~用户自定义的内容~~~</p>
    </template>
</MyCom1>

具名插槽

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

// 组件 Article
<dic class="article-container">
    <header>
        <!-- 把文章标题放到这里 -->
        <slot name="title">标题</slot>
    </header>
    <main>
        <!-- 把文章内容放到这里 -->
        <slot name="article">内容</slot>
    </main>
    <footer>
        <!-- 把文章作者放到这里 -->
        <slot name="author">作者</slot>
    </footer>
</div>

// 使用组件 Article
<Article>
    <template #title>
        <h2>文章标题</h2>
    </template>
    <template #article>
        <P>文章内容<p>
    </template>
    <template #author>
        <P>文章作者<p>
    </template>
</Article>
没有指定 name 名称的插槽,会有隐含的默认名称叫做 “default”

作用域插槽

在封装组件的过程中,可以为预留的 <slot> 插槽绑定一个 props 数据,这种带有 props 数据的 <slot> 叫做 “作用域插槽” :

// 组件 A
<tbody>
    <!-- 下面的 slot 是一个作用域插槽 -->
    <!-- 为预留的 slot 提供属性对应的值 -->
    <slot name="a" msg="hello vue.js" :user="userinfo"></slot>
</tbody>

// 使用组件 A
<A>
    // 把数据用等号 然后 使用 {} 解构出来
    // scope
    <template #a="{msg, user}">
        <!-- <p>{{ scope }}<p>  输出是对象 { msg: 'hello vue.js', {name: '张三', age: 18} } -->
        <p>{{ msg }}<p> <!-- hello vue.js -->
        <p>{{ user.name }}<p> <!-- 张三 -->
    </template>
</A>

自定义指令

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

自定义指令的分类

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

私有自定义指令

在每个 vue 组件中,可以在 directives 节点下生命私有自定义指令:

<!-- 声明自定义指令时,指令的名字是 color -->
<!-- 使用自定义指令时,需要加上 v- 指令前缀 -->
<h1 v-color>App 组件</h1>

// 私有自定义指令的节点
directives: {
    color: {
        // 为绑定的 HTML 元素设置红色字体
        bind(el) {
            // 形参中的 el 是绑定了此指令的原生 DOM 对象
            el.style.color = 'red'
        }
    }
}

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

在 template 结构中使用自定义指令时,可以通过 = 号赋值的方式,为当前指令动态绑定参数值
在声明自定义指令时,可以通过形参的第二个参数 binding 获取指令的参数值

<!-- 在使用指令时,动态为当前指令绑定参数值 color -->
<h1 v-color="color">App 组件</h1>

data() {
    return {
        // 定义 color 颜色
        color: 'red'
    }
},
directives: {
    color: {
        bind(el, binding) {
            // 通过 binding 对象的 .value 属性,获取动态的参数值
            el.style.color = binding.value
        }
    }
}

update 函数

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

directives: {
    color: {
        // 当指令第一次被绑定到元素时被调用
        bind(el,binding) {
            el.style.color = binding.value
        },
        // 每次 DOM 更新时被调用
        bind(el,binding) {
            el.style.color = binding.value
        }
    }
}

函数简写

如果 bindupdate 函数中的逻辑完全相同,则对象格式的自定义指令可以简写成函数格式:

directives: {
    // 在 bind 和 update 时,会触发相同的业务逻辑
    color(el,binding) {
        el.style.color = binding.value
    }
}

全局自定义指令

全局共享的自定义指令需要通过 Vue.directive() 进行声明,写到 main.js 里面:

// 参数1:字符串,表示全局自定义指令的名字
// 参数2:对象,用来接收指令的数值
Vue.directive('color', {
    bind(el, binding) {
        el.style.color = binding.value
    },
    update(el, binding) {
        el.style.color = binding.value
    }
})
// 简写
Vue.directive('color', function(el, binding) {
    el.style.color = binding.value
})

Vue.directive('color', (el, binding) => {
    el.style.color = binding.value
})

总结

keep-alive 元素基本使用

  • <keep-alive> 标签、 include 属性

插槽基本使用

  • <slot> 标签、具名插槽、作用域插槽、后备内容(插槽的默认内容)

自定义指令

  • 私有自定义指令 directive: {}
  • 全局自定义指令 Vue.directive()

Vue2

版权属于:Joe
作品采用:本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。
0

目录

来自 《Vue2-动态组件&插槽&自定义指令》
评论

qiaofugui

博主很懒,啥都没有
188 文章数
14 评论量
3 分类数
191 页面数
已在风雨中度过 2年138天2小时44分