vue中的mixins的介绍和使用

468 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第13天,点击查看活动详情

混入 mixins

介绍

当我们的项目越来越大,我们会发现组件之间可能存在很多相似的功能,你在一遍又一遍的复制粘贴相同的代码段(data,method,watch、mounted等),如果我们在每个组件中去重复定义这些属性和方法会使得项目出现代码 冗余并提高了维护难度,针对这种情况官方提供了Mixins特性

一、什么是Mixins?

mixins(混入),官方的描述是一种分发 Vue 组件中可复用功能的非常灵活的方式,mixins是一个js对象,它可以包含我们组件中script项中的任意功能选项,如data、components、methods 、created、computed等等。我们只要将共用的功能以对象的方式传入 mixins选项中,当组件使用 mixins对象时所有mixins对象的选项都将被混入该组件本身的选项中来,这样就可以提高代码的重用性,使你的代码保持干净和易于维护。

二、什么时候使用Mixins?

当我们存在多个组件中的数据或者功能很相近时,我们就可以利用mixins将公共部分提取出来,通过 mixins封装的函数,组件调用他们是不会改变函数作用域外部的。

注意:

​ 不同组件混入之后,会生成不同的实例,数据会相互隔离,互不影响

三、如何创建Mixins?

在src目录下创建一个mixins文件夹,文件夹下新建一个Mixins.js文件。前面我们说了mixins是一个js对象,所以应该以对象的形式来定义Mixins,在对象中我们可以和vue组件一样来定义我们的data、components、methods 、created、computed等属性,并通过export导出该对象
实例

export default {
    created() {
        this.mixins()
    },
    methods: {
        mixins() {
            console.log('我来自 mixins! 文件')
        }
    }
}

index.vue

<template>
  <div>Mixins</div>
</template>

<script>
import Mixins from "./Mixins";
export default {
     mixins: [Mixins],
  data() {
    return {};
  },
  mounted() {

  },
  methods: {
      
  },
};
</script>

<style>
</style>

运行

捕获1231.PNG

合并内容

1. data对象

data对象会进行递归合并,如果有冲突,会使用组件中的数据

Mixins.js

export default {
    data() {
        return {
            mixinData: '浪漫至死不渝'
        }
    },
    created() {
        this.mixins()
    },
    methods: {
        mixins() {
            console.log('我来自 mixins! 文件')
        }
    }
}

index.vue

<template>
  <div>Mixins</div>
</template>

<script>
import Mixins from "./Mixins";
export default {
     mixins: [Mixins],
  data() {
    return {
        mixinData:'理想主义的花'
    };
  },
  mounted() {
      console.log(this.$data);
  },

  methods: {
      
      
  },
};
</script>

<style>
</style>

运行

4.PNG

2. 钩子函数

钩子函数会被合并起来执行,先执行混入的钩子函数,再执行组件对应的钩子函数

Mixins.js

export default {
    data() {
        return {
            mixinData: '浪漫至死不渝'
        }
    },
    created() {
        this.mixins()
    },
    mounted() {
        this.mountMix()
    },
    methods: {
        mixins() {
            console.log('我来自 mixins! 文件 created')
        },
        mountMix() {
            console.log('我来自 mixins! 文件 mounted')
        }

    }
}

index.vue

<template>
  <div>Mixins</div>
</template>

<script>
import Mixins from "./Mixins";
export default {
     mixins: [Mixins],
  data() {
    return {
        mixinData:'理想主义的花'
    };
  },
  created(){
      this.indexCreat()
  },
  mounted() {
    //   console.log(this.$data);
      this.indexMount()
  },

  methods: {
       indexCreat() {
            console.log('我来自 index.vue! 组件 created')
        },
        indexMount() {
            console.log('我来自 index.vue! 组件 mounted')
        }
      
  },
};
</script>

<style>
</style>

运行

捕获3121.PNG

3. 值为对象的选项,例如method,components,directives等

将会被合并成一个大对象,如果有冲入,以组件中的选项为准

Mixins.js

export default {
    data() {
        return {
            mixinData: '浪漫至死不渝'
        }
    },
    created() {
        // this.mixins()
        // this.say()
    },
    mounted() {
        // this.mountMix()
    },
    methods: {
        // mixins() {
        //     console.log('我来自 mixins! 文件 created')
        // },
        // mountMix() {
        //     console.log('我来自 mixins! 文件 mounted')
        // }
        say() {
            console.log('say hi~');
        },
        eat() {
            console.log('eat apple~');
        }

    }
}

index.vue

<template>
  <div>Mixins</div>
</template>

<script>
import Mixins from "./Mixins";
export default {
     mixins: [Mixins],
  data() {
    return {
        mixinData:'理想主义的花'
    };
  },
  created(){
    //   this.indexCreat()
  },
  mounted() {
    //   console.log(this.$data);
    //   this.indexMount()
    this.say()
    this.eat()
  },

  methods: {
    //    indexCreat() {
    //         console.log('我来自 index.vue! 组件 created')
    //     },
    //     indexMount() {
    //         console.log('我来自 index.vue! 组件 mounted')
    //     }
    eat(){
        console.log('eat pitaya~');
    }
      
  },
};
</script>

<style>
</style>

运行

捕获.PNG

结果:

  • say方法没有冲突,使用mixins.js中的
  • eat方法有冲突,使用index.vue组件中的

4. 全局混入

混入分为组件混入和全局混入

  • 组件混入:每个组件单独按需进行混入
  • 全局混入:一旦进行全局混入,它将影响每一个之后创建的 Vue 实例(包括第三方组件),所以需要慎重

Mixins.js

export default {
  data () {
    return {
      // Mixins中定义的变量
      message: 'hello',
    }
  },
  created () {
    console.log('我是 mixins')
  }
}

main.js

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import Mixins from '@/views/mixin/Mixins'

Vue.config.productionTip = false

// 全局混入
Vue.mixin(Mixins)

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

index.vue

<template>
  <div>Mixins</div>
</template>

<script>
export default {
  data() {
    return {};
  },
  mounted() {

  },
  methods: {
      
  },
};
</script>

<style>
</style>

结果:
之后每个创建的组件都混入了这些选项,导致访问一个路由组件,其中创建的每个组件都打印了created的处理

5. 扩展

1. 与vuex的区别

vuex:用来做状态管理,里面定义的变量每个组件都可以查看和修改,共享一分数据,一般只能存储属性和方法,不能存放钩子函数

mixins:可以用来定义公用变量、方法,总的钩子函数等。在组件混入之后,每个组件各自维护一份变量,相互隔离

2. 与公共组件的区别

组件:在父组件中引入公共组件之后,相当于引入了一个公共子组件,通过props等方式进行组件传值,但本质上是相互独立的

mixins:在引入组件之后,于组件中的对象和方法进行合并,相当于扩展了父组件的对象和方法,可以理解为形成了一个新的组件