vue2和vue3混合和插槽的使用区别
一、混合
1. 当两个组件复用共用的代码块时
2. 定义公共的代码块
3. 复用语法:mixins: [变量名]
4. demo
<body> <div id="app"> <com1></com1> <com2></com2> </div> <script> // 定义公用代码 let base = { data() { return { is_show: false } }, methods: { show_text: function(){ this.is_show = true; }, hide_text(){ this.is_show = false; } } }; let com1 = { template: `<div> <button @click="show_text">点击显示文本</button> <button @click="hide_text">点击隐藏文本</button> <div v-show="is_show">威猛的明哥出现了</div> </div>`, // 继承公用代码 mixins: [base], // 还可以修改继承过来的代码 data(){ return { is_show: true } } }; let com2 = { template: `<div> <button v-on="{mouseenter: show_text, mouseleave: hide_text}">鼠标移入显示文本,移出隐藏</button> <div v-show="is_show">威猛的明哥出现了</div> </div>`, // 继承代码 mixins: [base] }; const app = new Vue({ el: "#app", components: { com1: com1, com2: com2, } }) </script> </body>
二、插槽
1、vue2插槽
默认插槽(不命名的插槽)
1. 定义组件template代码时,slot不需要设置name属性
2. 使用组件的时候,嵌入的内容直接用slot标签包含或者不用都行
3. demo
<body> <div id="app"> <com> <h3>Python</h3> <p>Golang</p> </com> <com> <slot>Mysql</slot> </com> </div> <!--组件的template还可以单独写出来--> <template id="my_com"> <div> <h1>这是一个子组件</h1> <!--用slot定义插槽--> <slot></slot> <hr> </div> </template> <script> let com = { // 找到template模板 template: "#my_com" }; const app = new Vue({ el: "#app", components: { com: com } }) </script> </body>
具名插槽(命名的插槽)
1. 定义组件template代码时,slot使用name属性区分不同的插槽信息
2. 使用组件的时候,嵌入的内容标签中通过slot="name",可以给组件添加上不同的内容
3. demo
<body> <div id="app"> <com> <h3 slot="title">Python</h3> <p slot="brief">从入门到精通</p> </com> <com> <h3 slot="title">Mysql</h3> <p slot="brief">从删库到跑路</p> </com> </div> <!--组件的template还可以单独写出来--> <template id="my_com"> <div> <h1>这是一个子组件</h1> <!--用slot定义插槽--> <slot name="title"></slot> <slot name="brief"></slot> <hr> </div> </template> <script> let com = { // 找到template模板 template: "#my_com" }; const app = new Vue({ el: "#app", components: { com: com } }) </script> </body>
2、vue3插槽
Vue3中的插槽分为三种类型:默认插槽、具名插槽和作用域插槽。
默认插槽(不命名的插槽)
默认插槽是指在组件中没有特定命名的插槽,定义跟用法与vue2基本是一致。
<body> <div id="app"> <com> <h3>Python</h3> <p>Golang</p> </com> <com> <slot>Mysql</slot> </com> </div> <template id="my_com"> <div> <h1>这是一个子组件</h1> <slot></slot> <hr> </div> </template> <script> let com = { // 找到template模板 template: "#my_com" }; // vue3是用createApp创建vue实例 Vue.createApp({ components: { com: com } }).mount("#app") </script> </body>
具名插槽(命名的插槽)
默认插槽是指在组件中slot使用name属性区分不同的插槽信息,定义vue2基本是一致,但是用法稍有不用,vue3中具名插槽使用时,需要用 template 标签。
实际上默认插槽也会被隐式的命名为 default。
vue3中具名插槽的v-slot也可以简化为 # 符号,demo如下:
<body> <div id="app"> <com> <!-- vue3具名插槽需要使用template,并使用v-slot标识对应哪个插槽 --> <template v-slot:title> <h2>Python</h2> </template> <p>这段没使用template对应的是默认插槽</p> <!-- v-slot可以简写成 # --> <template #brief> <h3>从入门到放弃</h3> </template> </com> </div> <template id="my_com"> <div> <h1>这是一个子组件</h1> <slot name="title">默认标题</slot> <slot>默认插槽</slot> <slot name="brief">默认信息</slot> <hr> </div> </template> <script> let com = { // 找到template模板 template: "#my_com" }; // vue3是用createApp创建vue实例 Vue.createApp({ components: { com: com } }).mount("#app") </script> </body>
作用域插槽
在使用插槽时,我们可以发现,插槽的内容可以访问到父组件的数据作用域,但是无法访问到子组件的数据。如果我们有需求就是需要在插槽内容中获取子组件数据怎么办呢?
那么可以使用Vue3中的作用域插槽。
使用方式:
1、在子组件中 slot
标签上添加了一些自定义属性,属性值就是我们想要传递给父组件的一些内容。
2、在父组件中通过 v-slot="scope"
等形式接收子组件传过来的数据,scope
的名字是可以任意取的,它是一个对象,或者使用析构接受也行。
<body> <div id="app"> <com> <!-- 具名插槽的作用域传值,scope是子组件传过来的所有标签对的值,是对象 --> <template v-slot:title="scope"> <h2>{{ scope.headline }}</h2> <p>{{ scope.text }}</p> </template> <!-- 默认插槽如果需要使用作用域传值,也要用template --> <template v-slot:default="scope"> <!-- 直接 v-slot="scope" 也行 --> <h2>{{ scope.dtext }}</h2> </template> <!-- v-slot可以简写成 # ,还可以直接析构拿值--> <template #brief="{ info, remarks }"> <h3>{{ info }}</h3> <h3>{{ remarks }}</h3> </template> </com> </div> <template id="my_com"> <div> <h1>这是一个子组件</h1> <slot name="title" headline="子给父的标题" text="子给父的标题文本">默认标题</slot> <slot dtext="默认插槽也可以传给父">默认插槽</slot> <slot name="brief" info="子给父的信息" remarks="子给父的备注信息">默认信息</slot> <hr> </div> </template> <script> let com = { // 找到template模板 template: "#my_com" } // vue3是用createApp创建vue实例 Vue.createApp({ components: { com: com } }).mount("#app") </script> </body>