zoukankan      html  css  js  c++  java
  • vue 父子组件通信详解

    这是一篇详细讲解vue父子组件之间通信的文章,初始学习vue的时候,总是搞不清楚几个情况

    • 通过props在父子组件传值时,v-bind:data="data",props接收的到底是哪个?
    • this.$emit提交的事件名称,v-on:handleChange="handleChange",和父组件监听时候创建的方法名是否一样?到底哪个才是v-on应该监听的事件名称?

    你是否也有这样的疑惑呢?如果你跟我有一样的疑惑,那么继续往下看吧~~

    1.创建一个父组件 Parent.vue,在data中添加一个parentAge

    <template>
      <div class="my-parent">
        <h3>我是父组件</h3>
        <p>父组件的年龄是:{parentAge}}</p>
      </div>
    </template>
    
    <script>
    export default {
      data() {
        return {
          parentAge: 50
        };
      }
    };
    </script>
    
    <style>
    .my-parent {
      text-align: left;
      text-indent: 1em;
       1000px;
      height: 500px;
      border: 1px solid #555;
    }
    </style>

    2.创建子组件,在data中添加一个childAge

    <template>
      <div class="my-child">
        <h3>我是子组件</h3>
        <p>子组件的年龄是:{{childAge}}</p>
      </div>
    </template>
    
    <script>
    export default {
      data() {
        return {
          childAge: 27
        };
      }
    };
    </script>
    
    <style>
    .my-child {
      margin: 20px;
       760px;
      height: 200px;
      border: 1px solid red;
    }
    </style>

    3.把父子组件关联起来,并通过v-bind(即简写“:”)将父组件中的parentAge值,传递给子组件

    v-on绑定的属性名称deliverParentAge与data中定义的parentAge名称可以不一样
    属性deliverParentAge通过v-bind绑定的,也是子组件中通过props接收的,而parentAge是要传递给子组件的数值,它是一个值
     
    <template>
      <div class="my-parent">
        <h3>我是父组件,我想告诉我的子组件,我的年龄值是:{{parentAge}}</h3>
        <h3>我要通过v-bind(即简写":")语法糖绑定一个属性deliverParentAge,将父组件的值传递到子组件中</h3>
        <!-- 下面就是我的子组件 -->
        <my-child :deliverParentAge="parentAge"></my-child>
    
      </div>
    </template>
    
    <script>
    import MyChild from "./Child";
    export default {
      components: { MyChild },
      data() {
        return {
          parentAge: 49
        };
      }
    };
    </script>
    

    4.子组件通过props属性,在子组件中接收父组件传过来的值

    <template>
      <div class="my-child">
        <h5>我是子组件,我可以通过属性props来接收父组件传过来的年龄值是:{{deliverParentAge}}</h5>
      </div>
    </template>
    
    <script>
    export default {
      data() {
        return {
          childAge: 27
        };
      },
      props: {
        deliverParentAge: Number
      }
    };
    </script>
    

    5.现在来修改父组件的值(这个不是真的修改而是通过this.$emit提交一个事件,将子组件的行为告诉父组件)

    <template>
      <div class="my-child">
        <h5>我是子组件,我可以通过属性props来接收父组件传过来的年龄值是:{{deliverParentAge}},这是一个数字类型</h5>
        <h5>并且,我要告诉他,他今年生日已经过了,所以他的年龄应该<button @click="AddAge">加1</button></h5>
        下面我要通过this.$emit方法提交一个事件addParentAge,告诉我的父组件,他的实际年龄
      </div>
    </template>
    
    <script>
    export default {
      data() {
        return {
          childAge: 27
        };
      },
      props: {
        deliverParentAge: Number
      },
      // 新建一个计算属性,将父组件原来的值加1
      computed: {
        parentActualAge() {
          return this.deliverParentAge + 1;
        }
      },
      methods: {
        AddAge() {
          this.$emit("addParentAge", this.parentActualAge);
        }
      }
    };
    </script>

    6.父组件通过语法糖v-on(即简写为“@”)来监听子组件提交的事件addParentAge

    this.$emit提交的事件名称addParentAge,与方法handleAddParentAge名称可以不一样
    addParentAge是子组件提交的事件名称,也是父组件通过v-on监听的事件名称,而handleAddParentAge是父组件自定义的方法名称
     
    <template>
      <div class="my-parent">
        <h3>我是父组件,我想告诉我的子组件,我的年龄值是:{{parentAge}}</h3>
        <h3>我要通过v-bind(即简写":")语法糖绑定一个属性parentAge,告诉子组件我的年龄值是:{{parentAge}}</h3>
        <!-- 下面就是我的子组件 -->
        <my-child :deliverParentAge="parentAge"
                @addParentAge="handleAddParentAge"></my-child>
        <h3>通过监听子组件提交的事件addParentAge,我知道到了自己的实际年龄应该是:{{parentAge+1}},并通过方法handleAddParentAge,在控制台打印出我的真实年龄</h3>
    
      </div>
    </template>
    
    <script>
    import MyChild from "./Child";
    export default {
      components: { MyChild },
      data() {
        return {
          parentAge: 49
        };
      },
      methods: {
        handleAddParentAge(actualAge) {
          console.log("父组件的实际年龄是:", actualAge);
        }
      }
    };
    </script>

    现在来看控制台打印出来的内容

    7.现在将子组件data中的值,提交给父组件来看看

    <template>
      <div class="my-child">
        <h5>我是子组件,我可以通过属性props来接收父组件传过来的年龄值是:{{deliverParentAge}},这是一个数字类型</h5>
        <h5>现在我要告诉父组件,我的年龄是{{childAge}},这样他就可以知道,我们<button @click="DiffAge">相差</button>多少岁</h5>
        <h5>并且,我要告诉他,他今年生日已经过了,所以他的年龄应该<button @click="AddAge">加1</button></h5>
        下面我要通过this.$emit方法提交一个事件addParentAge,告诉我的父组件,他的实际年龄
      </div>
    </template>
    
    <script>
    export default {
      data() {
        return {
          childAge: 27
        };
      },
      props: {
        deliverParentAge: Number
      },
      computed: {
        parentActualAge() {
          return this.deliverParentAge + 1;
        }
      },
      methods: {
        AddAge() {
          this.$emit("addParentAge", this.parentActualAge);
        },
        DiffAge() {
          this.$emit("differAge", this.childAge);
        }
      }
    };
    </script>

    8.父组件通过v-on监听子组件提交的事件differAge

    <template>
      <div class="my-parent">
        <h3>我是父组件,我想告诉我的子组件,我的年龄值是:{{parentAge}}</h3>
        <h3>我要通过v-bind(即简写":")语法糖绑定一个属性parentAge,告诉子组件我的年龄值是:{{parentAge}}</h3>
        <!-- 下面就是我的子组件 -->
        <my-child :deliverParentAge="parentAge"
                @differAge="handleDifferAge"
                  @addParentAge="handleAddParentAge"></my-child>
        <h3>通过监听子组件提交的事件addParentAge,我知道到了自己的实际年龄应该是:{{parentAge+1}},并通过方法handleAddParentAge,在控制台打印出我的真实年龄</h3>
        <h3>通过监听子组件提交的事件differAge,并通过方法handleDifferAge,在控制台打印出子组件的年龄</h3>
    
      </div>
    </template>
    
    <script>
    import MyChild from "./Child";
    export default {
      components: { MyChild },
      data() {
        return {
          parentAge: 49
        };
      },
      methods: {
        handleAddParentAge(actualAge) {
          console.log("父组件的实际年龄是:", actualAge);
        },
        handleDifferAge(child) {
          console.log("我们的年龄差是:", this.parentAge + 1 - child);
        }
      }
    };
    </script>

    现在来看看页面展示的效果和控制台打印出来的信息

    下面贴上完整的代码

    // Parent.vue
    <template>
      <div class="my-parent">
        <h3>我是父组件,我想告诉我的子组件,我的年龄值是:{{parentAge}}</h3>
        <h3>我要通过v-bind(即简写":")语法糖绑定一个属性parentAge,告诉子组件我的年龄值是:{{parentAge}}</h3>
        <!-- 下面就是我的子组件 -->
        <my-child :deliverParentAge="parentAge"
                  @differAge="handleDifferAge"
                  @addParentAge="handleAddParentAge"></my-child>
        <h3>通过监听子组件提交的事件addParentAge,我知道到了自己的实际年龄应该是:{{parentAge+1}},并通过方法handleAddParentAge,在控制台打印出我的真实年龄</h3>
        <h3>通过监听子组件提交的事件differAge,并通过方法handleDifferAge,在控制台打印出子组件的年龄</h3>
    
      </div>
    </template>
    
    <script>
    import MyChild from "./Child";
    export default {
      components: { MyChild },
      data() {
        return {
          parentAge: 49
        };
      },
      methods: {
        handleAddParentAge(actualAge) {
          console.log("父组件的实际年龄是:", actualAge);
        },
        handleDifferAge(child) {
          console.log("我们的年龄差是:", this.parentAge + 1 - child);
        }
      }
    };
    </script>
    
    <style lang="stylus" scoped>
    .my-parent {
      text-align: left;
      text-indent: 1em;
       1000px;
      height: 500px;
      border: 1px solid #555;
    }
    </style>
    // Child.vue
    <template>
      <div class="my-child">
        <h5>我是子组件,我可以通过属性props来接收父组件传过来的年龄值是:{{deliverParentAge}},这是一个数字类型</h5>
        <h5>现在我要告诉父组件,我的年龄是{{childAge}},这样他就可以知道,我们<button @click="DiffAge">相差</button>多少岁</h5>
        <h5>并且,我要告诉他,他今年生日已经过了,所以他的年龄应该<button @click="AddAge">加1</button></h5>
        下面我要通过this.$emit方法提交一个事件addParentAge,告诉我的父组件,他的实际年龄
      </div>
    </template>
    
    <script>
    export default {
      data() {
        return {
          childAge: 27
        };
      },
      props: {
        deliverParentAge: Number
      },
      computed: {
        parentActualAge() {
          return this.deliverParentAge + 1;
        }
      },
      methods: {
        AddAge() {
          this.$emit("addParentAge", this.parentActualAge);
        },
        DiffAge() {
          this.$emit("differAge", this.childAge);
        }
      }
    };
    </script>
    
    <style>
    .my-child {
      margin: 20px;
       760px;
      height: 200px;
      border: 1px solid red;
    }
    </style>

    希望对你有用,欢迎提问与指正,一起学习前端呀!

  • 相关阅读:
    前端构建工具gulpjs的使用介绍及技巧(转载)
    jq checked 设置问题
    JavaScript面向对象及相关知识
    github 操作指南
    WebStorm常用快捷键
    Windows下Scala环境搭建
    For与Function进阶实战、Lazy的使用笔记总结
    第3课 Scala函数式编程彻底精通及Spark源码阅读笔记
    第2课 Scala面向对象彻底精通及Spark源码SparkContext,RDD阅读总结
    第1课 Scala入门与实战笔记总结
  • 原文地址:https://www.cnblogs.com/shengnan-2017/p/10419050.html
Copyright © 2011-2022 走看看