Vue入门基础—— 动态组件&插槽&自定义指令
Posted 小hu同学
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vue入门基础—— 动态组件&插槽&自定义指令相关的知识,希望对你有一定的参考价值。
本篇文章主要讲述的是 动态组件&插槽&自定义指令
一、动态组件
1、什么是动态组件
动态组件指的是
动态切换组件的显示与隐藏
2、如何实现动态组件渲染
Vue提供了一个内置的组件,专门用来实现动态组件的渲染。示例代码如下
data()
//1、当前要渲染的组件名称
retrn comName:'Left'
<!--2. 通过is属性,动态指定要渲染的组件 -->
<component :is='comName'></component>
<!-- 3. 点击按钮,动态切换组件的名称-->
<button @click="Toleft">切换为Left</button>
<button @click="Toright">切换为Right</button>
在App组件的中 导入两个组件(这个导入步骤省略)
//可使用component is 来渲染组件
<component :is="Left"></component>
总结:《component》 是一个占位符 ,要渲染谁就在is 后面添加对应的组件
2.1 动态组件-动态切换
我们刚刚这个component里面的is 后面是写死的,这个时候我们要让后面的值改为动态的
代码示例如下:
//动态绑定一个comname值
<!-- 1、component标签是vue内置的 作用 组件的占位符 -->
<!-- 2、is 属性的值 表示要渲染的组件的名字 -->
<component :is="comname"></component>
export default
data()
return
// 表示默认展示的名字
comname:'Left'
,
需求:当我们点击按钮上面的切换时,点击对应按钮就展示对应的组件
<button @click="Toleft">切换为Left</button>
<button @click="Toright">切换为Right</button>
<component :is="comname"></component>
export default
data()
return
// 表示默认展示的名字
comname:'Left'
,
methods:
Toleft()
this.comname ='Left'
,
Toright()
this.comname ='Right'
,
// 注册组件
components:
// 如果在声明组件名称的时候 没有为组件声明name 名称 默认就是注册的名称
Left,
Right,
2.2 动态组件-keep-alive的使用
可以看下面这个案例,我在left 组件里面定义了一个自增加1,当我们加1后,切换到另外一个组件在切换回来,会发现我们的自增的数据没了这是为什么呢?
原因就是:当我们切换组件的时候,组件被销毁了,当我们切换回来的时候 ,组件又创建了
如果还不清楚 可以看下面这个。注意看右边的组件
我们在Left 组件中
创建一个 creatd生命周期函数,还记得created是什么意思么? 是组件完成数据的请求的阶段
created()
console.log('left组件创建了')
,
然后再创建一个destroyed生命周期函数?组件销毁时触发阶段
destroyed()
console.log('left组件销毁了');
,
看下图
当页面一进来的时候,会触发一次 created,切换到组件right的时候 会触发destroyed,当我们再次切换会left组件,可以看到我们组件 再次创建了
这个时候,我们就需要用到keep-alive了,官网的说法是,将失活的组件 [包裹起来](动态组件 & 异步组件 — Vue.js (vuejs.org))
用法:给我们在App.vue组件里面定义的component占位符外面包裹起来就可以了
<!--keep-alive可以吧内部的组件 进行缓存 而不是销毁组件 -->
<keep-alive>
<component :is='comname'></component>
</keep-alive>
可以看到,我们的数据并没有销毁,而是保存下来了,注意看右边调试器,当我们切换组件的时候,left组件并没有被销毁,而是被缓存了
2.2.1 keep-alive对应的生命周期函数
- 当组件被缓存时,会自动触发组件的deactivated生命周期函数
deactivated()
console.log('组件被缓存了');
,
- 当组件被激活的时候,会自动触发组件的activated生命
activated()
console.log('组件被激活了');
,
2.2.2 keep-alive的include属性
include 指定哪些组件需要缓存的
exinclude 指定哪些组件不需要缓存的
最好不要同时使用这两个属性
<keep-alive include="MyLeft">
<component :is='comname'></component>
</keep-alive>
2.3 扩展-组件name名称
在声明组件的时候,没有为组件单独设置name名称时,这组件的名称就为注册时的名称,要是声明了name组件名称的名称,则组件的名称就为name名称
export default
name:'MyLeft'
二、插槽
1、什么是插槽
插槽(Slot)
是 vue 为组件的封装者
提供的能力。允许开发者在封装组件时,把不确定的、希望由用户指定的部分
定义为插槽。
可以把插槽认为是组件封装期间,为用户预留的内容的占位符。
代码示例:
在app.vue中导入left组件
//在当前组件定义内容后,在页面上也是不会展示的,
因为需要到封装的组件中,预留一个插槽,来进行自定义内容的填充
<left>
<p> 这是默认插槽</p>
</left>
<!--默认情况下 在使用组件的时候
提供的内容会默认的被填充到名字为default的插槽中 -->
left.vue 组件
<!-- 声明一个插槽区 -->
<slot></slot>
<!-- Vue 官方规定 每一个slot 都要有一个name 名称 -->
<!-- 如果省略了 slot 的name 属性 则会有一个默认名称 -->
<!--<slot name="default">默认插槽名称</slot>-->
2、v-slot 指令
v-slot 指名道姓的将某部分内容放到哪个插槽里面去
v-slot指令不能放在元素上,只能放在template
和组件
上
<left>
<p v-slot:default> 这是默认插槽</p>//错误写法,会报错
</left>
<left>
// 将p 元素放到 插槽name为default的里面
//<tempalte>标签 不会被渲染到页面结构里面
<tempalte v-slot:default>
<p> 这是默认插槽</p>
</template>
</left>
总结
- 如果要吧内容填充到指定名称的插槽中 需要使用 v-slot:这个指令
- v-slot 这个指令后面要跟上插槽的名称
- v-slot:指令不能直接用在元素身上 必须用在template标签上
- template 这个标签 它是一个虚拟的标签 只起到包裹性质的作用 但是不会被渲染为任何实质性的html 元素
- v-slot 的简写是
#
- 当在
<slot></slot>
插槽中填写了内容,又在组件中定义内容,会以自定义内容为准
left.vue
//里面的内容为默认内容,当自定义内容为空时,会展示默认内容
<slot name="default">默认插槽</slot>
app.vue
<left>
//自定义内容,当自定义内容里面有数据时,会把默认内容给覆盖掉
<template #default>
<p>这是我后来自定义内容</p>
</template>
</left>
3、具名插槽
插槽拥有自己的名称,就是具名插槽
结合Vant 组件库看看
代码示例
right.vue组件
<!-- 渲染文章的标题 -->
<div class="header-box">
<slot name="title" ></slot>
</div>
<!-- 渲染文章的内容 -->
<div class="content-box">
<!-- 在封装组件时 为预留的slot 提供属性对应的值 这种用法 叫做“作用域插槽” -->
<!--ms 这里定义了一个值后,可以在组件调用时 使用-->
<slot name="content" ms="hello vue" :user="user"></slot>
</div>
<!-- 渲染文章的作者 -->
<div class="footer-box">
<slot name="footer"></slot>
</div>
//data里面定义1个 user对象 绑定到插槽上面,也作为数据传递过去
<script>
export default
data()
return
user:
name:'张三',
age:14
,
name:'Art'
</script>
app.vue 根组件
<right>
<template #title>
<h3>锄禾</h3>
</template>
<!-- 可以在这个插槽里面接收传递过来的数据,并且使用-->
<!-- <template #content="ms">-->
当有多个值需要接收时,可以写成
<!--<template #content="ms,user">-->
<template #content>
<div>锄禾日当午,汗滴禾下土</div>
<div>谁知盘中餐,粒粒皆辛苦</div>
<div> ms </div>
<div> user.name </div>
</template>
<template #footer>
<div>白居易</div>
</template>
</right>
三、自定义指令
1、什么是自定义指令
vue官方提供了v-text、v-for、v-model、v-if等常用的指令。除此之外vue还允许开发者自定义指令
2、自定义指令的分类
vue中的自定义指令分为两类,分别是:
私有
自定义指令全局
自定义指令
3、私有自定义指令
在每个vue 组件中,可以在directives
节点下声明私有自定义指令。示例代码如下:
app.vue的业务逻辑
directives:
// 定义为color 的指令 指向一个配置对象
color:
// 当指令第一次被绑定到元素上的时候 会立即触发bind 函数
// 形参中的el 表示当前指令所绑定的那个Dom 元素
bind(el)
el.style.color = 'red'
,
app.vue根页面结构
<h4 v-color="'red'">测试</h4>
非写死
<h1 v-color="color">App 根组件</h1>
export default
data()
return
color: 'blue'
,
directives:
// 定义为color 的指令 指向一个配置对象
color:
// 当指令第一次被绑定到元素上的时候 会立即触发bind 函数
// 形参中的el 表示当前指令所绑定的那个Dom 元素
//传递一个形参binding
bind(el,binding)
//私有binding.value 来获取到color的值
el.style.color = binding.value
,
- value 是真正的值
- expression 外面有一层单引号(是一个表达式的意思)
3.1 update函数
<button @click="color = 'red'">改变App的颜色</button>
//当指令第一次被绑定到元素上的时候 会立即触发bind 函数。
但我们点击时,数据修改了,页面的内容没有修改
<script>
export default
data()
return
color: 'blue'
,
directives:
// 定义为color 的指令 指向一个配置对象
color:
// 当指令第一次被绑定到元素上的时候 会立即触发bind 函数
// 形参中的el 表示当前指令所绑定的那个Dom 元素
//传递一个形参binding
bind(el,binding)
//私有binding.value 来获取到color的值
el.style.color = binding.value
,
</script>
原因:bind 函数只调用 1 次:当指令第一次绑定到元素时调用,当 DOM 更新时 bind 函数不会被触发。 update 函数会在每次 DOM 更新时被调用。示例代码如下:
3.2 代码优化函数简写
如果 insert 和update 函数中的逻辑完全相同,则对象格式的自定义指令可以简写成函数格式:
就是bind函数和update函数里面的业务逻辑是一样的就可以简写成以下的方式
// 私有自定义指令的节点
directives:
color(el, binding)
el.style.color = binding.value
4、全局自定义指令
全局共享的自定义指令需要通过“
Vue.directive(
)”进行声明,示例代码如下:
main.js
//参数1:字符串,表示全局自定义指令的名字
//参数2:对象用来接收指令的参数值
Vue.directive('color',function(el,obj)
el.style.color = obj.value
)
以上是关于Vue入门基础—— 动态组件&插槽&自定义指令的主要内容,如果未能解决你的问题,请参考以下文章
15《Vue 入门教程》Vue 动态组件 &amp; keep-alive