Vue 面试题常问:了解 Vue 中的 Mixin 吗?

简介: 混入(mixin)提供了一种非常灵活的方式,来分发 Vue 组件中的可复用功能。一个混入对象可以包含任意组件选项。当组件使用混入对象时,所有混入对象的选项将被“混合”进入该组件本身的选项。

Vue 面试题常问:了解 Vue 中的 Mixin 吗?


什么是 Mixin?


  • 官方解释


混入(mixin)提供了一种非常灵活的方式,来分发 Vue 组件中的可复用功能。一个混入对象可以包含任意组件选项。当组件使用混入对象时,所有混入对象的选项将被“混合”进入该组件本身的选项。


  • 自己理解


将组件的公共逻辑或者配置提取出来,哪个组件需要用到时,直接将提取的这部分混入到组件内部即可。这样既可以减少代码冗杂度,也可以让后期维护起来更加容易。


需要注意的是:提取的是逻辑或者配置,而不是 HTML 代码和 CSS 代码。可以将 Mixin 简单理解为组件中的组件,Vue 组件化让代码复用性更高,那么组件与组件之间还有重复部分,就可以用 Mixin 再抽离一遍。


  • 举例


当我们在使用 Vue 开发后台管理系统的时候,一定会使用到表格(用户数据,订单数据等等)来对数据进行展示,但是每一个表格的数据都需要向后台发送请求来获取表格的数据,而发送请求的逻辑代码如果每一个 Table 页面都去写一下的话,重复的代码就会有很多,这是我们就可以将发送请求获取数据的逻辑代码抽离出来,放到 Mixin 中,从而混入到需要获取数据的 Table 页面中。

 export const TableListMixin = {
   data() {
     return {
       // 数据源
       dataSource: [],
       // table加载状态
       loading: false,
       // 分页参数
       ipagination: {
         current: 1,
         pageSize: 10,
         currentTotal: 0,
         pageSizeOptions: ['10', '20', '30'],
         showTotal: (total, range) => {
           return range[0] + "-" + range[1] + " 共" + total + "条"
         },
         showQuickJumper: true,
         showSizeChanger: true,
         total: 0,
         onShowSizeChange: (current, pageSize) => this.handleSizeChange(current, pageSize),
       },
     }
   },
   loadData(arg) {
     let that = this
     if (!this.url.list) {
       this.$message.error("请设置url.list属性!")
       return
     }
     //加载数据 若传入参数1则加载第一页的内容
     if (arg === 1) {
       this.ipagination.current = 1;
     }
     var params = this.getQueryParams();//查询条件
     // getQueryParams() 是获取查询条件的方法,此处就不具体列出了
     this.loading = true;
     if (this.isNoPageTotal) {
       params.pageSize = 99999999
     }
     getAction(this.url.list, params).then((res) => {
       if (res.success) {
         this.dataSource = res.result.records || res.result;
         if (res.result.total) {
           this.ipagination.total = res.result.total;
         } else {
           this.ipagination.total = 0;
         }
       } else {
         this.$message.warning(res.message)
       }
     }).finally(() => {
       this.loading = false
     })
   },
 }
  • 在项目中的 Mixin 中添加了上述代码,我们就可以在 Table 页面获取数据的时候直接混入,并在 data 中添加一个对象:url: { list: '' } 对象,list 的值对应需要调用的接口地址即可。一套代码适用所有 Table 页面,是不是很方便?


Mixin 和 Vuex 的区别?


  • Mixin 具有抽离公共部分的作用。在 Vue 中,Vuex 状态管理似乎也有这样的功能,Vuex 也是将组件之间可能共享的数据抽离出来。两者看似一样,实则还是有细微的区别,区别如下:
  • Vuex 公共状态管理,如果在一个组件中更改了 Vuex 中的某个数据,那么其他所有引用了 Vuex 中该数据的组件也会跟着变化。
  • Mixin 中的数据和方法都是独立的,组件之间使用后是互相不影响的。


如何使用?


Mixin 定义


  • 定义 Mixin 也非常简单,它就是一个对象而已,只不过这个对象里面可以包含 Vue 组件中的一些常见配置,如 datamethodscreated 等等。
  • 在项目的 src 目录下新建 mixin 文件夹,然后新建 index.js 文件,该文件存放 Mixin 代码。
 // src/mixin/index.js
 export const mixins = {
     data() {
         return{}
     },
     computed: {},
     created() {},
     mounted() {},
     methods: {}
 }
  • 可以看到 Mixin 非常简单,主要包含了一个 Vue 组件的常见的逻辑结构。


