Parent-child component communication
prop
event
style和class
natvie修饰符
$listeners
v-model
sync修饰符
$parent和$children
$slots和$scopedSlots
ref
Communicate across components
Provide和Inject
router
vuex
store模式
eventbus
Parent-child component communication
prop
The most common way of component communication, passed from parent component to child component. prop can receive an array or object
//子组件
<script>
export default {
name: "Comp",
//数组方式 props:[....]
// ↓ 对象方式
props: {
datas: {
type: Object,
default: () => {
return {};
}
},
}
</script>
event
The child component sends a notification to the parent component and passes parameters
Subassembly
methods:{
// 通过 $emit向父组件发送一个通知
handleEvent(){
this.$emit('eventMsg', option)
}
}
parent component
methods:{
// 监听子组件定义的方法
eventMsg(option){
console.log(option);
}
}
style and class
The parent component can pass style and class to the child component, and the style and class will be merged into the root element of the child component
parent component
<template>
<div id="app">
<HelloWorld
style="color:red"
class="hello"
msg="Welcome to Your Vue.js App"
/>
</div>
</template>
<script>
import HelloWorld from "./components/HelloWorld.vue";
export default {
components: {
HelloWorld,
},
};
</script>
Subcomponents
<template>
<div class="world" style="text-align:center">
<h1>{{msg}}</h1>
</div>
</template>
<script>
export default {
name: "HelloWorld",
props: {
msg: String,
},
};
</script>
final render result
<div id="app">
<div class="hello world" style="color:red; text-aling:center">
<h1>Welcome to Your Vue.js App</h1>
</div>
</div>
attribute
When the parent component uses the child component, it defines some properties on the child component. These properties will act on the root element of the child component, but do not include style and class
parent component
<HelloWorld data-a="1" data-b="2" msg="Welcome to Your Vue.js App" />
Subassembly
<template>
<div>
<h1>{{msg}}</h1>
</div>
</template>
<script>
export default {
name: "HelloWorld",
props: {
msg: String,
},
created() {
// 通过$attrs获取父组件定义的 attribute
console.log(this.$attrs); // {"data-a":"1","data-b":"2"}
},
};
</script>
final render result
<div id="app">
<div data-a="1" data-b="2">
<h1>Welcome to Your Vue.js App</h1>
</div>
</div>
Tip: Subcomponents can attach attributes to the root element of subcomponents by defining inheritAttrs: false without affecting the data obtained through $attrs
natvie modifier
When registering an event, the parent component can register the event on the root element of the child component through the navite modifier
parent component
<template>
<div id="app">
<HelloWorld @click.native="handleClick" />
</div>
</template>
<script>
import HelloWorld from "./components/HelloWorld.vue";
export default {
components: {
HelloWorld,
},
methods: {
handleClick() {
console.log(1);
},
},
};
</script>
Subassembly
<template>
<div>
<h1>Hello World</h1>
</div>
</template>
final render result
<template>
<div id="app">
<h1>Hello World</h1>
</div>
</template>
// 当点击app时。会触发父组件定义的 handleClick 方法
$listeners
Child components can get all the handlers passed by the parent component through $listeners
v-model
When the parent component uses the child component, it can bind the v-model to the child component, and the child component also obtains the value defined by the parent component by defining the model's prop and event
parent component
`
<Compn v-model="datas" />
`
Subassembly
<script>
export default {
//分类筛选组件
name: "sortFilter",
//定义实现v-modal的属性与事件
model: {
prop: "value",
event: "change"
},
props: {
//绑定的值
value: {
type: [String, Number],
default: ""
}
},
created() {
console.log(this.value)
},
</script>
sync modifier
Similar to v-model, used for two-way data binding, the difference is that v-model can only bind to one data, and the sync modifier has no restrictions
Subcomponents
<template>
<div>
<p>
<button @click="$emit(`update:num1`, num1 - 1)">-</button>
{{ num1 }}
<button @click="$emit(`update:num1`, num1 + 1)">+</button>
</p>
<p>
<button @click="$emit(`update:num2`, num2 - 1)">-</button>
{{ num2 }}
<button @click="$emit(`update:num2`, num2 + 1)">+</button>
</p>
</div>
</template>
<script>
export default {
props: ["num1", "num2"],
};
</script>
parent component
<template>
<div id="app">
<Numbers :num1.sync="n1" :num2.sync="n2" />
<!-- 等同于 -->
<Numbers
:num1="n1"
@update:num1="n1 = $event"
:num2="n2"
@update:num2="n2 = $event"
/>
</div>
</template>
<script>
import Numbers from "./components/Numbers.vue";
export default {
components: {
Numbers,
},
data() {
return {
n1: 0,
n2: 0,
};
},
};
</script>
$parent and $children
Inside the component, you can get the parent and child component instances of the current component through the $parent and $children properties, respectively
<template>
<div class="hello">
<button @click="handelParent">获取父组件实例</button>
<button @click="handelChild">获取子组件实例</button>
<Child />
</div>
</template>
<script>
import Child from "./Children.vue";
export default {
name: "HelloWorld",
props: {
msg: String,
},
components: {
Child,
},
methods: {
handelParent() {
console.log("父组件实例:", this.$parent);
},
handelChild() {
console.log("子组件实例", this.$children);
},
},
};
</script>
ref
When using a component, you can get the component instance by defining a ref on the component
<template>
<div class="hello">
<button @click="handelChild">获取子组件实例</button>
<Child ref="child" />
</div>
</template>
<script>
import Child from "./Children.vue";
export default {
name: "HelloWorld",
props: {
msg: String,
},
components: {
Child,
},
methods: {
handelChild() {
console.log("子组件实例", this.$refs.child);
},
},
};
</script>
Communicate across components
provide and inject
Provide and inject can implement deep component communication. The top-level component only needs to define provide, and the bottom-level component accepts data through inject
top level component
// 父组件
provide(){
msg:'hello Children'
},
// 子组件
inject: ['msg']
created () {
console.log(this.msg) // hello Children
}
router
If a group will change the address bar, all groups listening to the address bar will make corresponding changes,
//监听路由变化
watch:{
$route(to,from) {
console.log(to,from);
}
}
vuex
Vuex is too bulky and is generally not recommended for use in small projects. Small projects can use store or eventbus instead of vuex. Vuex is essentially a data warehouse. I won’t go into too much detail here, just dig a hole and talk about it next time.
store mode
The store mode is actually an ordinary js module. Each component can import the module and put the data into the data. At this time, the store is responsive.
// 导出一个 store.js模块
export default {
userInfo:{...},
loginInfo:{...}
}
// A子组件导入 store模块
import store from './store.js'
export default {
name:'Acompon',
data(){
userInfo: store.userInfo
}
}
// B子组件导入 store模块
import store from './store.js'
export default {
name:'Bcompon',
data(){
loginInfo: store.loginInfo
}
}
tip: The disadvantage of store mode is that it cannot track data changes, because all components can change data
eventbus
The eventbus event bus is equivalent to a bridge. As an event center for all groups, all components can register events in eventbus, and can also monitor events.
// 定义一个eventbus模块
import Vue from 'vue'
export const EventBus = new Vue()
// 在main.js里导入该模块并挂载到全局
// main.js
import eventbus from './eventbus.js'
Vue.prototype.$eventBus = eventbus
所有子组件向eventbus里组 注册 或者 监听 事件
// 组件A 通过 $emit()注册事件
sendMsg() {
this.$eventBus.$emit("aMsg", 'from A');
}
// 组件B 通过 $on 监听事件
this.$eventBus.$on("aMsg", (msg) => {
// A发送来的消息
console.log(msg) // from A
})
// 通过 $off() 可以关闭事件
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。