总结:
1.子组件$emit抛出 父组件响应
父组件
<template>
<div>
<Son :parentsData="num" @updateParents="changeNum" />
</div>
</template>
<script>
import Son from "./text.vue";
export default {
data() {
return {
num: 0,
};
},
components: {
Son,
},
methods: {
changeNum(params) {
this.num = params;
},
},
};
</script>
<style scoped>
div {
padding: 50px;
}
</style>
子组件
<template>
<div>
{{ parentsData }}
<button @click="add">加1</button>
</div>
</template>
<script>
export default {
props: {
parentsData: {
type: Number,
},
},
methods: {
add() {
this.$emit("updateParents", 1);
},
},
};
</script>
<style lang="scss" scoped>
</style>
2.父组件xx.sync="xx"也是双向绑定 子组件$emit('update:xx')抛出 语法糖
父组件语法糖写法
<template>
<div>
<Son :parentsData.sync="num" />
</div>
</template>
<script>
import Son from "./text.vue";
export default {
data() {
return {
num: 0,
};
},
components: {
Son,
},
methods: {
// changeNum(params) {
// this.num = params;
// },
},
};
</script>
<style scoped>
div {
padding: 50px;
}
</style>
子组件语法糖写法
<template>
<div>
{{ parentsData }}
<button @click="add">加1</button>
</div>
</template>
<script>
export default {
props: {
parentsData: {
type: Number,
},
},
methods: {
add() {
this.$emit("update:parentsData", 1);
},
},
};
</script>
<style lang="scss" scoped>
</style>
不使用语法糖
父组件
<template>
<div>
<Son :parentsData.sync="num" @changeNum="(e) => (num = e)" />
</div>
</template>
<script>
import Son from "./text.vue";
export default {
data() {
return {
num: 0,
};
},
components: {
Son,
},
methods: {
// changeNum(params) {
// this.num = params;
// },
},
};
</script>
<style scoped>
div {
padding: 50px;
}
</style>
子组件
<template>
<div>
{{ parentsData }}
<button @click="add">加1</button>
</div>
</template>
<script>
export default {
props: {
parentsData: {
type: Number,
},
},
methods: {
add() {
this.$emit("changeNum", 1);
},
},
};
</script>
<style lang="scss" scoped>
</style>
3.父组件v-model响应 子组件抛出input事件 接收value参数 可以通过model参数配置响应事件与接收参数
父组件
<template>
<div>
<Son v-model="num" />
</div>
</template>
<script>
import Son from "./text.vue";
export default {
data() {
return {
num: 0,
};
},
components: {
Son,
},
methods: {
},
};
</script>
<style scoped>
div {
padding: 50px;
}
</style>
子组件 定义model vue3.0model内key有改变
<template>
<div>
{{ num }}
<button @click="add">加1</button>
</div>
</template>
<script>
export default {
props: {
num: {
type: Number,
},
},
model:{
prop:"num",
event:"changeNum"
},
mounted(){
console.log(this.num);
},
methods: {
add() {
this.$emit("changeNum", 1);
},
},
};
</script>
<style lang="scss" scoped>
</style>
另一种写法
父组件
<template>
<div>
<Son v-model="num" @input="(e) => (num = e)" />
// @input="(e) => (num = e)" 可以不用加上input也能生效
</div>
</template>
<script>
import Son from "./text.vue";
export default {
data() {
return {
num: 0,
};
},
components: {
Son,
},
methods: {
},
};
</script>
<style scoped>
div {
padding: 50px;
}
</style>
子组件、只能用value接收父传来参数
<template>
<div>
{{ value }}
<button @click="add">加1</button>
</div>
</template>
<script>
export default {
props: {
value: {
type: Number,
},
},
mounted() {
console.log(this.num);
},
methods: {
add() {
this.$emit("input", 1);
},
},
};
</script>
<style lang="scss" scoped>
</style>
4.parents访问父组件实例,官方文档建议谨慎使用,看个人需求
父组件
<template>
<div>
<Son :parentsNum="num" />
</div>
</template>
<script>
import Son from "./text.vue";
export default {
data() {
return {
num: 0,
};
},
components: {
Son,
},
methods: {
changeNum() {
this.num++;
},
},
};
</script>
<style scoped>
div {
padding: 50px;
}
</style>
子组件
<template>
<div>
{{ parentsNum }}
<button @click="add">加1</button>
</div>
</template>
<script>
export default {
props: {
parentsNum: {
type: Number,
},
},
methods: {
add() {
this.$parent.changeNum()
},
},
};
</script>
<style lang="scss" scoped>
</style>
5.通过provide inject传递函数与参数
父组件 重点:传递的对象在有响应式,否则子组件没有响应式
<template>
<div>
<Son />
</div>
</template>
<script>
import Son from "./text.vue";
export default {
data() {
return {
obj: {
num: 0,
},
};
},
provide() {
return {
_parents: this,
obj: this.obj,
changeNum: this.changeNum,
};
},
components: {
Son,
},
methods: {
changeNum() {
this.obj.num++;
},
},
};
</script>
<style scoped>
div {
padding: 50px;
}
</style>
子组件
<template>
<div>
{{ obj.num }}
<button @click="add">加1</button>
</div>
</template>
<script>
export default {
inject: ["obj", "changeNum", "_parents"],
mounted() {
console.log(this._parents);//拿到父组件实例,单页面应用控制某些状态
},
methods: {
add() {
this.changeNum();
},
},
};
</script>
<style lang="scss" scoped>
</style>
5.通过ref来获取组件实例,ref不能再template上使用,compute也不能用
父组件 在搜索参数触发子组件方法
<template>
<div>
<Son ref="sonModule" />
</div>
</template>
<script>
import Son from "./text.vue";
export default {
components: {
Son,
},
mounted() {
this.$refs.sonModule.add();
},
};
</script>
<style scoped>
div {
padding: 50px;
}
</style>
子组件
<template>
<div>
{{ num }}
<button @click="add">加1</button>
</div>
</template>
<script>
export default {
data() {
return {
num: 0,
};
},
methods: {
add() {
this.num++;
},
},
};
</script>
<style lang="scss" scoped>
</style>
6.可以通过扩展函数在原型上绑定广播/派发这个是在1.0中有的,但是2.0去除了,原理就是通过$children $parent循环emit事件
7.重新创建一个实例实现eventBus事件总线 原理为在新的实例上通过$on $emit传递与响应
8.传递参数时可以用v-bind/$attrs传递 传递函数可以用v-on/$listeners
父组件
<template>
<div>
{{ num }}
<Son :parentsNum="num" :parentsName="name" @parentsEvent="changeNum" />
</div>
</template>
<script>
import Son from "./text.vue";
export default {
data() {
return {
num: 0,
name: "baby",
};
},
components: {
Son,
},
methods: {
changeNum(params) {
this.num = params;
},
},
};
</script>
<style scoped>
div {
padding: 50px;
}
</style>
子组件
$attrs内部值被prios接收,则值被存到$props内部,没有被props接收,则存在$attrs内部,子组件内部把$attrs赋值给孙子组件该值会一直传递
$listeners不受影响
<template>
<div>
{{ parentsNum }}
<button v-on="$listeners" @click="add">孩子组件传递加1</button>
<Child v-bind="$attrs" v-on="$listeners" />
</div>
</template>
<script>
import Child from "./child.vue";
export default {
//这里接收了一个props,当前实例里$attrs只剩下boby
//$listeners会一直随着传递下去
props: {
parentsNum: {
type: Number,
},
},
components: {
Child,
},
mounted() {
console.log(this.$attrs);
},
methods: {
add() {
this.$emit("parentsEvent", 456);
},
},
};
</script>
<style lang="scss" scoped>
</style>
孙子组件
<template>
<div>
<button v-on="$listeners" @click="add">孙子组件传递加1</button>
</div>
</template>
<script>
export default {
mounted() {
console.log(this.$attrs, "child");
console.log(this, "child");
},
methods: {
add() {
this.$emit("parentsEvent", 132);
},
},
};
</script>
<style lang="scss" scoped>
</style>
不建议用$parent/$children 以及组件派发/广播,dispatch1.0是有得,2.0就没有了,因为这样结构不清晰