vue2 last stubbornness

How to exclude the listening of some attributes when watch listens to an object

The following code is to re request data when params changes, regardless of the change of a, b, c and d attributes

data() {
    return {
      params: {
        a: 1,
        b: 2,
        c: 3,
        d: 4
      },
    };
  },
watch: {
    params: {
      deep: true,
      handler() {
        this.getList;
      },
    },
  }

But what if I just want to re request when a and b change and not re request when c and d change?

mounted() {
    Object.keys(this.params)
      .filter((_) => !["c", "d"].includes(_)) // Exclude listening to c and d attributes
      .forEach((_) => {
        this.$watch((vm) => vm.params[_], handler, {
          deep: true,
        });
      });
  },
data() {
    return {
      params: {
        a: 1,
        b: 2,
        c: 3,
        d: 4
      },
    };
  },
watch: {
    params: {
      deep: true,
      handler() {
        this.getList;
      },
    },
  }

How does computed implement parameter passing?

// html
<div>{{ total(3) }}

// js
computed: {
    total() {
      return function(n) {
          return n * this.num
         }
    },
  }

Use of hook in vue

  • Used in the same component
    This is the way we often use timers
export default{
  data(){
    timer:null  
  },
  mounted(){
      this.timer = setInterval(()=>{
      //Specific implementation contents
      console.log('1');
    },1000);
  }
  beforeDestory(){
    clearInterval(this.timer);
    this.timer = null;
  }
}

The disadvantage of the above method is that you have to define a timer variable globally. You can use hook to do this:

export default{
  methods:{
    fn(){
      let timer = setInterval(()=>{
        //Specific execution code
        console.log('1');
      },1000);
      this.$once('hook:beforeDestroy',()=>{
        clearInterval(timer);
        timer = null;
      })
    }
  }
}
  • Parent child component usage
    If the child component needs to trigger a function of the parent component when mounted, it will be written as follows:
//Parent component
<rl-child @childMounted="childMountedHandle"
/>
method () {
  childMountedHandle() {
  // do something...
  }
},

// Subcomponents
mounted () {
  this.$emit('childMounted')
},

It is more convenient to use hook:

//Parent component
<rl-child @hook:mounted="childMountedHandle"
/>
method () {
  childMountedHandle() {
  // do something...
  }
},

Vue's el attribute and $mount priority?

new Vue({
  router,
  store,
  el: '#app',
  render: h => h(App)
}).$mount('#ggg')

This is an official figure. It can be seen that when el and $mount exist at the same time, El priority > $mount

Have dynamic instructions and parameters been used?

<template>
    ...
    <aButton @[someEvent]="handleSomeEvent()" :[someProps]="1000" />...
</template>
<script>
  ...
  data(){
    return{
      ...
      someEvent: someCondition ? "click" : "dbclick",
      someProps: someCondition ? "num" : "price"
    }
  },
  methods: {
    handleSomeEvent(){
      // handle some event
    }
  }  
</script>

How to re render the same routing components?

Developers often encounter situations where multiple routes resolve to the same Vue component. The problem is that Vue, for performance reasons, shared components will not be re rendered by default, and nothing will change if you try to switch between routes using the same components.

const routes = [
  {
    path: "/a",
    component: MyComponent
  },
  {
    path: "/b",
    component: MyComponent
  },
];

What if you still want to re render? You can use key

<template>
    <router-view :key="$route.path"></router-view>
</template>

Custom v-model

The v-model on a component will use prop named value and event named input by default, but input controls such as radio boxes and check boxes may use value attribute for different purposes. The model option can be used to avoid such conflicts:

Vue.component('base-checkbox', {
  model: {
    prop: 'checked',
    event: 'change'
  },
  props: {
    checked: Boolean
  },
  template: `
    <input
      type="checkbox"
      v-bind:checked="checked"
      v-on:change="$emit('change', $event.target.checked)"
    >
  `
})

Now when using v-model on this component:

<base-checkbox v-model="lovingVue"></base-checkbox>

The value of lovingVue here will be passed into the prop named checked. At the same time, when a change event is triggered with a new value, the property of the lovingVue will be updated.

How to get the initial state of a data in data?

In development, sometimes we need to take the initial state to calculate. for example

data() {
    return {
      num: 10
  },
mounted() {
    this.num = 1000
  },
methods: {
    howMuch() {
        // Calculate how much num has increased, which is 1000 - the initial value
        // You can use this$ options. data(). XXX to get the initial value
        console.log(1000 - this.$options.data().num)
    }
  }

Why not suggest that v-for and v-if exist at the same time

<div v-for="item in [1, 2, 3, 4, 5, 6, 7]" v-if="item !== 3">
    {{item}}
</div>

The above writing method is that v-for and v-if exist at the same time. We will traverse all seven elements first, and then judge whether they are 3 and hide them. The disadvantage is that useless 3 nodes are rendered and useless dom operations are added. It is recommended to use computed to solve this problem:

<div v-for="item in list">
    {{item}}
</div>

computed() {
    list() {
        return [1, 2, 3, 4, 5, 6, 7].filter(item => item !== 3)
    }
  }

When calculating variables, which is better, methods or calculated?

<div>
    <div>{{howMuch1()}}</div>
    <div>{{howMuch2()}}</div>
    <div>{{index}}</div>
</div>

data: () {
    return {
         index: 0
       }
     }
methods: {
    howMuch1() {
        return this.num + this.price
    }
  }
computed: {
    howMuch2() {
        return this.num + this.price
    }
  }

Computed is better because it has a cache. For example, if the index changes from 0 to 1, the view update will be triggered. At this time, the methods will be executed again, but computed will not, because the two variables num and price that computed depends on remain unchanged.

Keywords: Javascript Front-end Vue.js

Added by Replika on Wed, 26 Jan 2022 13:05:51 +0200