vuejs中使用mixin局部混入/全局混入的方法详解

目录
  • 前言
  • 需求
  • 什么是mixin
  • 全局混入
  • 几个重要的疑问
  • 选项合并
    • 生命周期函数
    • data数据冲突
    • 方法名冲突
  • mixin的优缺点
    • 1.变量名来源不明确
    • 2. 多个mixins的生命周期会合并融合到一起运行,但是同名属性,同名方法无法融合,会导致冲突或覆盖
    • 3. mixins和组件可能出现多对多的关系,复杂度会变高
  • mixin优点
  • 总结

前言

我们在实际项目开发中,有很多基本相似功能模块,只是操作显示数据不同,很多逻辑和配置都是相同的

在Vue项目里,每个单文件组件都是一个模块组件,每个组件都有自己内部的数据和方法逻辑

如果每个单文件组件想要实现同样的功能

那么在每个单文件组件都要在逻辑业务代码里重复写一遍,这样在很多单文件组件内,到处都是从某一处复制粘贴过来的代码

在Vue当中,可以用封装组件来达到复用代码的目的,除了可以复用模板,那么逻辑,一些配置选项,是不是也可以公用?

当然是可以的,当只需要二次修改时,同样的逻辑的代码,只需要修改一处就可以了的

今天就来学习下Vue当中的这个mixin的,多个组件,当遇到相同的逻辑,是如何共用逻辑配置的

需求

假设:现在有两个不同的按钮组件ButtonA,ButtonB,点击它弹出组件自身不同的属性

用Vue-cli脚手架创建一个项目,在components文件夹下分别创建ButtonA.vue,ButtonB.vue两个组件

以下是ButtonA组件内容,在按钮上绑定了handleButton方法,并在methods选项配置中定义

<template>
    <div class="wrap">
        <button @click="handleButton">按钮组件A</button>
    </div>
</template>
<script>
    export default {
        name: "ButtonA",
        data() {
            return {
                name: "itclan.cn"
            }
        },
        methods: {
            handleButton() {
                alert(this.name);
            }
        }
    }
</script>

<style lang="scss" scoped>
.wrap {
    margin-right: 20px;
}
</style>

以下是ButtonB组件内容,在按钮上绑定了handleButton方法,并在methods选项配置中定义

<template>
    <div>
        <button @click="handleButton">按钮组件B</button>
    </div>
</template>

<script>
    export default {
        name: "ButtonB",
        data() {
            return {
                name: "video.itclan.cn"
            }
        },
        methods: {
            handleButton() {
                alert(this.name);
            }
        }
    }
</script>

<style lang="scss" scoped>

</style>

然后再App.vue当中引入两个ButtonA,ButtonB组件

<template>
  <div id="app">
       <ButtonA></ButtonA>
       <ButtonB></ButtonB>
  </div>
</template>

<script>

import ButtonA from "./components/ButtonA"
import ButtonB from "./components/ButtonB"
export default {
  name: 'App',
  components: {
    ButtonA,
    ButtonB
  }
}
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
  display: flex;
  justify-content: center;
}
</style>

经过上面的几行代码,可以实现我们想要的目的,但是你会发现,他们的功能逻辑都是一样的,定义的方法名也都是一样的

如果一个项目里,有很多个这样的组件,只要想改,那么所有的单文件组件都得手动的修改一次,毫无疑问,重复性的代码也比较多,比较分散

对于不同组件间同样的配置,能不能提取出来共用一份呢,在Vue当中,提供了mixin

什么是mixin

把多个组件共有的配置提取成一个混入对象,然后通过局部混入或者全局混入,以达到共用配置的目的,这就是mixin

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

翻译一下: 将组件的公共逻辑或者配置(包括data,方法,生命周期,甚至props等)提取出来,哪个组件需要用到时,直接将提取的这部分混入到组件内部即可。这样既可以减少代码冗余度,也可以让后期维护起来更加容易,改一处即可,不用到处去每个组件内修改配置

注意:提取的是逻辑或配置,而不是HTML代码和CSS代码。也就是说,mixin就是组件中的组件,Vue组件化让我们的代码复用性更高

