在这里就引用之前写的项目,举个栗子
先贴上代码
list.vue组件
<template> <div class="list"> <ul v-for="(friend, i) in friendList"> <li @click="setContact(i)"> <p class="name">{{friend.username}}</p> </li> </ul> </div> </template> <script> export default { props: ["friendList"], methods: { // 创建一个setContact方法,把当前点击的名称传给父组件 setContact(index) { this.$emit("set-contact", this.friendList[index]); }, // 创建一个方法,获取参数 getList(list) { console.log(list); console.log(typeof this.$parent);// object }, }, }; </script>
父组件chat.vue
<template> <div id="chat"> <user-list :friendList="this.friendList" @set-contact="getcontact"ref="friends"></user-list> </div> </template> <script> import UserList from "../../components/chat/list"; export default { data() { return { friendList: [ { username: "tom" }, { username: "cat" }, { username: "dog" } ], }; }, components: { UserList }, mounted() { console.log(this.$refs.friends); this.$refs.friends.getList(this.friendList); console.log(this.$children instanceof Array); // true console.log(this.$children); }, methods: { // 接收子组件返回的数据 getcontact(index) { console.log(index); }, }, }; </script>
通过props父传子,通过$emit子传父
在父组件中引用子组件,再把数据通过参数传给子组件,如果需要子组件在返回数据的话,父组件可以通过自定义事件的形式,接收数据。
如下图,父组件通过friendList传给子组件,子组件用props中的friendList接收,然后显示出来,当点击某个li的时候,子组件就通过$emit把当前点击li的username传给父组件,父组件通过getcontact接收。
注意:父组件中@set-contact中的set-contact,必须与子组件中this.$emit(“set-contact”, this.friendList[index])中set-contact一致。
在子组件中利用props接收父组件中传过来的值,相当于形参,也可以自己定义接收参数类型,比如这样:
// 把props: ["friendList"]换成 props: { friendList: { type: Array, } }
效果图
当我们点击某个item时,比如cat,控制台就会显示,就会显示子组件返回的数据了。
通过$refs
通过在父组件中的子组件中声明ref,那么这个ref就指向子组件实例
接下来,就可以通过this.$refs.名称 的形式调用子组件的方法。
如下图,通过在父组件中的mounted中调用this.$refs.friends可以看到一个vue实例对象,这个对象就是list.vue实例,而且可以通过this. $refs.friends.getList(this.friendList)形式调用子组件的方法,并把参数this.friendList传给子组件。
通过$parent和 $children
通过$parent可以访问父组件,通过 $children可以访问子组件,用法跟前面两种大同小异,主要就是一些细节的问题
$parent返回一个object对象, $children返回的是一个数组对象
通过下图,可以看到$parent和 $children返回的是一个对象,需要引用组件方法属性的话,需要this. $parent.方法和this. $children[0].方法
这个用的比较少,我主要用的是上面两个