从零开始学Vue.js(四)组件间通信初探

2019-11-14  本文已影响0人  Geekholt

如需转载请评论或简信,并注明出处,未经允许不得转载

前言

上一节中我们将ToDoList小工具拆分成了父组件和子组件,我们可以通过v-bind向子组件中传递数据。那么我们的子组件要如何向父组件传递数据呢?这节中我们通过一个小需求来简单认识Vue中的组件间通信

目录

了解需求

这是上节中我们最终的代码,包含了父组件app和子组件TodoItem

<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="vue.js"></script>
</head>
<body>
<div id="app">
    <input type="text" v-model="inputValue">
    <button v-on:click="onSubmitClick">提交</button>
    <todo-item v-bind:content="item"
               v-for="item in list">
    </todo-item>
</div>

<script>
    var TodoItem = {
        props: ['content'],
        template: '<li>{{content}}</li>>'
    }
    var app = new Vue({
        el: '#app',
        components: {
          TodoItem: TodoItem
        },
        data: {
            list: [],
            inputValue: ''
        },
        methods: {
            onSubmitClick: function () {
                this.list.push(this.inputValue)
                this.inputValue = ""
            }
        }
    })

</script>
</body>
</html>

运行后,我们提交一个ToDoList,结果如下

现在我们希望我们点击列表中的某一项时,就删除这一项

分析需求

我们知道Vue是基于MVVM模式设计的,所以删除列表中的某一个item只需要删除对应的数据即可。我们需要响应子组件的点击事件,记录被点击的组件的index,删除父组件data中的list中的对应数据

实现步骤

添加列表item的点击事件

var TodoItem = {
    props: ['content'],
    template: '<li v-on:click="handleItemClick">{{content}}</li>>',
    methods: {
        handleItemClick: function () {
            
        }
    }
}

向外触发事件

var TodoItem = {
    props: ['content'],
    template: '<li v-on:click="handleItemClick">{{content}}</li>>',
    methods: {
        handleItemClick: function () {
            this.$emit("delete")
        }
    }
}

我们通过$emit向外触发一个删除事件,在<todo-item/>中可以这么使用

<todo-item v-bind:content="item"
           v-for="item in list"
           v-on:delete="handleItemDelete">
</todo-item>

之后可以在父组件的methods中声明这个方法

methods: {
   ...
    handleItemDelete: function () {
       
    }
}

传递index数据

我们可以继续使用v-bind来给TodoItem传递数据

 <todo-item v-bind:content="item"
            v-bind:index="index"
            v-for="(item,index) in list"
            v-on:delete="handleItemDelete">
 </todo-item>

在子组件中拿到index后,向父组件传递

var TodoItem = {
    props: ['content', "index"],
    template: '<li v-on:click="handleItemClick">{{content}}</li>>',
    methods: {
        handleItemClick: function () {
            this.$emit("delete", this.index)
        }
    }
}

在父组件的handleItemDelete方法中就可以拿到index

methods: {
   ...
    handleItemDelete: function (index) {
       
    }
}

其他

为了代码更加简洁,写起来效率更高, v-bind:可以直接写成:v-on:可以直接写成@

完整版

<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="vue.js"></script>
</head>
<body>
<div id="app">
    <input type="text" v-model="inputValue">
    <button @click="onSubmitClick">提交</button>

    <todo-item :content="item"
               :index="index"
               v-for="(item,index) in list"
               @delete="handleItemDelete">
    </todo-item>
</div>

<script>
    var TodoItem = {
        props: ['content', "index"],
        template: '<li @click="handleItemClick">{{content}}</li>>',
        methods: {
            handleItemClick: function () {
                this.$emit("delete", this.index)
            }
        }
    }
    var app = new Vue({
        el: '#app',
        components: {
            TodoItem: TodoItem
        },
        data: {
            list: [],
            inputValue: ''
        },
        methods: {
            onSubmitClick: function () {
                this.list.push(this.inputValue)
                this.inputValue = ""
            },
            handleItemDelete: function (index) {
                this.list.splice(index, 1)
            }
        }
    })

</script>
</body>
</html>

总结

本文主要讲了一个非常基础的组件间通信案例,通过$emit由子组件向父组件发送事件(@delete),还可以通过这个方法向父组件传递一些数据(index

this.$emit("delete", this.index)
上一篇下一篇

猜你喜欢

热点阅读