Vue componentization

Components are reusable Vue instances

  • Components are intended for reuse
  • The component andnew Vue()Receive the same options, for exampledata,computed,watch,methodsLifecycle hooks, etc. (the only exceptions are likeelSuch root instance-specific options.

Intercomponent communication

1. Parent component –> child component

  • throughPropsPassing 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