那么组件与组件之间还有重复部分,比如逻辑业务的复用,我们还可以使用Mixin在抽离一遍

以下是经过mixin改写过的

在src文件夹下创建一个mixin文件夹(这个文件夹下全部放入一些混入),创建一个popButton.js文件,创建一个对象,然后暴露出去,如下所示

export const popButton  = {
    // 这里面组件选项的配置都是可以的,生命周期等,data属性,计算属性,监听属性等
    methods: {
        handleButton() {
            alert(this.name);
        }
    }
}

然后再组件使用处引入即可,如下ButtonA组件,通过import引入,同时在组件配置选项中mixins:[引入的混入名],要是多个的话,用逗号分隔

<template>
    <div class="wrap">
        <button @click="handleButton">按钮组件A</button>
    </div>
</template>

<script>
import {popButton} from "../mixin/popButton.js"
    export default {
        name: "ButtonA",
        mixins: [popButton],
        data() {
            return {
                name: "itclan.cn"
            }
        },
    }
</script>

<style lang="scss" scoped>
.wrap {
    margin-right: 20px;
}
</style>

这种在组件内部,通过minxins:[混入名称],也被视为局部混入

局部混入也就是只在当前组件内起作用,与按需加载有些相似,也就是需要用到mixin中的代码时,我们再在组件内引入它

而全局混入的话,则代表我在项目的任何组件中都可以使用mixin,从根组件下至到它的任何一个组件都会用到混入

全局混入

局部混入是,在需要的组件引入混入,通过import导入混入,在通过在组件的配置选项中通过minxins: [混入名称]

而全局混入,则是在项目代码中的main.js中去引入混入,在用Vue.mixin(混入名称)进行注册

这样任何一个组件,都可以使用混入了的,如下代码所示

import Vue from 'vue'
import App from './App.vue'

import {popButton} from "./mixin/popButton.js"

Vue.mixin(popButton);

Vue.config.productionTip = false

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

::: tip 注意事项 在使用全局混入时,应当格外小心,一旦使用全局混入,它将影响每一个之后创建的vue实例,也就是所有的vm,vc都会有混入

它与局部混入没有啥区别,虽然一次性注入混入很方便,但是也会带来一些问题,所有的组件实例,Vue实例都会有混入

在官方的特殊提示里,提到了,谨慎使用全局混入,因为它会影响每个单独创建的vue实例(包括第三方组件)

大多数情况下,只应当应用于自定义选项,就像上面示例一样,推荐将其作为插件发布,以避免重复应用混入 :::

几个重要的疑问

  • mixin中的生命周期函数会和组件的生命周期一起合并执行
  • mixin中的data数据在组件中可以使用
  • mixin中的方法在组件内部可以直接调用
  • 生命周期函数合并后执行顺序:先执行mixin中的,然后执行组件的
  • mounted不会合并,都会加载一遍
  • 不同组件中的mixin是相互独立的,改变一个组件中mixin中的数据,另一个引用了mixin的组件不会受影响

如下代码

export const popButton  = {
    data() {
        return {
            name: "川川",
            age: 18
        }
    },
    created() {
        console.log("混入生命周期开始执行");
    },
    mounted() {
        console.log("我是混入");
    },
    methods: {
        handleButton() {
            alert(this.name);
        },
        handleMounted() {
            console.log("加载方法");
        }
    }
}

选项合并

当组件和混入对象含有同名选项时,这些选项将以合适的方式进行合并

也就是说,当mixin中定义的数据,方法名与组件里的属性名,方法名同名时,会怎么样呢

会存在数据,和方法名的覆盖问题?谁覆盖谁?执行先后顺序是?

生命周期函数

mixin里面可以有自己的生命周期函数,同组件一样,生命周期函数是自执行函数,在某个阶段会自动执行

它都是固定的,默认合并策略如下所示

  • 先执行mixin中生命周期函数中的代码,然后再执行组件内部的代码
