往期内容
《Vue零基础入门教程》第十四课:列表渲染
《Vue零基础入门教程》第十五课:样式绑定
《Vue零基础入门教程》第十六课:计算属性
《Vue零基础入门教程》第十七课:侦听器
《Vue零基础入门教程》第十八课:计算属性 VS 侦听器
《Vue零基础入门教程》第十九课:组件式开发简介
《Vue零基础入门教程》第二十课:父子组件间通信(重点掌握)
《Vue零基础入门教程》第二十一课:深入组件
《Vue零基础入门教程》第二十二课:具名插槽
编译作用域
在 Vue 编译的过程中, 如果父子组件中定义的相同的状态
, 会不会冲突呢?
如果不会冲突, 具体访问的是哪个状态
呢
示例
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Document</title><script src="../node_modules/vue/dist/vue.global.js"></script></head><body><!-- 父组件模板 --><div id="app"><son v-show="isShow"></son></div><!-- 子组件的模板 --><template id="tmp"><div><h3>我是子组件</h3><button v-show="isShow">子组件按钮</button></div></template><script>const { createApp } = Vueconst vm = createApp({data() {return {isShow: false,}},components: {son: {template: '#tmp',data() {return {isShow: true,}},},},}).mount('#app')</script></body>
</html>
父组件和子组件中都存在isShow
.
- 如果在父模板中使用 isShow, 访问的是父组件
data
中的值 - 如果在子模板中使用 isShow, 访问的是子组件
data
中的值
通过上述示例, 我们可以发现, 在父组件中是不能直接访问子组件中的状态的.
为什么需要作用域插槽
为了解决上述问题, 引入了作用域插槽的概念, 其核心是在父模板中访问子组件的数据
示例
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Document</title><script src="../node_modules/vue/dist/vue.global.js"></script></head><body><!-- 父组件模板 --><div id="app"><son><!-- 通过v-slot指令定义默认插槽的名字, 可以随便起. 表示一个slot对象 {test: 'hello', row: {name: 'xiaoming'}}--><template v-slot:default="slotProps">{{slotProps.test}} -- {{slotProps.row.name}}</template><!-- cpuSlot: {type: 'I7 12700K'} --><!-- v-slot的简写: # --><template #cpu="cpuSlot"><div>{{cpuSlot.type}}</div></template></son></div><!-- 子组件模板 --><template id="temp"><h3>子组件</h3><!-- 1. 在slot上绑定一个自定义属性 --><slot :test="msg" :row="user"></slot><slot name="cpu" :type="cpu"></slot></template><script>const { createApp } = VuecreateApp({components: {son: {template: '#temp',data() {return {msg: 'hello',user: {name: 'xiaoming',},cpu: 'I7 12700K',}},},},}).mount('#app')</script></body>
</html>
其中, v-slot
指令可以使用#
简写
<template #cpu="cpuSlot"><div>{{cpuSlot.type}}</div>
</template>
5) 动态组件
场景
根据type
类型不同, 渲染不同的组件
- 当type为
image
时, 渲染图片组件 - 当type当
video
时, 渲染视频组件
传统的做法
使用v-if
判断
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Document</title><script src="../node_modules/vue/dist/vue.global.js"></script></head><body><div id="app"><!-- <div v-if="type == 'image'"><my-image></my-image></div><div v-else-if="type == 'video'"><my-video></my-video></div> --><!-- 动态组件: 根据不同的状态, 渲染不同的组件 --><!-- 使用v-if指令实现 --><my-image v-if="type=='image'"></my-image><my-video v-else-if="type=='video'"></my-video></div><script>const { createApp } = Vueconst vm = createApp({data() {return {type: 'image',name: 'MyImage',}},components: {MyImage: {template: `<img src=""/>`,},MyVideo: {template: `<video></video>`,},},}).mount('#app')</script></body>
</html>
动态组件
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Document</title><script src="../node_modules/vue/dist/vue.global.js"></script></head><body><div id="app"><!-- 动态组件: 根据不同的状态, 渲染不同的组件 --><!-- 使用component内置组件is绑定组件名--><component :is="name"></component></div><script>const { createApp } = Vueconst vm = createApp({data() {return {type: 'image',name: 'MyImage',}},components: {MyImage: {template: `<img src=""/>`,},MyVideo: {template: `<video></video>`,},},}).mount('#app')</script></body>
</html>
动态组件
渲染的组件是动态生成, 根据不同的状态渲染不同的组件