• 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
          })
        },
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
      • 45
      • 46
      • 47
      • 48
      • 49
      • 50
      • 51
      • 52
      • 53
      • 54
      • 55

      在项目中的 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: {}
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10

      可以看到 Mixin 非常简单,主要包含了一个 Vue 组件的常见的逻辑结构。

    局部混入

    
    
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 上段代码中引入 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')
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11

      虽然全局引入很方便,但是不推荐使用。

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

    选项合并

    • mixin 中定义的属性或方法的名称与组件中定义的名称没有冲突。
    • 这里的冲突主要分为以下几种情况:
      • 生命周期函数
        • 确切来说不算冲突,因为生命周期函数的名称都是固定的,默认的合并策略:先执行 mixin 中生命周期函数中的代码,然后执行组件内部的代码。
      • data 数据冲突
        • 当 mixin 中的 data 数据与组件中的 data 数据冲突时,组件中的 data 数据会覆盖 mixin 中的数据
      • 方法冲突
        • 这种冲突很容易遇到,因为协作开发中,很容易命名相同。当方法发生冲突时,默认调用的是组件的方法

    Mixin 的优缺点

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

    优点

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

    缺点

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

    总结

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

  • 相关阅读:
    为云环境开发的 RADIUS 认证服务
    Gitlab API调用给每个人生成一个token,操作api
    [SCTF 2021]rceme
    Jmeter上传文件的文件名中文乱码解决方法
    Activiti学习(一)之工作流的介绍和使用
    Three.js加载360全景图片/视频
    新型氢氧型N,N,N′,N′-四甲基-N″-丁基胍离子液体[BTMG]OH离子液体
    Java IO流(下)
    学习Rust适合写什么练手项目?【云驻共创】
    基于JavaWEB+MySQL的二手闲置物品交易网站系统
  • 原文地址:https://blog.csdn.net/McapricornZ/article/details/127475044