export const popButton  = {
    data() {
        return {
            name: "川川",
            age: 18
        }
    },
    beforeCreate() {
        console.log("创建之前");
    },
    created() {
        console.log("混入生命周期开始执行");
    },
    mounted() {
        console.log("我是混入");
    },

    beforeUpdate() {
        console.log("更新之前");
    },
    updated() {
        console.log("更新之时");
    },
    beforeDestroy() {
        console.log("销毁之前");
    },
    destroyed() {
        console.log("销毁时");
    },
    methods: {
        handleButton() {
            alert(this.name);
        },
        handleMounted() {
            console.log("加载方法");
        }
    }
}

若是方法重名,则后者组件内的方法会覆盖mixin中的方法

data数据冲突

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

若是没有相同的话,会进行数据的合并

export const popButton  = {
    data() {
        return {
            name: "川川",
            age: 18
        }
    },
}

方法名冲突

在同一个项目里,起相同的名称,是很容易遇到的,如果mixin中的方法名与引入mixin中组件的方法名一致时,那么以当前组件为准

mixin的优缺点

既然mixin这么好用,那为什么不直接大量推荐使用?mixin可以复用组件的逻辑,这样可以节省很多代码,但是同样,也会带来一些问题

1.变量名来源不明确

在某些单文件组件里,引入mixin,因为组件内可以调用mixin的方法和使用mixin中定义的数据,找上下文的时候,变得不是那么直观,要么通过阅读代码逐级向上进行查找,要么就是全局进行搜索查找

使用mixin时,不利于阅读,代码变得难以维护

因为组件里可以引入多个mixin,并直接隐式的调用mixin里面的变量和方法,这会让写代码的人看着有些混乱,区分不出这些变量和方法,分别是哪个mixin的

所以这里建议是:但凡mixin的方法,统一放到mixin文件夹下进行管理的

2. 多个mixins的生命周期会合并融合到一起运行,但是同名属性,同名方法无法融合,会导致冲突或覆盖

当遇到组件中定义的属性,方法与minxin当中的出现相同时,后者组件的属性会覆盖mixin中的属性

3. mixins和组件可能出现多对多的关系,复杂度会变高

一个组件可以引用多个mixins一个mixins也可以被多个组件引用,因为是共用逻辑,所以在关系上,不是很明确

不好追溯代码,排查问题,可以利用工具vscode全局搜索,如果是很多个地方用到了的mixin那么就得挨个的检查

如果滥用mixin的话,会让代码变得难以维护

如果是用了全局混入,在审查代码时,在任何一组件当中会莫名的多出一些属性和方法,会令新的同学很困惑,如果对mixin很熟悉的话,那没什么,如果不熟悉

那么就非常苦恼,这个变量名和方法,我在组件当中明明没有定义,但是为啥能使用呢,带来一些困惑

注意

如果一个功能,逻辑,一开始就很确定,它以后是不会动的,那么就可以使用mixin

mixin优点

  • 提高组件代码复用性
  • 无需传递状态
  • 维护方便,只需要修改一处地方就可以,全局混入,应当谨慎使用

总结

mixin是在vue当中复用逻辑,精简代码的一种思想,相当于就是提取组件当中的公共配置属性,方法,可以使用mixins:[混入名称]局部混入,也可以在main.js中Vue.mixin(混入名称),全局混入

给封装复用代码带来了很多方便,但是也不要滥用它,有些场景非常适合,但是有些场景使用过多了,也会带来一些不可预知的问题

一般封装公共组件就比较适合使用mixin,还有做数据可视化时,当组件层级较多,想要从同一个数据源抽出公共的数据时,也可以使用mixin

在阅读一些优秀的项目时,也会看到很多项目里有使用mixin的

