混合和插槽

一、混合

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>

 

posted @ 2023-09-20 23:04  我用python写Bug  阅读(17)  评论(0编辑  收藏  举报