Vue学习笔记之父子组件通信以及经典案例

父组件、子组件直接的访问方式:

1、父组件访问子组件可以用$childern 或者$refs

$childern 的用法:

当父组件引用多个子组件的时候,就会生成多个对应的对象:

$childern可以访问子组件中的方法、data等数据

但$childern一般在开发中比较少用,用$refs比较常用,因为$refs是可以通过key来绝对定位到对应的子组件,这种方法在实际开发中比较常用。$refs是一个对象类型,默认是一个空对象,在引用的时候通过ref = key 值来生成一个实例对象:

 

扫描二维码关注公众号,回复: 11412673 查看本文章

2、子组件访问父组件用$parent

但是在实际开发是不会这样使用的,因为如果这样嵌套组件的话,里面的子组件就不够独立了,导致子组件的复用性不强,与父组件的耦合度高。

如果需要访问跟组件里面的方法或数据,则可以用$root进行访问:

 

 

经典小案例:

  1. 功能需求:通过组件,有两个数据输入,由子组件输入的数字,改变父组件的数字,反之亦然,并且两个数字成倍数相互影响。

 

1、在我们实现这个需求的时候,我们第一想到的就是通过v-model进行输入框与data数据的绑定,由于子组件只能访问自己的数据,所以我们一开始想到的最简单的办法是:

但是这样编译器会反馈一个错误信息给我们:

大概的意思是:避免直接修改prop里的值,应该要通过父组件进行值的修改。代替方案:通过修改子组件的Data函数进行值修改,或者通过计算的方法,替代方案如下:

此时不再报错,但是我们发现当改变输入框的值时,props里面的值时没有发生变化的。原因是Input输入框里面绑定的是data()函数中的字段。所以要改变子组件里面的数据,需要通过data函数或计算方法进行修改,不要直接绑定props里面的字段!但是展示是可以直接用props里面的字段。

2、为了实现修改props里面数据,我们将v-modle进行拆分:v-bind、v-on进行处理:

子组件:

父组件:

3、第一个数字是第二个数字的倍数关系,而且给变任何一个值,就会影响另外一个值

为了实现此功能,在num1Input(event)事件中进一步修改另外一个数字的值:

改变data1的值,相应的data2的值也跟着变化:

改变data2的值,相应的data1的值也跟着变化:

4、完整代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<div id="app">
  <cpn :number1="num1" :number2="num2"
       @num1change="num1change"
       @num2change="num2change"></cpn>
</div>

<template id="cpn">
  <div>
    <h2>props1: {{number1}}</h2>
    <h2>data1: {{dnumber1}}</h2>
<!--    <input type="text" v-model="dnumber1">-->
    <input type="text" v-bind:value="dnumber1" @input="num1Input">
    <h2>props2: {{number2}}</h2>
    <h2>data2: {{dnumber2}}</h2>
    <input type="text" :value="dnumber2" @input="num2Input">
<!--    <input type="text" v-model="dnumber2">-->
  </div>
</template>

<script src="../js/vue.js"></script>
<script>
  const  app = new Vue({
    el: '#app',
    data: {
      num1: 1,
      num2: 0
    },
    methods: {
      num1change(value) {
        this.num1 = parseFloat(value)
      },
      num2change(value) {
        this.num2 = parseInt(value)
      }
    },
    components: {
      cpn: {
        template: '#cpn',
        props: {
          number1: Number,
          number2: Number
        },
        data() {
          return {
            dnumber1: this.number1,
            dnumber2: this.number2
          }
        },
        methods: {
          num1Input(event) {
            // 1、将Input输入框的值复制到dnumber1中
            this.dnumber1 = event.target.value;
            // 2、通过$emit发出事件改变父组件的值
            this.$emit('num1change', this.dnumber1)  // 通过$emit改变父组件的值
            // 3、同时修改dnumber2的值
            this.dnumber2 = this.dnumber1 * 100;  // 改变值
            this.$emit('num2change', this.dnumber2)  // 再次传出去
          },
          num2Input(event) {
            this.dnumber2 = event.target.value;
            this.$emit('num2change', this.dnumber2)
            this.dnumber1 = this.dnumber2 / 100;  // 改变值
            this.$emit('num1change', this.dnumber1)  // 再次传出去
          }
        }
      }
    }
  })
</script>

</body>
</html>

猜你喜欢

转载自blog.csdn.net/zeng_sily/article/details/106461773