到此这篇关于vuejs中使用mixin局部混入/全局混入的文章就介绍到这了,更多相关vuejs使用mixin局部/全局混入内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Vue之Mixins(混入)的使用方法

    混入 (mixin) 提供了一种非常灵活的方式,来分发 Vue 组件中的可复用功能.一个混入对象可以包含任意组件选项.当组件使用混入对象时,所有混入对象的选项将被"混合"进入该组件本身的选项. 当组件和混入对象含有同名选项时,这些选项将以恰当的方式进行"合并". 比如,数据对象在内部会进行递归合并,并在发生冲突时以组件数据优先. var Mymixin = { data: function(){ return { message: 'hello', foo: 'ab

  • Vue混入mixins滚动触底的方法

    前言 在app端常常看到类似加载数据的动画,接下来我们来实现滚动触底加载动画提示,以及如何复用这些逻辑. 如何判断滚动触底 来看下几张图: 情况一: 当文档高度还为超过可视区域高度时,不存在滚动,所以也没有滚动触底 情况二: 当文档高度超过可视区域的高度时,还有剩余的文档没有滚动完,也就是说 可视区域高度 + 滚动高度 < 文档高度 ,此时没有达到滚动触底的条件   情况三: 文档高度大于可视区域,并且滚动到文档底部, 也就是说 可视区域高度 + 滚动高度 = 文档高度 判断是否滚动到底 经过上

  • 深入了解Vue.js 混入(mixins)

    混入 (mixins)定义了一部分可复用的方法或者计算属性.混入对象可以包含任意组件选项.当组件使用混入对象时,所有混入对象的选项将被混入该组件本身的选项. 来看一个简单的实例: var vm = new Vue({ el: '#databinding', data: { }, methods : { }, }); // 定义一个混入对象 var myMixin = { created: function () { this.startmixin() }, methods: { startmix

  • vue3  mixin 混入使用方法

    目录 一.mixin 如何使用 ? 二.mixin 使用时注意点 2.1.使用 mixin 对象时,组件内部和 mixin 包含相同选项,如何处理呢? 2.2.使用的 mixin 对象选项 和实例中的选项拥有相同的属性该如何处理? 2.3.mixin 对象也可以添加生命周期钩子函数 三.mixin 自定义属性 四.合并策略 五.全局配置 mixin vue 2 中采用选项式API 如: data.methods.watch.computed以及生命周期钩子函数等等. mixin 混入,提供了一种

  • 详解Vue.js Mixins 混入使用

    Mixins一般有两种用途: 1.在你已经写好了构造器后,需要增加方法或者临时的活动时使用的方法,这时用混入会减少源代码的污染. 2.很多地方都会用到的公用方法,用混入的方法可以减少代码量,实现代码重用. 一.Mixins的基本用法 我们现在有个数字点击递增的程序,假设已经完成了,这时我们希望每次数据变化时都能够在控制台打印出提示:"数据发生变化". 代码实现过程: <!DOCTYPE html> <html lang="en"> <h

  • 记一次Vue.js混入mixin的使用(分权限管理页面)

    需求背景:在一个后台的管理系统中,不同的用户角色对应不同的用户权限.现要求,同一个页面对有操作权限的用户来说是可操作的,对无操作权限的用户来说是只读的,即操作按钮均失效.系统用Vue.js开发. 一.mixin的概念 官方文档这么说:混入是一种分发Vue组件中可服用功能的非常灵活的方式.混入对象可以包含任意组件选项.当组件使用混入对象时,所有混入对象的选项将被混入该组件本身的选项. 我自己的理解:混入对象具有Vue组件可以声明的所有选项,如[components].[computed].[met

  • Vue中的混入的使用(vue mixins)

    使用场景: 例如我们在Vue单页面开发的时候当多个组件中都需要下拉刷新,或者使用的都是一个方法的时候,我们就可以使用vue mixins进行封装调用,以及继承,具体看代码. 选项合并 var mixin = { data: function () { return { message: 'hello' } }, created:function(){ console.log('我是mixins中的created') }, methods:{ show:function(num){ console

  • vuejs中使用mixin局部混入/全局混入的方法详解

    目录 前言 需求 什么是mixin 全局混入 几个重要的疑问 选项合并 生命周期函数 data数据冲突 方法名冲突 mixin的优缺点 1.变量名来源不明确 2. 多个mixins的生命周期会合并融合到一起运行,但是同名属性,同名方法无法融合,会导致冲突或覆盖 3. mixins和组件可能出现多对多的关系,复杂度会变高 mixin优点 总结 前言 我们在实际项目开发中,有很多基本相似功能模块,只是操作显示数据不同,很多逻辑和配置都是相同的 在Vue项目里,每个单文件组件都是一个模块组件,每个组件

  • python 中Mixin混入类的使用方法详解

    目录 前言 Mixin 与继承的区别 总结 前言 最近在看sanic的源码,发现有很多Mixin的类,大概长成这个样子 class BaseSanic(    RouteMixin,    MiddlewareMixin,    ListenerMixin,    ExceptionMixin,    SignalMixin,    metaclass=SanicMeta, ): 于是对于这种 Mixin 研究了一下,其实也没什么新的东西,Mixin 又称混入,只是一种编程思想的体现,但是在使用

  • vuejs动态组件给子组件传递数据的方法详解

    通过子组件定义时候的props可以支持父组件给子组件传递数据,这些定义的props在子组件的标签中使用绑定属性即可,但是如果使用的是<component>动态组件,这个时候就没有显式的子组件标签,要给子组件传递数据需要在<component> 中进行绑定 <div class="app" id="deviceready"> <component :is="currentView" :user_name.s

  • JS中call/apply、arguments、undefined/null方法详解

    a.call和apply方法详解 -------------------------------------------------------------------------------- call方法: 语法:call([thisObj[,arg1[, arg2[, [,.argN]]]]]) 定义:调用一个对象的一个方法,以另一个对象替换当前对象. 说明: call 方法可以用来代替另一个对象调用一个方法.call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指

  • 关于java中可变长参数的定义及使用方法详解

    JAVA中可以为方法定义可变长参数( Varargs)来匹配不确定数量的多个参数,其定义用"..."表示.其实,这类似于为方法传了一个数组,且在使用方法上也和数组相同,如下: public void test(String... str){ for(String s : str){ } } 调用方法就像普通的调用方式相同,只不过可以匹配的参数为0到多个.如下: test(); test("lilei"); test("lilei","h

  • 对python中xlsx,csv以及json文件的相互转化方法详解

    最近需要各种转格式,这里对相关代码作一个记录,方便日后查询. xlsx文件转csv文件 import xlrd import csv def xlsx_to_csv(): workbook = xlrd.open_workbook('1.xlsx') table = workbook.sheet_by_index(0) with codecs.open('1.csv', 'w', encoding='utf-8') as f: write = csv.writer(f) for row_num

  • 对Python中一维向量和一维向量转置相乘的方法详解

    在Python中有时会碰到需要一个一维列向量(n*1)与另一个一维列向量(n*1)的转置(1*n)相乘,得到一个n*n的矩阵的情况.但是在python中, 我们发现,无论是".T"还是"np.transpose"都无法实现一维向量的转置,相比之下,Matlab一句" a' "就能实现了. 那怎么实现呢?我找了个方法.请看: 即,我们把向量reshape一下,如此便实现了一维向量与一维向量转置相乘为矩阵的目的. 若大家有其他方法望告知. 以上这篇对

  • 在Pycharm中对代码进行注释和缩进的方法详解

    一.注释 1. #单行注释 2. """ 多行注释 """ 3. pycharm多行注释快捷键:Ctrl+/ 二.缩进 缩进:Tab 反向缩进:Shift+Tab 以上这篇在Pycharm中对代码进行注释和缩进的方法详解就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们.

  • 对numpy中二进制格式的数据存储与读取方法详解

    使用save可以实现对numpy数据的磁盘存储,存储的方式是二进制.查看使用说明,说明专门提到了是未经压缩的二进制形式.存储后的数据可以进行加载或者读取,通过使用load方法. In [81]:np.save('demo',data1) 通过以上操作,数据data1被存储到了demo文件中,numpy会自动加上npy的文件后缀名. In [82]: a =np.load('demo.npy') In [83]: a Out[83]: array([0,1, 2, 3, 4, 5, 6, 7, 8

  • c++中的单例类模板的实现方法详解

     1.什么是单例模式 在架构设计时,某些类在整个系统生命周期中最多只能有一个对象存在 ( Single Instance ).如超市收银系统,其外观主要由显示器(1个).扫描枪(1个).收款箱(1个)组成,在系统正常运行期间这三部分都是唯一存在的:也就是说,显示器.扫描枪.收款箱这三部分都应该有各自的类,并且每个类只能唯一地实例化一个对象,基于这种模式的程序设计,称为单例模式. !!!单例模式只能创建一个对象,且该对象的生命周期伴随系统的整个运行期间. 2.怎么实现单例模式 思考:如何定义一个类

随机推荐