Close read Vue official documentation series πŸŽ‰


Convert values using Computed.

  • Non-asynchronous value conversion based on data change listening is perfectly acceptablecomputedTo take the place ofwatch.
  • If the converted value will be used in more than one place, you should use computed properties, which have caching properties.
  • If caching is not required, you can consider using methods to transform directly in the template, because a change in reactive data must trigger a re-rendering of the template, and the method can then be re-executed.
<template>
  <div>
    <p><input type="text" v-model="str" /></p>
    <p>
      <b>{{ btoa }}</b>
    </p>
    <p>repeated:{{ btoa }}</p>
  </div>
</template>
<script>
export default {
  name: "HelloWorld".data() {
    return {
      str: "hello world!"}; },computed: {
    btoa() {
      return window.btoa(this.str); ,}}};</script>
Copy the code

Because the template does not have access to the window object, you need to call the window.btoa method with the calculated property. If you use an external imported method, you can simplify the code even more without having to convert the data multiple times:

<template>
  <div>
    <p><input type="text" v-model="str" /></p>
    <p>
      <b>{{ changeStr(str) }}</b>
    </p>
  </div>
</template>
<script>
import {myBtoA} from './myBtoA.js';
import {ref} from '@vue/composition-api';
export default defineComponent({
  name: "UseComputed".setup(){
    const {value:str, changeStr:change} = myBtoA();
    return {
       str,
       changeStr
    }
  });
};
</script>
Copy the code

The most common requirement scenario is to take props outside the component and convert it to data inside the component

<script>
export default defineComponent({
   name:"UseComputed".props: ["propData"].setup(props){
      const data = computed(() = >props.propData);
      return{data}; }})</script>
Copy the code

Of course, there are many ways to do this, such as watch listening for commands to perform conversions, or event-based callbacks, but none is as elegant as computed.

By extension, what if you need to add security for data changes at this point? Solutions:

  1. willv-modelSplit it into value and input and apply it specifically for input eventsdebounceMethod to make data changes to prevent shaking.
  2. Custom instruction, hijackinginputThe event is shaken.
  3. usev-model.lazyMake a small amount of optimization.

usecomputedConditional filtering is performed.

{
 computed: {
    filterData() {
      let dataSource = this.dataSource;
      let searchFilter = this.searchFilter;
      let sortKey = this.sortKey;

      if (searchFilter) {
        dataSource = dataSource.filter((record) = > {
          return Object.keys(record).some((key) = > {
            return String(record[key]).toLowerCase().indexOf(searchFilter) > -1;
          });
        });
      }

      if (sortFiter) {
        dataSource = dataSource.sort((a, b) = > {
          const first = a[sortKey];
          const last = b[sortKey];
          return a === b ? 0 : a > b ? 1 : -1;
        });
      }

      returndataSource; }},}Copy the code

If your data source is affected by multiple responsive conditions, running them in a computed computed approach is a good fit.

watch 与 computedIn combination with

We always emphasize that computed is used in a scenario where data is affected by multiple data, while Watch is used in a scenario where a change in data affects multiple data, but in fact, the two can be used in combination. Using computed as watch’s monitoring data can maximize their advantages.

<template>
  <div>
    <input type="text" v-model="value1" />
    <input type="radio" value="a" v-model="value2" /><input type="radio" value="b" v-model="value2" />
    <hr/>
    <button @click="download">download</button>
  </div>
</template>
<script>
export default {
  name: "HelloWorld".data() {
    return {
      value1: "".value2: "a"}; },computed: {
    filter() {
      const { value1, value2 } = this;
      return{ value1, value2 }; }},methods: {
    download() {
      console.log("download".this.filter);
    },
    getData() {
      console.log("fetch data".this.filter); }},created() {
    this.$watch("filter".this.getData, { immediate: true}); }};</script>
Copy the code