天天看點

【Vue 開發實戰】基礎篇 # 4:Vue元件的核心概念:插槽

說明

【Vue 開發實戰】學習筆記。

插槽

Vue 實作了一套内容分發的 API,這套 API 的設計靈感源自 Web Components​ 規範草案,将 ​

​<slot>​

​ 元素作為承載分發内容的出口。

【Vue 開發實戰】基礎篇 # 4: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>Vue元件的核心概念:插槽</title>
</head>
<body>
    <div id="app">
        {{message}}

        <todo-list>
            <todo-item v-for="item in list" :title="item.title" :del="item.del" @delete="handleDelete"></todo-item>
        </todo-list>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>// 定義一個名為 todo-item 的元件;名字需要唯一
        Vue.component("todo-item", {
            props: {
                title: String,
                del: {
                    type: Boolean,
                    default: false
                }
            },
            template: `
                <li>
                    <span v-if="!del">{{title}}</span>
                    <span v-else style="text-decoration: line-through;">{{title}}</span>
                    <button v-show="del" @click="handleClick">删除</button>
                </li>
            `,
            // data 需要為函數傳回一個對象,保證唯一性
            data: function() {
                return {}
            },
            methods: {
                handleClick() {
                    console.log('點選了删除按鈕');
                    // 發射時間出去
                    this.$emit("delete", this.title);
                }
            },
        });
        // 定義一個名為 todo-list 的元件
        Vue.component("todo-list", {
            template: `
                <ul><slot></slot></ul>
            `,
        });

        var vm = new Vue({
            el: "#app",
            data: {
                message: "kaimo 313",
                list: [
                    {
                        title: "課程1",
                        del: true
                    },{
                        title: "課程2",
                        del: false
                    },
                ]
            },
            methods: {
                handleDelete(val) {
                    console.log('handleDelete---->', val);
                }
            }
        })</script>
</body>
</html>      
【Vue 開發實戰】基礎篇 # 4: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>Vue元件的核心概念:插槽</title>
</head>
<body>
    <div id="app">
        {{message}}

        <todo-list>
            <todo-item v-for="item in list" :title="item.title" :del="item.del" @delete="handleDelete">
                <span slot="pre-icon">前置icon</span>
                <!-- 新文法 v-slot -->
                <template v-slot:suf-icon>後置icon</template>
            </todo-item>
        </todo-list>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>// 定義一個名為 todo-item 的元件;名字需要唯一
        Vue.component("todo-item", {
            props: {
                title: String,
                del: {
                    type: Boolean,
                    default: false
                }
            },
            template: `
                <li>
                    <slot name="pre-icon"></slot>
                    <span v-if="!del">{{title}}</span>
                    <span v-else style="text-decoration: line-through;">{{title}}</span>
                    <slot name="suf-icon">沒有使用,預設文字展示</slot>
                    <button v-show="del" @click="handleClick">删除</button>
                </li>
            `,
            // data 需要為函數傳回一個對象,保證唯一性
            data: function() {
                return {}
            },
            methods: {
                handleClick() {
                    console.log('點選了删除按鈕');
                    // 發射時間出去
                    this.$emit("delete", this.title);
                }
            },
        });
        // 定義一個名為 todo-list 的元件
        Vue.component("todo-list", {
            template: `
                <ul><slot></slot></ul>
            `,
        });

        var vm = new Vue({
            el: "#app",
            data: {
                message: "kaimo 313",
                list: [
                    {
                        title: "課程1",
                        del: true
                    },{
                        title: "課程2",
                        del: false
                    },
                ]
            },
            methods: {
                handleDelete(val) {
                    console.log('handleDelete---->', val);
                }
            }
        })</script>
</body>
</html>      
【Vue 開發實戰】基礎篇 # 4:Vue元件的核心概念:插槽

不使用後置 icon 插槽

【Vue 開發實戰】基礎篇 # 4:Vue元件的核心概念:插槽

就會展示預設的東西

【Vue 開發實戰】基礎篇 # 4: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>Vue元件的核心概念:插槽</title>
</head>
<body>
    <div id="app">
        {{message}}

        <todo-list>
            <todo-item v-for="item in list" :title="item.title" :del="item.del" @delete="handleDelete">
                <span slot="pre-icon">前置icon</span>
                <!-- 新文法 v-slot -->
                <template v-slot:suf-icon="{value}">後置icon:{{value}}</template>
            </todo-item>
        </todo-list>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>// 定義一個名為 todo-item 的元件;名字需要唯一
        Vue.component("todo-item", {
            props: {
                title: String,
                del: {
                    type: Boolean,
                    default: false
                }
            },
            template: `
                <li>
                    <slot name="pre-icon"></slot>
                    <span v-if="!del">{{title}}</span>
                    <span v-else style="text-decoration: line-through;">{{title}}</span>
                    <slot name="suf-icon" :value="value">沒有使用,預設文字展示</slot>
                    <button v-show="del" @click="handleClick">删除</button>
                </li>
            `,
            // data 需要為函數傳回一個對象,保證唯一性
            data: function() {
                return {
                    value: Math.random()
                }
            },
            methods: {
                handleClick() {
                    console.log('點選了删除按鈕');
                    // 發射時間出去
                    this.$emit("delete", this.title);
                }
            },
        });
        // 定義一個名為 todo-list 的元件
        Vue.component("todo-list", {
            template: `
                <ul><slot></slot></ul>
            `,
        });

        var vm = new Vue({
            el: "#app",
            data: {
                message: "kaimo 313",
                list: [
                    {
                        title: "課程1",
                        del: true
                    },{
                        title: "課程2",
                        del: false
                    },
                ]
            },
            methods: {
                handleDelete(val) {
                    console.log('handleDelete---->', val);
                }
            }
        })</script>
</body>
</html>