局部混入

 <template>
   <div>
     App 组件
   </div>
 </template>
 ​
 <script>
 import { mixins } from 'src/mixin/index.js'
 export default {
   name: "App",
   mixins: [mixins],
   components: {},
   data() {},
   methods: {}
 }
 </script>
 ​
 <style>
 </style>
  • 上段代码中引入 Mixin 的方法也非常简单,直接使用 Vue 提供的 mixins: [mixins]


  • 总结


  • mixin 中的生命周期函数会和组件的生命周期函数一起合并执行。
  • mixin 中的 data 数据在组件中也可以使用。
  • mixin 中的方法在组件内部可以直接调用。
  • 生命周期函数合并后执行顺序:先执行 mixin 中的,后执行组件的。


  • 问题:一个组件中改动了 mixin 中的数据,另一个引用了 mixin 的组件会受影响吗?


  • 答案是不会的


全局混入


  • 上一点使用 mixin 是在需要的时候在组件中引入,其实也可以在全局先把它注册好,这样就可以在任何组件中直接使用了。
 // main.js
 import Vue from 'vue'
 import App from './App'
 import { mixins } from './mixin/index.js'
 Vue.mixin(mixins)
 ​
 Vue.config.productionTip = false
 ​
 new Vue({
   render: (h) => h(App),
 }).$mount('#app')
  • 虽然全局引入很方便,但是不推荐使用。


请谨慎使用全局混入,因为它会影响每个单独创建的 Vue 实例(包括第三方组件)。大多数情况下,只应当应用于自定义选项,就像上面的示例一样。推荐将其作为插件发布,以避免重复应用混入。


选项合并


  • mixin 中定义的属性或方法的名称与组件中定义的名称没有冲突。
  • 这里的冲突主要分为以下几种情况:


  • 生命周期函数


  • 确切来说不算冲突,因为生命周期函数的名称都是固定的,默认的合并策略:先执行 mixin 中生命周期函数中的代码,然后执行组件内部的代码。


  • data 数据冲突


  • 当 mixin 中的 data 数据与组件中的 data 数据冲突时,组件中的 data 数据会覆盖 mixin 中的数据


  • 方法冲突


  • 这种冲突很容易遇到,因为协作开发中,很容易命名相同。当方法发生冲突时,默认调用的是组件的方法


Mixin 的优缺点


  • Mixin 虽然好处多多,但是凡是都有两面性。


优点


  • 提高代码复用性
  • 无需传递状态
  • 维护方便,只需要修改一个地方即可


缺点

  • 命名冲突
  • 滥用的话后期很难维护
  • 不好追溯源,排查问题稍显麻烦
  • 不能轻易的重复代码

总结

Mixin 提供了方便的同时也带来了灾难,所以很多时候不建议滥用它,但是在有些场景下使用它又非常合适,这就要自己去判断了。所以在很多时候需要考虑用公共组件还是使用 Mixin 。

相关文章
|
2月前
|
JavaScript 前端开发 API
vue面试题目汇总
vue面试题目汇总
38 4
|
2月前
|
缓存 JavaScript 前端开发
Vue常见面试题 标准答案汇总一
Vue常见面试题 标准答案汇总一
51 1
|
3月前
|
JavaScript
Vue中的mixin和extend有什么区别?
Vue中的mixin和extend有什么区别?
35 0
|
3月前
|
监控 JavaScript 前端开发
vue基础面试题10问
vue基础面试题10问
40 0
|
3月前
|
JavaScript 前端开发
提高Vue开发效率的必杀技——掌握mixin代码复用技术!
Vue 进阶系列教程将在本号持续发布,一起查漏补缺学个痛快!若您有遇到其它相关问题,非常欢迎在评论中留言讨论,达到帮助更多人的目的。若感本文对您有所帮助请点个赞吧!
|
4月前
|
设计模式 JavaScript 前端开发
探索 Vue Mixin 的世界:如何轻松复用代码并提高项目性能(下)
探索 Vue Mixin 的世界:如何轻松复用代码并提高项目性能(下)
|
4月前
|
设计模式 JavaScript
探索 Vue Mixin 的世界:如何轻松复用代码并提高项目性能(上)
探索 Vue Mixin 的世界:如何轻松复用代码并提高项目性能(上)
探索 Vue Mixin 的世界:如何轻松复用代码并提高项目性能(上)
|
4月前
|
人工智能 缓存 JavaScript
【利用AI刷面试题】AI:十道Vue面试题巩固一下知识
【利用AI刷面试题】AI:十道Vue面试题巩固一下知识
|
4月前
|
存储 JavaScript 安全
Vue基础面试题题目一
Vue基础面试题题目一
28 0
|
4月前
|
JavaScript 数据安全/隐私保护 开发者
常见的vue面试中的proxy和object.defineProperty的区别
常见的vue面试中的proxy和object.defineProperty的区别