This is the third day of my participation in the August Text Challenge.More challenges in August

background

I have studied the communication mechanism between Vue components, including parent/child component communication (PROPS /$EMIT), central event bus $emit/$ON,Vuex state management, etc. Not much practice, maybe not a very deep understanding. This is an example of how to use the props/$emit communication mechanism.

Requirements describe

The table component displays data, and the drawer component is used to operate pop-ups. The drawer component is required to be packaged into a sub-component. Changes in variables that control the opening and closing of drawer components in the same component can be directly used, but when packaged as child components, this state variable needs to be synchronized between parent and child components.

Implementation approach

1. The parent component


<template>
     <div>
      <el-table :data="tableData" row-key="C0" border>
        <el-table-column prop="C0" label="C0" align="center"></el-table-column>
        <el-table-column prop="C1" label="C1" align="center"></el-table-column>
        <el-table-column prop="C2" label="C2" align="center"></el-table-column>
        <el-table-column prop="" label="Operation" align="center">
          <template slot-scope="scope">
            <el-button type="primary" @click="handleEdit(scope.row)">The editor</el-button>
          </template>
        </el-table-column>
      </el-table>
      <editComponent
        v-model="drawerShow"
        :state="activeRow"
        @close="loadData"
      ></editComponent>
     </div>
</template>
Copy the code

The parent component passes the current row to the child component through state.

Handle the close event and execute the appropriate callback.

Here is a trick to control the behavior of the child components by bidirectionally binding the drawerShow properties to the V-Model.

The V-Model of the component can be customized

2.2.0 + added

By default, a V-Model on a component makes use of a prop named Value and an event named input, but input controls of types like checkboxes, checkboxes, and so on May use value attributes for different purposes. The Model option can be used to avoid such conflicts:

2. The child component


<template>
    <div>
      <el-drawer
      :visible.sync="drawerShow"
      custom-class="demo-drawer"
      destroy-on-close
    >
      <el-row slot="title">
        <h1>The editor</h1>
      </el-row>
      <div class="demo-drawer__content">
        <div class="demo-drawer__footer">
          <el-button @click="cancelForm('lecturerEditForm')">Take away</el-button>
          <el-button type="primary" @click="">determine</el-button>
        </div>
      </div>
    </el-drawer>
  </div>
</template>

<script>
  export default {
    components: {},
    model: {
      prop: 'show'.event: 'change',},props: {
      show: {
        type: Boolean.default: false,},state: {
        type: Object.default: null,}},data() {
      return{}; },computed: {
      drawerShow: {
        get() {
          return this.show;
        },
        set(value) {
          this.$emit('close', value); }},},watch: {
      show(value) {
        if (value) {
          // Open the drawer
        } else {
          // Close the drawer}}},created() {},
    methods: {
      cancelForm() {
        this.drawerShow = false; ,}}};</script>

<style lang="scss" scoped>
</style>
Copy the code

As mentioned above, we customized the v-Model of the component and took advantage of a prop named Show and an event named change. The prop that controls the state passed in from the outside is show, and the variable handleClose used to control the state in the child component is a property calculated based on the show value, and listeners are set in the child component to listen for changes in the show value.

One thing to note is that the event listeners in the parent component that are triggered in the child component should be registered on the child component tag. They are initially registered on the external tag of the parent component and do not capture the corresponding event.

In the child component, it is the calculation property handleClose that controls the opening and closing of the component, but this calculation property is based on Prop Show, which gets the information passed in externally.

Why not just use prop instead of adding a layer to calculate properties? Because prop is not reactive, we need to do something when the state changes, so we use a combination of computed properties and listeners to achieve reactive.

This way, we can set in the listener what we need to do when the drawer opens and closes, while in the child component, the close event can be actively triggered whenever the drawer is closed and drawerShow is given a new value. When the parent component receives a close event (the parent component has a listener for the close event set), the appropriate callback is executed. This synchronizes the state in the parent and child components.