This is the 11th day of my participation in the August More Text Challenge. For details, see:August is more challenging

1. Introduction of mixins

Mixins are a very flexible way to distribute reusable functionality in Vue components.

A mixed object can contain any component option.

When a component uses a mixed object, all the options for the mixed object are mixed in with the component’s own options.

1.1 mixins understand

After a reference, a component opens up a separate space in the parent component to perform operations on the parent component’s props, but essentially the two are distinct and relatively independent.

Mixins, on the other hand, merge the contents of the component, such as methods such as data, and properties such as method, with the corresponding contents of the parent component after the component is introduced. After the introduction, the various property methods of the parent component are extended.

  • Simple component reference:

Parent + child –> Parent + child

  • mixins

Parent + child –> new parent

Sort of like registering a vUE public method, it can be bound to multiple components or multiple VUE object instances for use. On the other hand, similar to registering methods in prototype objects, instance objects (components or Vue instance objects) can still be overridden by methods that define the same function name, a bit like subclasses and superclasses.

2. Use mixins

  1. Define a mixin object
const testMixin = {
  data(){
    return{
      count:1,}},methods: {
    test(){
      console.log('mixin')}},beforeMount() {
    this.test()
  },
}

export{
  testMixin
}
Copy the code
  1. Mixes the mixin object into the current component
<template>
  <div class="template1">The component a</div>
</template>

<script>
import { testMixin } from '@/mixins/mixin.js'
export default {
  data() {
    return {};
  },
  mixins:[testMixin],
  methods: {},
  mounted(){}};</script>
Copy the code
  1. The effect

3. Features of mixins

3.1 Methods and Parameters Are Not shared among components

The parameter count in the mixed object

const testMixin = {
  data(){
    return{
      count:1,}},methods: {
    test(){
      console.log('mixin')}},beforeMount() {
    this.test()
  },
}

export{
  testMixin
}
Copy the code

The parameter count in component 1 performs the +1 operation

<template>
  <div class="template1">The count in the template1: {{count}}</div>
</template>

<script>
import { testMixin } from '@/mixins/mixin.js'
export default {
  data() {
    return {};
  },
  mixins:[testMixin],
  methods: {},
  mounted() {
    this.count ++; }};</script>

<style lang="stylus" scoped>
.template1{
  color : red;
}
</style>
Copy the code

The parameter Count in component 2 is not operated on

<template>
  <div class="template2">The count of template2: {{count}}</div>
</template>

<script>
import { testMixin } from '@/mixins/mixin.js'
export default {
  data() {
    return {};
  },
  mixins:[testMixin],
  methods: {},
  mounted(){}};</script>

<style lang="stylus" scoped>
.template2{
  color : blue;
}
</style>
Copy the code

Look at the count values printed in each component

As you can see, the count value in component 1 was changed, and the count value in component 2 was the original value mixed in with the object

3.2 Options with object values (methods,components, etc.) will be merged (key conflicts,components will overwrite mixed objects)

Methods mixed into objects

const testMixin = {
  data(){
    return{
      count:1,}},methods: {
    test1(){
      console.log('test1 from mixin')},test2(){
      console.log('test2 from mixin')}},beforeMount(){},}export{
  testMixin
}
Copy the code

Methods in components

<template>
  <div class="template1">The count in the template1: {{count}}</div>
</template>

<script>
import { testMixin } from '@/mixins/mixin.js'
export default {
  data() {
    return {
      count:10
    };
  },
  mixins:[testMixin],
  methods: {
    testSelf(){
      console.log('testSelf from template1')},test2(){
      console.log('test2 from template1')}},mounted() {
    this.testSelf();
    this.test1();
    this.test2(); }};</script>
Copy the code

Printing table output

3.3 Options with function values (such as Created, Mounted, etc.) are called in combination. The hook function in the mixed object is called before the hook function in the component

Interfuse console in object functions

const testMixin = {
  data(){
    return{
      count:1,}},methods: {},
  mounted() {
    console.log('mixin')}},export{
  testMixin
}
Copy the code

Console in component functions

<template>
  <div class="template1">The count in the template1: {{count}}</div>
</template>

<script>
import { testMixin } from '@/mixins/mixin.js'
export default {
  data() {
    return{}; },mixins:[testMixin],
  methods: {},
  mounted() {
    console.log('template1')}};</script>
Copy the code

Printing table output

3.3 Asynchronous requests in mixins

When the mix contains the asynchronous request function and we need to use the return value of the asynchronous request function in the component, we will not get the return value, as follows:

// mixin.js
const testMixin = {
  data(){
    return{}},methods: {
    remote(){
      new Promise((resolve,reject) = > {
        let a = 1;
        setTimeout(() = >{
          resolve(a)
        },1000)
      }).then(res= >{
        console.log(res,'mixin');
        return res
      })
    }
  },
  mounted(){},}export{
  testMixin
}
Copy the code
// test.vue
<template>
  <div class="template1">
    template1
  </div>
</template>

<script>
import { testMixin } from '@/mixins/mixin.js'
export default {
  data() {
    return {};
  },
  mixins:[testMixin],
  methods: {},
  mounted() {
    console.log(this.remote(),'template1')}};</script>
Copy the code

Solution: Do not return the result but return the asynchronous function directly

// mixin.js
const testMixin = {
  data(){
    return{}},methods: {
    async remote(){
      let result = await new Promise((resolve,reject) = > {
        let a = 1;
        setTimeout(() = >{
          resolve(a)
        },1000)})returnresult; }},mounted(){},}export{
  testMixin
}
Copy the code
// test.vue
<template>
  <div class="template1">
    template1
  </div>
</template>

<script>
import { testMixin } from '@/mixins/mixin.js'
export default {
  data() {
    return {};
  },
  mixins:[testMixin],
  methods: {},
  mounted() {
    this.remote().then(res= >{
      console.log(res,'template1')})}};</script>
Copy the code

4. To summarize

Difference with vuex:

  • Vuex: used for state management. Variables defined in vuex can be used and modified in each component. If the value of this variable is modified in any component, the value of this variable in other components will also be modified;
  • Mixins: You can define common variables that are used in each component. After being introduced into a component, the variables are independent of each other, and the changes to their values do not affect each other in the component.

And common components

  • Public component: Introducing a component in the parent component gives the child components a separate space in the parent component, and then passes values according to props, but they are essentially separate;
  • Mixins: After a component is introduced, it is merged with the objects and methods of the component. It extends the objects and methods of the parent component and can be understood as a new component.