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
在 Vue 中处理组件选项与 Mixin 选项冲突的详细解决方案
【10月更文挑战第18天】通过以上的分析和探讨,相信你对在 Vue 中使用 Mixin 时遇到组件选项与 Mixin 选项冲突的解决方法有了更深入的理解。在实际开发中,要根据具体情况灵活选择合适的解决方案,以确保代码的质量和可维护性。
94 7
|
4月前
|
JavaScript 前端开发 应用服务中间件
【Vue面试题三十】、vue项目本地开发完成后部署到服务器后报404是什么原因呢?
这篇文章分析了Vue项目在服务器部署后出现404错误的原因,主要是由于history路由模式下服务器缺少对单页应用的支持,并提供了通过修改nginx配置使用`try_files`指令重定向所有请求到`index.html`的解决方案。
【Vue面试题三十】、vue项目本地开发完成后部署到服务器后报404是什么原因呢?
|
4月前
|
JavaScript 前端开发
【Vue面试题二十五】、你了解axios的原理吗?有看过它的源码吗?
这篇文章主要讨论了axios的使用、原理以及源码分析。 文章中首先回顾了axios的基本用法,包括发送请求、请求拦截器和响应拦截器的使用,以及如何取消请求。接着,作者实现了一个简易版的axios,包括构造函数、请求方法、拦截器的实现等。最后,文章对axios的源码进行了分析,包括目录结构、核心文件axios.js的内容,以及axios实例化过程中的配置合并、拦截器的使用等。
【Vue面试题二十五】、你了解axios的原理吗?有看过它的源码吗?
|
4月前
|
JavaScript 前端开发 数据处理
【Vue面试题二十八】、vue要做权限管理该怎么做?如果控制到按钮级别的权限怎么做?
这篇文章讨论了Vue中实现权限管理的策略,包括接口权限、路由权限、菜单权限和按钮权限的控制方法,并提供了不同的实现方案及代码示例,以确保用户只能访问被授权的资源。
【Vue面试题二十八】、vue要做权限管理该怎么做?如果控制到按钮级别的权限怎么做?
|
4月前
|
JavaScript 前端开发
【Vue面试题二十七】、你了解axios的原理吗?有看过它的源码吗?
文章讨论了Vue项目目录结构的设计原则和实践,强调了项目结构清晰的重要性,提出了包括语义一致性、单一入口/出口、就近原则、公共文件的绝对路径引用等原则,并展示了单页面和多页面Vue项目的目录结构示例。
|
3月前
|
缓存 JavaScript 前端开发
vue面试题
vue面试题
169 64
|
2月前
|
JavaScript 索引
如何在 Vue 中动态地添加或删除 Mixin
【10月更文挑战第18天】通过以上的分析和探讨,相信你对如何在 Vue 中动态地添加或删除 Mixin 有了更深入的理解。在实际开发中,你可以根据具体的需求和场景,灵活运用这些方法,以实现更加灵活和高效的应用开发。
27 4
|
2月前
|
JavaScript
Vue 中mixin 的用法
【10月更文挑战第18天】Vue 中mixin 的用法
33 3
|
2月前
|
JavaScript 前端开发
vue尚品汇商城项目-day01【8.路由跳转与传参相关面试题】
vue尚品汇商城项目-day01【8.路由跳转与传参相关面试题】
42 0
vue尚品汇商城项目-day01【8.路由跳转与传参相关面试题】
|
4月前
|
JavaScript 安全 前端开发
【Vue面试题二十九】、Vue项目中你是如何解决跨域的呢?
这篇文章介绍了Vue项目中解决跨域问题的方法,包括使用CORS设置HTTP头、通过Proxy代理服务器进行请求转发,以及在vue.config.js中配置代理对象的策略。
【Vue面试题二十九】、Vue项目中你是如何解决跨域的呢?