Vue插槽、编译作用域及编译作用域插槽

slot插槽

匿名插槽

模板中使用插槽则增加标签,标签内部的html代码则是默认值

<template id="templates">
    <div>
        <h1>按钮</h1>
        <slot><p>默认插槽</p></slot>
        <button v-for="(item,index) in categories" @click="buttonClick(item)">
            {
    
    {
    
    index}}:{
    
    {
    
    item.name}}
        </button>
    </div>
</template>

具名插槽对插槽进行命名

对插槽命名会替换指定位置的插槽
插槽增加 slot="slot1"标记可以替换指定的插槽
模板中对插槽命名

默认插槽1

编译作用域

如下代码在标签中v-show所对应的data isShow,isShow会直接从app2所对应Vue对象的data中查找不会去子组件的vue对象中查找
官方解释:父组件模板所有的东西会在父级作用域内进行编译,子组件模板的所有东西会在子级作用域中进行编译

 <div id="app2">
        <cpn v-show="isShow"></cpn>
 </div>

作用域插槽

说明: 父组件替换子组件的插槽但内容由子组件提供
在父组件中的插槽绑定data使用子组件的哪一个数据
在这里插入图片描述
然后在子组件插槽内使用slot标签指定替换哪个插槽,slot-scope="slot"意思为当前插槽为作用域插槽
v-for使用时使用插槽的data就可以了 slot.data
在这里插入图片描述

例子

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="/js/vue.js"></script>
</head>
<body>
    <div id="app2">
        <cpn ref="refs" @itemclick=emit><p>插槽1</p></cpn>
        <cpn ref="refs" @itemclick=emit><p>插槽2</p></cpn>
        <cpn ref="refs" @itemclick=emit><p>插槽3</p><p>插槽4</p></cpn>
        <cpn ref="refs" @itemclick=emit></cpn>
        <span>----------------------------------------------------------------------------------------</span>
        <cpn ref="refs" @itemclick=emit>
            <span slot="slot1">修改默认插槽1</span><br>
            <span slot="slot2">修改默认插槽2</span><br>
            <span slot="slot3">修改默认插槽3</span><br>
        </cpn>
        <span>----------------------------------------------------------------------------------------</span>
        <h1>作用域插槽</h1>
        <cpn ref="refs" @itemclick=emit>
            <div  slot="slot1" slot-scope="slot">
                <button  v-for="(item,index) in slot.data" @click="buttonClick(item)">
                    {
    
    {
    
    item.id}}:{
    
    {
    
    item.name}}
                </button>
            </div>
        </cpn>
    </div>
</body>
<template id="templates">
    <div>
        <h1>按钮</h1>
        <slot name="slot1" :data="categories"><p>默认插槽1</p></slot>
        <slot name="slot2"><p>默认插槽2</p></slot>
        <slot name="slot3"><p>默认插槽3</p></slot>
        <button v-for="(item,index) in categories" @click="buttonClick(item)">
            {
    
    {
    
    index}}:{
    
    {
    
    item.name}}
        </button>
    </div>
</template>


<script>
    //1.子组件
    const cpn = {
    
    
        template:'#templates',
        data(){
    
    
            return {
    
    
                categories:[
                    {
    
    id:'1',name:'炸弹'},
                    {
    
    id:'2',name:'炸弹1'},
                    {
    
    id:'3',name:'炸弹2'},
                    {
    
    id:'4',name:'炸弹3'},
                    {
    
    id:'5',name:'炸弹4'},
                    {
    
    id:'6',name:'炸弹5'},
                ]
            };
        },
        methods: {
    
    
            buttonClick(item){
    
    
                //监听事件并发射出去给上一级
                this.$emit('itemclick',item);
                //打印父组件信息
               console.log(this.$parent.message);
               //直接找到根节点获取数据
               console.log(this.$root.message);
            }
        }
    }
    var app2 = new Vue({
    
    
        el:"#app2",
        data:{
    
    
            message:"消息"
        },
        components: {
    
    
            cpn
        },
        methods:{
    
    
            emit(item){
    
    
                //发射出来的事件监听
                console.log(item);
                //调用子组件中的值显示
                console.log( this.$children[0].categories);
                //这种写法需要给子组件增加ref标签
                console.log(this.$refs.refs.categories);
            }
        }
    })
</script>
</html>

github 例子地址

https://github.com/1142235090/study_vue

猜你喜欢

转载自blog.csdn.net/zhaohan___/article/details/109776936