vue基础05-匿名插槽、具名插槽

755 阅读1分钟

插槽分类为3种:

  • 匿名插槽
  • 具名插槽
  • 作用域插槽

1.匿名插槽:

🌵slot负责挖个坑放那,后面往里面填啥是啥

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <!-- 3.使用子组件 -->
        <App></App>

    </div>
    <script src="./vue.js"></script>
    <script>
        
        Vue.component('MBtn',{
            template:`
                <button>
                    <slot></slot>
                </button>
            `
        })

        const App = {
            data() {
                return {
                    title: "老爹"
                }
            },
           
            template: `
                <div>
                    <m-btn><a href="#">登录</a></m-btn>
                    <m-btn>注册</m-btn>
                </div>
            `,
        }
        
        new Vue({
            el: '#app',
            data: {

            },
            components: {
                // 2.挂载子组件
                App
            }

        })
    </script>
</body>

</html>

2.具名插槽

  • 只要匹配到slot标签的nametemplate中的内容就会被插入到这个槽
    • 模板中用<slot name="p1"></slot>挖坑;
    • 通过给元素<template ></template>填坑;
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <!-- 3.使用子组件 -->
        <App></App>

    </div>
    <script src="./vue.js"></script>
    <script>
        // 只要匹配到slot标签的name值 template中的内容就会被插入到这个槽中
        Vue.component('MBtn', {
            template: `
                <button>
                     <slot name='submit'></slot>
                     <slot name='login'></slot>
                     <slot name='register'></slot>
                </button>
            `
        })

        const App = {
            data() {
                return {
                    title: "老爹"
                }
            },

            template: `
                <div>
                     <m-btn>
                            <span slot="login">
                                提交
                            </span>         
                     </m-btn>
                    
                    <m-btn>
                        <template slot='login'>
                            <a href="#">登录</a>
                        </template>
                    </m-btn>
                   
                    <m-btn>
                        <template slot='register'>
                            注册
                        </template>
                    </m-btn>

                    <m-btn>
                        <template slot='login'>
                            艾弗森
                        </template>
                    </m-btn>
                </div>
            `,
        }
        new Vue({
            el: '#app',
            data: {

            },
            components: {
                // 2.挂载子组件
                App
            }
        })
    </script>
</body>

</html>

3.作用域插槽

需求场景: 已经开发了一个待办事项列表的组件,很多模块都在,A,B组件都使用了todolist组件,现在想要在不影响B组件正常使用的情况下,让A组件支持勾选☑️的功能。

具体实现思路:

  • todolist组件中,添加<slot :itemValue="item"></slot>,这样就可以把渲染todolist的数据,传递到外面的插槽
  • 外面使用todolist组件的,通过给todolist组件添加v-slot="data"来接收上面slot传递出来的数据;
  • todolist组件内添加☑️框代码如👇: <todolist v-slot="data"> <input type="checkbox" v-model='data.itemValue.isComplate' /> </todolist>
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <!-- 3.使用子组件 -->
        <App></App>

    </div>
    <script src="./vue.js"></script>
    <script>
        // 已经开发了一个待办事项列表的组件,很多模块都在
        // A B
        // 1.之前数据格式和引用接口不变,正常显示
        // 2.新功能模块增加对勾
        const todoList = {
            data() {
                return {

                }
            },
            props: {
                todos: Array,
                defaultValue: []
            },
            template: `
        <ul>
            <li v-for='item in todos' :key='item.id'>
                <slot :itemValue = 'item'>
                   
                </slot>
                 {{item.title}}
               
            </li>
        </ul>
        `
        }
       
        const App = {
            data() {
                return {
                    todoList: [{
                            title: '大哥你好么',
                            isComplate: true,
                            id: 1
                        },
                        {
                            title: '小弟我还行',
                            isComplate: false,
                            id: 2
                        },
                        {
                            title: '你在干什么',
                            isComplate: false,
                            id: 3
                        },
                        {
                            title: '抽烟喝酒烫头',
                            isComplate: true,
                            id: 4
                        }
                    ]
                }
            },
            components: {
                todoList
            },
            template: `
            	  <todoList :todos='todoList'>
                    <template v-slot='data'>
                        <input type="checkbox" v-model='data.itemValue.isComplate' />
                    </template>
            	  </todoList>
        `,
        }
        new Vue({
            el: '#app',
            data: {

            },
            components: {
                App
            }

        })
    </script>
</body>

</html>