Jun 01, 2021 Article blog
Vue offers a wide variety of communications, including
兄弟间
and
非兄弟间
which is easy to summarize and access.
components
├── Parent.vue // 父亲
├── Son1.vue // 儿子1
Use the son component in the father component to give the son a one-way pass value through
:date="xxx"
<template>
<div>
<div>爸爸:{{date}}</div>
<Son1 :date="date"></Son1>
</div>
</template>
<script>
import Son1 from "./son1";
export default {
components: { Son1 },
data() {
return {
date: 1,
};
},
};
</script>
The son component accepts the value passed by the parent component through
props
<template>
<div>儿子:{{date}}</div>
</template>
<script>
export default {
props: {
date: {
type: Number, //校验类型
default: "1",
},
},
};
</script>
components
├── Parent.vue // 父亲
├── Son1.vue // 儿子1
(Recommended tutorial: Vue 2 tutorial)
The child component triggers
$emit
method by touching itself, and then the parent component's method, passing the modified content to the parent component by calling back the
回调传参
<template>
<div>
<div>儿子:{{date}}</div>
<button @click="changeNum">修改</button>
</div>
</template>
<script>
export default {
props: {
date: {
type: Number,
default: "1",
},
},
methods: {
changeNum() {
this.$emit("changeNum", 2);
},
},
};
</script>
The parent component accepts the callback
params
parameter, which means that the father needs to bind a custom event to his
$on("changeNum",params)
<template>
<div>
<div>爸爸:{{date}}</div>
<Son1 :date="date" @changeNum="changeNum"></Son1>
</div>
</template>
<script>
import Son1 from "./son1";
export default {
components: { Son1 },
data() {
return {
date: 1,
};
},
methods: {
changeNum(params) {
this.date = params;
},
},
};
</script>
.sync
components
├── Parent.vue // 父亲
├── Son1.vue // 儿子1
Subcommys transmit events through
$emit("update:xxx")
<template>
<div>
<div>儿子:{{date}}</div>
<button @click="changeNum">修改</button>
</div>
</template>
<script>
export default {
props: {
date: {
type: Number,
default: "1",
},
},
methods: {
changeNum() {
this.$emit("update:date", 2);
},
},
};
</script>
The parent component accepts the argument by
:xxx.sync="xxx"
<template>
<div>
<div>爸爸:{{date}}</div>
<Son1 :date.sync="date"></Son1>
</div>
</template>
<script>
import Son1 from "./son1";
export default {
components: { Son1 },
data() {
return {
date: 1,
};
},
};
</script>
<Son1 :date.sync="date"></Son1>
//这个写法是上面的替代品 默认组件内部触发 update:count 规定写法
<Son1 :date="date" @update:date="val=>date=val"></Son1>
v-model
components
├── Parent.vue // 父亲
├── Son1.vue // 儿子1
The event triggered by the child component can only be an
input
event, and the property name of the receiving
props
can only be called
value
<template>
<div>
<div>儿子:{{value}}</div>
<button @click="changeNum">修改</button>
</div>
</template>
<script>
export default {
props: {
value: {
type: Number,
default: 1,
},
},
methods: {
changeNum() {
this.$emit("input", 2);
},
},
};
</script>
The parent component receives parameters through
v-model
<template>
<div>
<div>爸爸:{{value}}</div>
<Son1 v-model="value"></Son1>
</div>
</template>
<script>
import Son1 from "./son1";
export default {
components: { Son1 },
data() {
return {
value: 1,
};
},
};
</script>
<Son1 :value="value" @input="val=>value=val"></Son1>
//这个写法是上面的替代品 默认组件内部触发 input 规定写法
<Son1 v-model="value"></Son1>
v-model` 局限只能传递一个属性 如果只有一个 可以使用`v-model` 多个依然需要使用`.sync
components
├── Parent.vue // 父亲
├── Son1.vue // 儿子1
├── Grandson1.vue //孙子1
Here's the scenario: Grandson wants to pass data to grandpa, grandson needs to find grandpa's events to pass
$parent.$emit
<template>
<div>
<div>孙子{{value}}</div>
<button @click="$parent.$emit('change',3)">修改</button>
</div>
</template>
<script>
export default {
props: {
value: {
type: Number,
default: "",
},
},
};
</script>
The son component uses the grandchild component
<template>
<div>
<div>儿子:{{value}}</div>
<grandson1 :value="value"></grandson1>
</div>
</template>
<script>
import grandson1 from "./grandson1";
export default {
components: {
grandson1,
},
props: {
value: {
type: Number,
default: 1,
},
},
};
</script>
Dad customizes
change
event for his grandson
<template>
<div>
<div>爸爸:{{value}}</div>
<Son1 @change="val=>value=val" :value="value"></Son1>
</div>
</template>
<script>
import Son1 from "./son1";
export default {
components: { Son1 },
data() {
return {
value: 1,
};
},
};
</script>
If the hierarchy is deep then there will be
$parent.$parent.....
We can encapsulate a$dispatch
method to distribute up
Vue.prototype.$dispatch = function $dispatch(eventName, data) {
let parent = this.$parent;
while (parent) {
parent.$emit(eventName, data);
parent = parent.$parent;
}
};
By the same token, if you can find a father up, you can look down for a son, and you can encapsulate a downward distribution method
$broadcast
Vue.prototype.$broadcast = function $broadcast(eventName, data) {
const broadcast = function () {
this.$children.forEach((child) => {
child.$emit(eventName, data);
if (child.$children) {
$broadcast.call(child, eventName, data);
}
});
};
broadcast.call(this, eventName, data);
};
components
├── Parent.vue // 父亲
├── Son1.vue // 儿子1
├── Grandson1.vue //孙子1
$attrs
bulk pass-down properties
<template>
<div>
<div>爸爸:{{value}}</div>
<Son1 @change="val=>value=val" :value="value"></Son1>
</div>
</template>
<script>
import Son1 from "./son1";
export default {
components: { Son1 },
data() {
return {
value: 1,
};
},
};
</script>
Use the
$attrs
property in the son component, and with
v-bind
you can continue the property down
<template>
<div>
<div>儿子:{{$attrs.value}}</div>
<grandson1 v-bind="$attrs"></grandson1>
</div>
</template>
<script>
import grandson1 from "./grandson1";
export default {
components: {
grandson1,
},
mounted() {
console.log(this.$attrs);
},
};
</script>
Note that when you use $attrs, if you use
props
in a component, the property is removed from the currentattrs
Using
$attrs
property in the grandson component, you can continue the property down
<template>
<div>
<div>孙子{{$attrs.value}}</div>
</div>
</template>
<script>
export default {
//props: {
// value: Number,
//},
mounted() {
console.log(this.$attrs);
},
};
</script>
If the father passes the element to the son, the son has three properties that are not available, the grandson passes to the grandson, but does not want this property on the page, you can set
inheritAttrs: false
$listeners
batch-down method
<template>
<div>
<div>爸爸:{{value}}</div>
<Son1 @click="change" :value="value"></Son1>
</div>
</template>
<script>
import Son1 from "./son1";
export default {
components: { Son1 },
data() {
return {
value: 1,
};
},
methods: {
change() {
this.value = 2;
},
},
};
</script>
You can use the $listeners property in
$listeners
component, and
v-on
you can continue the method down
son1
<template>
<div>
<div>儿子:{{$attrs.value}}</div>
<grandson1 v-bind="$attrs" v-on="$listeners"></grandson1>
</div>
</template>
<script>
import grandson1 from "./grandson1";
export default {
components: {
grandson1,
},
mounted() {
console.log(this.$attrs);
console.log(this.$listeners);
},
};
</script>
Sun tzu components can use the methods on
$listeners
directly
<template>
<div>
<div>孙子{{$attrs.value}}</div>
<button @click="$listeners.click"></button>
</div>
</template>
<script>
export default {
mounted() {
console.log(this.$attrs);
console.log(this.$listeners);
},
};
</script>
app.vue
components
├── Parent.vue // 父亲
├── Son1.vue // 儿子1
├── Grandson1.vue //孙子1
Declare a public data at the parent level
export default {
provide() {
return { vm: this };
},
};
Principles can be injected into subcommys that mount data on the current instance
<template>
<div>
<div>孙子</div>
</div>
</template>
<script>
export default {
inject: ["vm"],
mounted() {
console.log(this);
},
};
</script>
Note: This method is confusing after use, it is generally
不会在业务代码中使用
often in component libraries or multi-level communication, for your convenience you can useprovide
components
├── Parent.vue // 父亲
├── Son1.vue // 儿子1
ref
gets the real dom element if it represents an instance of the current component on
当前组件的实例
Methods or data for child components can be obtained directly in the parent component.
<template>
<div>
<div>爸爸</div>
<Son1 ref="son"></Son1>
</div>
</template>
<script>
import Son1 from "./son1";
export default {
components: { Son1 },
mounted() {
this.$refs.son.show();
},
};
</script>
<template>
<div>
<div>儿子</div>
</div>
</template>
<script>
export default {
methods: {
show() {
console.log(1);
},
},
};
</script>
Note:
ref
does not重名
but it can cause数组
when and only whenv-for
is used
main.js
components
├── Grandson1.vue // 孙子1
├── Son2.vue // 儿子2
EventBus
can be used for
cross-component
notifications (not complex projects can be used this way)
Vue.prototype.$bus = new Vue();
Grandson1
component and
Son2
communicate with each other
<template>
<div>孙子1</div>
</template>
<script>
export default {
mounted() {
this.$nextTick(() => {
this.$bus.$emit("test", "go");
});
},
};
</script>
The Son 2 component here can only use
$on
to trigger
Grandson1
component event
<template>
<div>儿子2</div>
</template>
<script>
export default {
mounted() {
this.$bus.$on("test", (data) => {
console.log(data);
});
},
};
</script>
Vuex
is a state management model developed specifically for Vue .js applications.
(Recommended micro-class: Vue 2.x micro-class)
Source: Public Number - Clown's Cabin
Author: Clown
The above is the W3Cschool programming lion about the Vue components between the eight modes of communication related to the introduction, I hope to help you.