Skip to content

Vue子组件向父组件通信

1. Vue子组件向父组件通信

  1. 通过props属性,父组件提前传递一个方法或者函数
  2. 子组件中事件调用方法内部,调用props传递的函数,将要传递的值作为方法参数 需要注意的是:
  3. 父组件传递的函数名不要和子组件的data属性,computed属性,methods名字同名。
  4. 使用v-model时候要切记:v-model绑定的值不能是props传过来的值,因为props是不可以修改的
  5. props传过来的若是对象类型的值,修改对象中的属性时Vue不会报错,但不推荐这样做
vue
<template>
  <div>
    <h3>总共有: {{ totalNum }} 个任务</h3>
    <Header></Header>
<!-- changeTotalNum当做变量的写法传递给子组件   -->
    <List :changeTotalNum='changeTotalNum'></List>
    <Footer></Footer>
  </div>
</template>

<script>
import Header from "@/components/Header.vue";
import List from "@/components/List.vue";
import Footer from "@/components/Footer.vue";

export default {
  name: 'App',
  components: {
    Header, List, Footer
  },
  data() {
    return {
      totalNum:0
    }
  },
  methods: {
    changeTotalNum(totalNum){
      this.totalNum = totalNum
    }
  }
}
</script>
vue
<template>
  <div>
    <Item v-for="todoItem in todoList" :todoItem="todoItem" :key="todoItem.id"></Item>
  </div>
</template>

<script>
import Item from "@/components/Item.vue";

export default {
  name: "List",
  components: {Item},
  props: ['changeTotalNum'],/*接收父组件的函数*/
  data(){
    return {
      todoList:[
        {id:1, done: false, todoName: '学习'},
        {id:2, done: true, todoName: '打游戏'}
      ]
    }
  },
  methods:{
    addTodo(todoName) {
      let newId = this.todoList[this.todoList.length-1].id+1
      this.todoList.unshift({id: newId, done: false, todoName: todoName})
      // 将数组长度传入函数中,传给父组件
      this.changeTotalNum(this.todoList.length) 
    }
  },
  mounted() {
    this.$bus.$on('addTodo', this.addTodo)
  }
}
</script>

用户输入文字回车后,监听事件被调用,todoList是一个数组但是调用的是unshift(能够被Vue监测到被改变的方法),todoList加入元素放到第一位置后,引起DOM重新渲染,根据key发现原来的数组元素没有变h化,就直接插入虚拟DOM在List的DOM第一位置。