当前位置: 移动技术网 > IT编程>脚本编程>vue.js > Vue父子组件所有通信方法***前端Vue必学***(父子传值,父子方法的调用)

Vue父子组件所有通信方法***前端Vue必学***(父子传值,父子方法的调用)

2020年07月17日  | 移动技术网IT编程  | 我要评论

vue 父子组件通信详解

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

通过props在父子组件传值时,v-bind:data="data",props接收的到底是哪个?
this.$emit提交的事件名称,v-on:handleChange="handleChange",和父组件监听时候创建的方法名是否一样?到底哪个才是v-on应该监听的事件名称?
你是否也有这样的疑惑呢?如果你跟我有一样的疑惑,那么继续往下看吧~~

创建一个父组件 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;
  width: 1000px;
  height: 500px;
  border: 1px solid #555;
}
</style>

创建子组件,在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;
  width: 760px;
  height: 200px;
  border: 1px solid red;
}
</style>

把父子组件关联起来,并通过v-bind(即简写“:”)将父组件中的parentAge值,传递给子组件
v-on绑定的属性名称deliverParentAgedata中定义的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>

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

<template>
  <div class="my-child">
    <h5>我是子组件,我可以通过属性props来接收父组件传过来的年龄值是:{{deliverParentAge}}</h5>
  </div>
</template>

<script>
export default {
  data() {
    return {
      childAge: 27
    };
  },
  props: {
    deliverParentAge: Number
  }
};
</script>

现在来修改父组件的值(这个不是真的修改而是通过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>

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

在这里插入图片描述

现在将子组件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>

父组件通过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;
  width: 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;
  width: 760px;
  height: 200px;
  border: 1px solid red;
}
</style>

Vue子组件调用父组件的方法函数(3种)

第一种方法

直接在子组件中通过this.$parent.event来调用父组件的方法

父组件

<template>
  <div>
    <child></child>
  </div>
</template>
<script>
  import child from './components/dam/child';
  export default {
    components: {
      child
    },
    methods: {
      fatherMethod() {
        console.log('测试');
      }
    }
  };
</script>

子组件

<template>
  <div>
    <button @click="childMethod()">点击</button>
  </div>
</template>
<script>
  export default {
    methods: {
      childMethod() {
        this.$parent.fatherMethod();
      }
    }
  };
</script>

第二种方法
在子组件里用$emit向父组件触发一个事件,父组件监听这个事件就行了。

父组件

<template>
  <div>
    <child @fatherMethod="fatherMethod"></child>
  </div>
</template>
<script>
  import child from '~/components/dam/child';
  export default {
    components: {
      child
    },
    methods: {
      fatherMethod() {
        console.log('测试');
      }
    }
  };
</script>

子组件

<template>
  <div>
    <button @click="childMethod()">点击</button>
  </div>
</template>
<script>
  export default {
    methods: {
      childMethod() {
        this.$emit('fatherMethod');
      }
    }
  };
</script>

第三种方法
父组件把方法传入子组件中,在子组件里直接调用这个方法

父组件

<template>
  <div>
    <child :fatherMethod="fatherMethod"></child>
  </div>
</template>
<script>
  import child from '~/components/dam/child';
  export default {
    components: {
      child
    },
    methods: {
      fatherMethod() {
        console.log('测试');
      }
    }
  };
</script>

子组件

<template>
  <div>
    <button @click="childMethod()">点击</button>
  </div>
</template>
<script>
  export default {
    props: {
      fatherMethod: {
        type: Function,
        default: null
      }
    },
    methods: {
      childMethod() {
        if (this.fatherMethod) {
          this.fatherMethod();
        }
      }
    }
  };
</script>

子组件 更简便的写法

<template>
  <div>
    <button @click="fatherMethod()">点击</button>
  </div>
</template>
<script>
  export default {
    props: {
      fatherMethod: {
        type: Function,
        default: null
      }
    },
    methods: {
      
    }
  };
</script>

vue父组件中调用子组件的两个方法

Vue项目中如何在父组件中直接调用子组件的方法:

方案一:通过ref直接调用子组件的方法;

//父组件中

<template>
    <div>
        <Button @click="handleClick">点击调用子组件方法</Button>
        <Child ref="child"/>
    </div>
</template>    

<script>
import Child from './child';

export default {
    methods: {
        handleClick() {
              this.$refs.child.sing();
        },
    },
}
</script>
//子组件中

<template>
  <div>我是子组件</div>
</template>
<script>
export default {
  methods: {
    sing() {
      console.log('我是子组件的方法');
    },
  },
};
</script>

方案二:通过组件的$emit$on方法;

//父组件中

<template>
    <div>
        <Button @click="handleClick">点击调用子组件方法</Button>
        <Child ref="child"/>
    </div>
</template>    

<script>
import Child from './child';

export default {
    methods: {
        handleClick() {
              this.$refs.child.sing();
        },
    },
}
</script>
//子组件中

<template>
    <div>我是子组件</div>
</template>
<script>
export default {
    mounted() {
        this.$nextTick(function() {
            this.$on('childmethods', function() {
                console.log('我是子组件方法');
            });
        });
     },
};
</script>

本文地址:https://blog.csdn.net/Sky_fy_1314/article/details/107365466

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网