The use of .sync modifier in Vue projects

Write in front

  • The technology stack of this article is based on Vue2 + ElementUi
  • In common query businesses, there is often an operation to reset query conditions. Next, we will use this as a background to help you understand how the .sync modifier is used in projects.

Common parent-child component communication chestnuts

1. Write a subcomponent for drop-down data

  • Just name it here OptionsSelect
  • The el-select drop-down box is used, the selected data is monitored through the change event, and the selected value is exposed to the parent component using $emit
<template>
  <el-select v-model="mode" placeholder="Please select" @change="handleChange">
    <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value">
    </el-option>
  </el-select>
</template>
<script>
export default {<!-- -->
  props: {<!-- -->
    modelVal: {<!-- -->
      //Receive external incoming values for data echo
      type: String,
      default: null
    }
  },
  data() {<!-- -->
    return {<!-- -->
      mode: null,
      options: [
        {<!-- -->
          label: 'Polaris is super handsome',
          value: 'bjx'
        },
        {<!-- -->
          label: 'Dabai',
          value: 'db'
        }
      ]
    };
  },
  mounted() {<!-- -->
    //Data assignment, if there is a value
    this.mode = this.modelVal;
  },
  methods: {<!-- -->
    handleChange(val) {<!-- -->
      this.$emit('changeVal', val);
    }
  }
};
</script>

2. Write a parent component and introduce sub-components for use

  • The parent component code is as follows
<template>
  <div class="about">
    <h1>This is an about page</h1>
    <!-- <svg-icon name="top"></svg-icon> -->
    <div style="margin-bottom: 15px">
      value: {<!-- -->{<!-- --> value }}---- <el-button type="primary" @click="handleClick">Reset selected< /el-button>
    </div>
    <span>Select a friend:</span><OptionsSelect @changeVal="handleChangeVal"></OptionsSelect>
  </div>
</template>
<script>
import OptionsSelect from '@/components/OptionsSelect.vue';
export default {<!-- -->
  components: {<!-- -->
    OptionsSelect
  },
  data() {<!-- -->
    return {<!-- -->
      value: null
    };
  },
  methods: {<!-- -->
    handleChangeVal(val) {<!-- -->
      this.value = val; },
    handleClick() {<!-- -->
      this.value = null;
    }
  }
};
</script>
<style scoped>
.about {<!-- -->
  padding: 20px;
}
</style>

3. Page effect

  • The page effect is as shown below. The left side of the button displays the two-way binding value of the page for easy observation.
  • At this time, we click the drop-down box to select a piece of data, and click the reset button after selection.
  • Based on the existing logic, we cleared the two-way bound value value in the parent component, but we hope to clear the content of the drop-down box as well; it is also very simple to achieve this. First, through ref attribute gets the component instance, and the child component provides a method to clear the content; or the parent component passes an attribute to the child component through v-bind, which is triggered when the button is clicked. Its properties change, and the subcomponent performs clearing operations by monitoring this property change.
  • Based on the above analysis, it is processed in the ref way.
  • Go back to the page to check the effect. After selecting an item, click the reset button. Now the effect is as we expected.
  • This is a common solution, but the next introduction is to achieve the current effect through the .sync modifier. I personally think it will be more concise than the current processing method, and it can also reduce some parts. Logic processing of parent components

Use the sync modifier

  • According to Guangfang, the core processing is that the original this.$emit('xxx', xxx) needs to be rewritten into this.$emit('update:xxx', xxx )
  • The parent component no longer needs to listen to event names to customize functions for parameter processing, but can bind attributes through xxx.sync.
  • Chestnuts are as follows:

1. Subcomponent

  • The two-way binding attribute of the child component is mode, and the modelVal attribute passed in by the parent component is monitored through watch, and its value is assigned to mode
  • The reason why modelVal is not used for direct binding is: we need to ensure a one-way data flow to avoid the parent component directly modifying the data in the child component, thereby causing data confusion; in the case of ensuring single-select data flow Next, problems that arise can be easily located.
<template>
  <el-select v-model="mode" placeholder="Please select" @change="handleChange">
    <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value">
    </el-option>
  </el-select>
</template>
<script>
export default {<!-- -->
  props: {<!-- -->
    modelVal: {<!-- -->
      //Receive external incoming values for data echo
      type: String,
      default: null
    }
  },
  data() {<!-- -->
    return {<!-- -->
      mode: null,
      options: [
        {<!-- -->
          label: 'Polaris is super handsome',
          value: 'bjx'
        },
        {<!-- -->
          label: 'Dabai',
          value: 'db'
        }
      ]
    };
  },
  mounted() {<!-- -->
    //Data assignment, if there is a value
    this.mode = this.modelVal;
  },
  methods: {<!-- -->
    handleChange(val) {<!-- -->
      this.$emit('update:modelVal', val);
    }
  },
  computed: {<!-- -->
    modelValChange() {<!-- -->
      return this.modelVal;
    }
  },
  watch: {<!-- -->
    // Monitor the incoming value and assign it to the mode attribute
    modelValChange(val) {<!-- -->
      this.mode = val;
    }
  }
};
</script>

2. Parent component, introduce child component

  • After clicking the filter box to select any piece of data, click Reset to see that in addition to the two-way binding data of the parent component being cleared, the content of the child component filter box is also cleared.
  • Writing becomes more concise
<template>
  <div class="about">
    <h1>This is an about page</h1>
    <!-- <svg-icon name="top"></svg-icon> -->
    <div style="margin-bottom: 15px">
      value: {<!-- -->{<!-- --> value }}---- <el-button type="primary" @click="handleClick">Reset selected< /el-button>
    </div>
    <span>Choose a friend:</span>
    <OptionsSelect :modelVal.sync="value"></OptionsSelect>
  </div>
</template>
<script>
import OptionsSelect from '@/components/OptionsSelect.vue';
export default {<!-- -->
  components: {<!-- -->
    OptionsSelect
  },
  data() {<!-- -->
    return {<!-- -->
      value: null
    };
  },
  methods: {<!-- -->
    handleChangeVal(val) {<!-- -->
      this.value = val;
    },
    handleClick() {<!-- -->
      this.value = null;
    }
  }
};
</script>
<style scoped>
.about {<!-- -->
  padding: 20px;
}
</style>

3. Page effect

  • Select a piece of data and click Reset to get it right in one step (at the same time, the data bound to the parent and child components is cleared)

Simple summary

  • Using sync can make it more concise when the parent component wants to process some of the internal states of the child component. There is no need to use the processing methods in the first example.
  • And there is no need to write logic code in the parent component to clear the state of the child component.
  • Regarding the explanation of the .sync modifier, the official website also writes it very clearly. You can understand it yourself.

Write at the end

  • The above is a case analysis introduction to the use of sync modifier based on query reset conditions. I hope this article can inspire and help you.
  • Thank you for being so good and reading my article?