遇到问题首先要查官方文档
https://v2.cn.vuejs.org/v2/guide/components-edge-cases.html
文档能首先解决60% - 80%的问题。
父beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount->子mounted->父mounted
父beforeUpdate->子beforeUpdate->子updated->父updated
父beforeUpdate->父updated
父beforeDestroy->子beforeDestroy->子destroyed->父destroyed
首先这个一对一表示的是一个父组件下同名的只有一个子组件。【即子组件不可以被v-for包围】
在js栏中调用子组件的方法,$refs是Vue对象的一个实例属性,存储当前vue对象中所引用的组件标签。我们刚刚指定了子组件的名称,直接对应然后就可以调用该名称组件内部的方法了。
无论是方法1还是放发2,多关注是否使用了v-if在子组件上,v-if为false的时候,未渲染组件,无法通信。
方法2:
方案二:通过组件的$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.$emit("childmethod") //子组件$on中的名字
},
},
}
</script>
//子组件中
<template>
<div>我是子组件</div>
</template>
<script>
export default {
mounted() {
this.$nextTick(function() {
this.$on('childmethods', function() {
console.log('我是子组件方法');
});
});
},
};
</script>
以上两种方法都是基于this.$refs调用子组件,要求子组件已渲染,如果子组件使用了v-else等导致无法立即渲染的,可能会失效。【输出this.$refs可以看到有哪些子组件】,建议换用v-show。
一个子组件只有一个父组件
子组件直接使用this.$parent.xxx()即可,注意方法名是其父组件要已经定义的。
(效果有点不好)
在一对一的父子通信下,该方法更加简单。当然有另一种方法是使用$emit,下面的多对一中会讲到。
指定名称,即指定ref
先进入子组件,子组件中指定需要的变量的名称,指定字符串名称即可,因为只作为该组件的属性名!同时要注意,props是一个数组,而且是官方指定的vue实例的一个属性,所以其级别是和methods和data是同级的,不要放到里面去了。而且这个是在子组件中定义!
这里的item和i都是for内的临时值,没有在父类的return中定义。如果绑定this.父类的属性。则要求props中提供的变量名不能与之重复。比如父类return {num: 10}; 子类中不允许props: {‘num’}; 要改为props: {‘myNum’}
在进入父组件,对于子组件需要访问的变量,我们直接双向绑定,属性名与子组件的props数组中定义的一致,而绑定的对象就是父组件的属性变量,可以是如图的v-for的对象,也可以是data中的变量对象。【如果出错了,检查自己是不是加了this.属性,一律不要加this.属性, 直接输入变量名就好了】
这里的值是可以直接在method中使用的,在method中监察可以使用watch。而如果需要修改父组件的值,最好在父组件添加一个方法,使用method调用在父组件中进行修改
注意:
vue 中父组件向子组件传递数据用 props, 但是子组件是无法修改它的。如果子组件需要动态修改它就只能自造一个对应的 data 域。比如
components:{Tinymce},
props:['id','formDatas'],
data() {
return {
form: {
title: '',
title_type: '',
push_date: '',
source: '',
title_introduce: '',
title_content:'',
}
}
},
created(){
this.form = this.formDatas
},
这样是无法把props的值传递给data里面,因为data()只会运行一次,所以要用watch来进行监听props里面内容的变化,然后对data里面进行赋值
【是news而不是new】
watch:{
formDatas(news,olds){
this.form = news
}
}
因此当父组件传递值给子组件的时候,watch就会监听到formDatas的变化,将新的值赋给你想要传值的data,然后进行改变。
一个父组件下有多个同名子组件。如图,通过v-for后,名为Comments的组件在当前父组件中可就不止一个了。
如果我们仍然使用this.$ref.xxx
肯定无法获取,因为有多个同名组件。
那很容易理解,这多个同名对象一定被撞到一个容器中了。即this.$ref.xxx[i]
不就行了!?如图官方文档
this.$ref.xxx[i]
来获取子组件对象的this.$ref.xxx[i]
,因为对于索引来说会失控解决方向参考:
即多个同名子组件对应一个父组件。
与**子组件调用父组件的属性【一对一】**一致,使用props数组
官方对于兄弟组件进行通信,使用的是$bus
父调用子
子调用父
如果父子通信出现在v-for的场景下