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

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