Vue componentization
Components are reusable Vue instances
- Components are intended for reuse
- The component and
new Vue()
Receive the same options, for exampledata
,computed
,watch
,methods
Lifecycle hooks, etc. (the only exceptions are likeel
Such root instance-specific options.
Intercomponent communication
1. Parent component –> child component
- through
Props
Passing data to child components (common)
// Child component registers prop
export default {
name: 'HelloWorld'.props: {
msg: String}}// The parent component passes in the data as a custom attribute
<hello-World msg="Welcome to Your Vue.js App"/>
Copy the code
- $refs (common)
<! /> </template> < hell-world MSG ="Welcome to Your vue.js App" /> </template> <script> this.$refs.hw } </script>Copy the code
- $children(not used, resulting in too much coupling between components)
<! /> </template> <script> mounted() {// get the first component this.$children[0] } </script>Copy the code
A direct child of the current instance. Note that $children does not guarantee order and is not responsive
2. Child component –> Parent component
- Custom events (common)
// The child component invokes the built-in $emit method to fire the event
<button @click="$emit('custom-event')">click</button>
<button @click="$emit('custom-event', 'hello')">click</button>
// The parent component can listen for any event of the child component instance just as it handles native DOM events
<hello-World msg="Welcome to Your Vue.js App" @custom-event="handleEvent"/>
// Customize the value passed by the event
handleEvent(msg){
console.log('Parent component', msg);
}
Copy the code
3. Sibling components
- Through the common ancestor component
$parent
或$root
(Not commonly used, resulting in high coupling between components)
<!-- child1 -->
<template>
<button @click="handleClick">click</button>
</template>
<script>
export default {
name: "Child1",
methods: {
handleClick() {
this.$parent.$emit("msg-from-child1", "hello");
}
}
};
</script>
<!-- child2 -->
<script>
created() {
this.$parent.$on("msg-from-child1", msg => {
console.log(msg);
});
}
</script>
Copy the code
Between ancestors and descendants
provide/inject
/ / the ancestors
provide: {
foo: "bar"
}
/ / offspring
inject: ["foo"]
Copy the code
Provide and Inject are mainly used when developing high-level plug-in/component libraries. Not recommended for use in normal application code.
5. Communication between any two components
- Event bus (common)
class Bus {
constructor() {
this.callbacks = {};
}
$on(name, fn) {
this.callbacks[name] = this.callbacks[name] || [];
this.callbacks[name].push(fn);
}
$emit(name, args) {
if (this.callbacks[name]) {
this.callbacks[name].forEach(cb= > cb(args));
}
}
}
Vue.prototype.$bus = new Bus();
/ / or
Vue.prototype.$bus = new Vue();
Copy the code
Vuex
(common)
Slot slot.
Function Distribution Content
1. Anonymous slot
<! -- CustomButton.vue -->
<! -- Subcomponent -->
<button type="submit">
<! -- Anonymous slot -->
<slot></slot>
<! -- Backup content -->
<! -- <slot>Submit</slot>-->
</button>
<! -- Parent component -->
<custom-button>save</custom-button>
Copy the code
2. Named slot
<! -- CustomCard.vue -->
<! -- Subcomponent -->
<template>
<div>
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
</template>
<! -- Parent component -->
<custom-card>
<template v-slot:header>
<h1>Header Slot content</h1>
</template>
<template>
<p>The contents of the default slot</p>
</template>
<template v-slot:footer>
<div>The contents of the footer slot</div>
</template>
</custom-card>
Copy the code
3. Scope slot
Everything in the parent template is compiled in the parent scope; Everything in a subtemplate is compiled in a subscope.
Sometimes it is useful to give slot content access to data that is only available in child components
<! -- SlotComp.vue -->
<! -- Subcomponent -->
<div>
<slot :user="user"></slot>
</div>
<! -- Parent component -->
<slot-comp v-slot="slotProps">{{slotProps.user}}</slot-comp>
<slot-comp v-slot="{user}">{{user}}</slot-comp>
Copy the code