Vue 中的組件

Todo list 功能開發


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>TodoList</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>

<body>
    <div id="root">
        <div>
            <input v-model="inputValue"/>
            <button @click="handleSubmit">提交</button>
        </div>
        <ul>
            <li v-for="(item, index) of list" :key="index">
                {{item}}
            </li>
        </ul>
    </div>

    <script>
        new Vue({
            el: "#root",
            data: {
                inputValue: "",
                list: []
            },
            methods: {
                handleSubmit: function() {
                    // .push 是向 list 添加數據
                    this.list.push(this.inputValue)
                    // 添加完後,輸入框清空
                    this.inputValue = ''
                }
            }
        })
    </script>
    
</body>
</html>

組件的拆分


組件是指頁面上的某一部分,我們可以將大型網頁拆分成幾個部分,每個部分就是一個小的組件。這樣的話,維護每個小的組件就是簡單的多。

如何定義組件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>TodoList</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>

<body>
    <div id="root">
        <div>
            <input v-model="inputValue"/>
            <button @click="handleSubmit">提交</button>
        </div>
        <ul>
            <!--​ 全局組件的使用 -->
            <todo-item 
                v-for="(item,index) of list" 
                :key="index" 
                :content="item"
             >
             </todo-item>
        </ul>
    </div>

    <script>
        // 全局組件
        Vue.component('todo-item', {
            props: ['content'],
            template: '<li>{{content}}</li>'
        })

        //// 局部組件
        //var TodoItem = {
        //    template: '<li>item</li>'            
        //}

        new Vue({
            el: "#root",
            // 註冊局部組件到 vue 實例
            //components: {
            //    'todo-item': TodoItem
            //},
            data: {
                inputValue: "",
                list: []
            },
            methods: {
                handleSubmit: function() {
                    // .push 是向 list 添加數據
                    this.list.push(this.inputValue)
                    // 添加完後,輸入框清空
                    this.inputValue = ''
                }
            }
        })
    </script>
    
</body>
</html>
  • Vue.component 創建一個組件,它是一個全局組件,在任何模板裏面都可以使用。
  • 局部組件通過 var 定義,然後通過 components 來註冊局部組件到相應的 vue 實例中。

props 屬性的意思是接收最外面傳遞進來的名爲 content 的屬性,然後在 template 中直接使用 content 屬性

組件與實例的關係


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>TodoList</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>

<body>
    <div id="root">
        <div>
            <input v-model="inputValue"/>
            <button @click="handleSubmit">提交</button>
        </div>
        <ul>
            <!--​ 全局組件的使用 -->
            <todo-item v-for="(item,index) of list" :key="index" :content="item"></todo-item>
        </ul>
    </div>

    <script>
        // 全局組件
        Vue.component('todo-item', {
            props: ['content'],
            template: '<li @click="handleClick">{{content}}</li>',
            methods: {
                handleClick: function() {
                    alert('clicked')
                }
            }
        })

        //// 局部組件
        //var TodoItem = {
        //    template: '<li>item</li>'            
        //}

        new Vue({
            el: "#root",
            // 註冊局部組件到 vue 實例
            //components: {
            //    'todo-item': TodoItem
            //},
            data: {
                inputValue: "",
                list: []
            },
            methods: {
                handleSubmit: function() {
                    // .push 是向 list 添加數據
                    this.list.push(this.inputValue)
                    // 添加完後,輸入框清空
                    this.inputValue = ''
                }
            }
        })
    </script>
    
</body>
</html>

每一個 vue 的組件又是一個 vue 的實例。任何的 vue 項目都是由千千萬萬個 vue 實例(組件)組成。

在 vue 中父組件向子組件是通過屬性(如:props)的方式來進行傳遞的。

實現刪除功能


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>TodoList</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>

<body>
    <div id="root">
        <div>
            <input v-model="inputValue"/>
            <button @click="handleSubmit">提交</button>
        </div>
        <ul>
            <!--​ 全局組件的使用 -->
            <todo-item 
                v-for="(item,index) of list" 
                :key="index" 
                :content="item" 
                :index="index"
                @delete="handleDelete"  // 訂閱 delete 操作
            >
            </todo-item>
        </ul>
    </div>

    <script>
        // 全局組件
        Vue.component('todo-item', {
            props: ['content'],
            template: '<li @click="handleClick">{{content}}</li>',
            methods: {
                handleClick: function() {
                    // 向外觸發,發佈 'delete' 操作,帶上 index 做爲參數
                    this.$emit('delete', this.index)
                }
            }
        })

        //// 局部組件
        //var TodoItem = {
        //    template: '<li>item</li>'            
        //}

        new Vue({
            el: "#root",
            // 註冊局部組件到 vue 實例
            //components: {
            //    'todo-item': TodoItem
            //},
            data: {
                inputValue: "",
                list: []
            },
            methods: {
                handleSubmit: function() {
                    // .push 是向 list 添加數據
                    this.list.push(this.inputValue)
                    // 添加完後,輸入框清空
                    this.inputValue = ''
                },
                handleDelete: function(index) {
                    this.list.splice(index, 1)
                }
            }
        })
    </script>
    
</body>
</html>

當點擊子組件元素時,通知父組件刪除數據,怎麼通知?
可以通過子組件向父組件傳遞值的形式(發佈訂閱模式),可以做到刪除 todo-item

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章