说说你对vue的mixin的理解,有什么应用场景

news2024/11/20 1:23:12
  • mixin是什么
    • Vue中的mixin
      • 局部混入
      • 全局混入
      • 注意事项:
    • 使用场景
    • 源码分析
    • Vue 的几种类型的合并策略
      • 替换型
      • 合并型
      • 队列性
      • 叠加型
      • 小结

此文章,来源于印客学院的资料,这里只是分享,便于查漏补缺。

mixin是什么

Mixin 是 面向对象程序设计语言中的类,提供了方法的实现。其他类可以访问 mixin 类的方法而不必成为其子类

Mixin 类通常作为功能模块使用,在需要该功能时“混入”,有利于代码复用又避免了多继承的复杂

Vue中的mixin

先来看一下官方定义

mixin (混入) ,提供了一种非常灵活的方式,来分发 Vue 组件中的可复用功能

本质其实就是一个 js 对象,它可以包含我们组牛中任意功能选项,如 data、components、methods、created、computed 等等

我们只要将共用的功能以对象的方式传入 mixi选项中,当组件使用mixins对象时所有 mixins 对象的选项都将被混入该组件本身的选项中来

在 Vue2 中,Mixin 混入的生命周期函数与组件的生命周期函数相同

在 Vue 中我们可以局部混入全局混入

更多详细内容,请微信搜索“前端爱好者戳我 查看

局部混入

定义一个 mixin 对象,有组件 options 的 data、methods 属性

var myMixin = {
    created: function () {
        this.hello()
    },
    methods: {
        hello: function () {
            console.log('hello from mixin!')
        }
    }
}

组件通过 mixins 属性调用 mixin 对象

Vue.component('componentA',{
 mixins: [myMixin]
})

该组件在使用的时候,混合了 mixin 里面的方法,在自动执行 created生命钩子,执行 hello 方法

全局混入

通过 Vue.mixin()进行全局的混入

Vue.mixin({
    created: function () {
        console.log("全局混入")
    }
})

使用全局混入需要特别注意,因为它会影响到每一个组件实例 (包括第三方组件)

PS: 全局混入常用于插件的编写

注意事项:
  • 当组件存在与 mixin 对象相同的选项的时候,进行递归合并的时候组件的选项会覆盖 mixin 的选项
  • 但是如果相同选项为生命周期钩子的时候,会合并成一个数组,先执行 mixin 的钩子,再执行组件的钩子

使用场景

在日常的开发中,我们经常会遇到在不同的组件中乡常会需要用到一些相同或者相似的代码,这些代码
的功能相对独立

这时,可以通过 Vue 的 mixin 功能将相同或者相似的代码提出来

举个例子

定义一个modal 弹窗组件,内部通过 isShowing 来控制显示

const Modal = {
    template: '#modal',
    data() {
        return {
            isShowing: false
        }
    },
methods: {
    toggleShow() {
        this.isShowing = !this.isShowing;
        }
    }
}

定义一个 tooltip 提示框,内部通过 isShowing 来控制显示

const Tooltip = {
    template: '#tooltip',
    data() {
        return {
            isShowing: false
        }
    },
    methods: {
        toggleShow() {
            this.isShowing = !this.isShowing;
        }
    }
}

通过观察上面两个组件,发现两者的逻辑是相同,代码控制显示也是相同的,这时候 mixin 就派上用场了

首先抽出共同代码,编写一个 mixin

const toggle = {
    data() {
        return {
            isShowing: false
        }
    },
    methods: {
        toggleShow() {
            this.isShowing = !this.isShowing;
        }
    }
}

两个组件在用上,只需要引入 mixin

const Modal = {
    template: '#modal',
    mixins: [toggle]
};

const Tooltip = {
    template: '#tooltip',
    mixins: [toggle]
}

通过上面小小的例子,让我们知道了 Mixin 对于封装一些可复用的功能如此有趣、方便、实用

源码分析

首先从 Vue.mixin 入手

源码位置: /src/core/global-api/mixin.js

export function initMixin (Vue: GlobalAPI) {
 Vue.mixin = function (mixin: Object) {
    this.options = mergeOptions(this.options, mixin)
    return this
 }
}

主要是调用 mergeOptions 方法

源码位置: /src/core/util/options.js

export function mergeOptions (
 parent: Object,
 child: Object,
 vm?: Component
): Object {
    if (child.mixins) { // /判断有没有mixin 也就是mixin里面挂mixin的情况 有的话递归进行合并
        for (let i = 0, l = child.mixins.length; i < l; i++) {
            parent = mergeOptions(parent, child.mixins[i], vm)
        }
    }

    const options = {}
    let key

    for (key in parent) {
        mergeField(key) // 先遍历parent的key 调对应的strats[XXX]方法进行合并
    }

    for (key in child) {
        if (!hasOwn(parent, key)) { // 如果parent已经处理过某个key 就不处理了
            mergeField(key) // 处理child中的key 也就parent中没有处理过的key
        }
    }

    function mergeField (key) {
        const strat = strats[key] || defaultStrat
        options[key] = strat(parent[key], child[key], vm, key) // 根据不同类型的options调用strats中不同的方法进行合并
    }
    return options
}

从上面的源码,我们得到以下几点:

  • 优先递归处理 mixins
  • 先遍历合并 parent 中的 key ,调用 mergeField 方法进行合并,然后保存在变量 options
  • 再遍历 child,合并补上 parent 中没有的 key ,调用 mergeField 方法进行合并,保存在变量 options
  • 通过 mergeField 函数进行了合并

Vue 的几种类型的合并策略

下面是关于 Vue 的几种类型的合并策略

  • 替换型
  • 合并型
  • 队列型
  • 叠加型
替换型

替换型合并有 props、methods 、inject 、computed

同名的 props 、methods 、inject 、computed 会被后来者代替

合并型

和并型合并有: data

mergeData 函数遍历了要合并的 data 的所有属性,然后根据不同情况进行合并:

  • 当目标 data 对象不包含当前属性时,调用 set 方法进行合并 (set方法其实就是一些合并重新赋值的方法)
  • 当目标 data 对象包含当前属性并且当前值为纯对象时,递归合并当前对象值,这样做是为了防止对象存在新增属性
队列性

队列性合并有: 全部生命周期和 watch

function mergeHook (
 parentVal: ?Array<Function>,
 childVal: ?Function | ?Array<Function>
): ?Array<Function> {
 return childVal
 ? parentVal
 ? parentVal.concat(childVal)
 : Array.isArray(childVal)
 ? childVal
 : [childVal]
 : parentVal
}

LIFECYCLE_HOOKS.forEach(hook => {
 strats[hook] = mergeHook
})

// watch
strats.watch = function (
 parentVal,
 childVal,
 vm,
 key
) {
    // work around Firefox's Object.prototype.watch...
    if (parentVal === nativeWatch) { parentVal = undefined; }
    if (childVal === nativeWatch) { childVal = undefined; }
    /* istanbul ignore if */
    if (!childVal) { return Object.create(parentVal || null) }
    {
        assertObjectType(key, childVal, vm);
    }
        if (!parentVal) { 
        return childVal 
    }
    var ret = {};

    extend(ret, parentVal);

    for (var key$1 in childVal) {
        var parent = ret[key$1];
        var child = childVal[key$1];
        if (parent && !Array.isArray(parent)) {
         parent = [parent];
        }
        ret[key$1] = parent
        ? parent.concat(child)
        : Array.isArray(child) ? child : [child];
    }
  return ret
};

生命周期钩子和 watch 被合并为一个数组,然后正序遍历一次执行

叠加型

叠加型有:directives、 filters、component

strats.components=
strats.directives=
strats.filters = function mergeAssets(
 parentVal, childVal, vm, key
) { 
 var res = Object.create(parentVal || null); 
 if (childVal) {
    for (var key in childVal) {
        res[key] = childVal[key];
    } 
 }
 return res
}

叠加型主要是通过原型链进行层层的叠加

小结
  • 替换型策略有 props、methods 、inject 、computed,就是将新的同名参数替代旧的参数
  • 合并型策略是 data,通过 set 方法进行合并和重新赋值
  • 队列型策略有生命周期函数和 watch ,原理是将函数存入一个数组,然后正序遍历依次执行叠加型有 component 、 directives 、 filters ,通过原型链进- 行层层的叠加

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1417162.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

一文理清楚-Docker 容器如何工作

Docker 容器如何工作 集装箱什么是虚拟机&#xff1f;虚拟化如何运作&#xff1f;什么是容器&#xff1f;什么是 Docker&#xff1f;总结 五星上将麦克阿瑟曾经说过&#xff1a;在docker面前&#xff0c;虚拟机就是个弟弟 集装箱 《盒子&#xff1a;集装箱如何让世界变得更小&…

车载电子电器架构 —— 多核处理器刷写策略

车载电子电器架构 —— 多核处理器刷写策略 我是穿拖鞋的汉子&#xff0c;魔都中坚持长期主义的汽车电子工程师。 老规矩&#xff0c;分享一段喜欢的文字&#xff0c;避免自己成为高知识低文化的工程师&#xff1a; 屏蔽力是信息过载时代一个人的特殊竞争力&#xff0c;任何消…

内存管理(mmu)/内存分配原理/多级页表

1.为什么要做内存管理&#xff1f; 随着进程对内存需求的扩大&#xff0c;和同时调度的进程增加&#xff0c;内存是比较瓶颈的资源&#xff0c;如何更好的高效的利于存储资源是一个重要问题。 这个内存管理的需求也是慢慢发展而来&#xff0c;早期总线上的master是直接使用物…

C++:STL - string

C&#xff1a;STL - string basic_stringstringstring的常见构造string的输入输出operator<<c_stroperator>>getline string访问及遍历operator[ ] & atfont & back迭代器begin & endrbegin & rend 范围for string的容量操作size & lengthmax_…

用甘特图有效管理多个项目进度

当公司或组织同时承担多个项目时,合理规划各项目的时间节点与资源分配对确保高效完成至关重要。采用甘特图可以直观地展示多个项目的时间进程、关键里程碑以及资源分配情况,便于从宏观层面全面把控各项目的动态。 在线甘特图软件 zz-plan.com 提供了非常强大的时间轴规划功能,支…

CSS 多色正方形上升

<template><view class="loop cubes"><view class="item cubes"></view> <!-- 方块1 --><view class="item cubes"></view> <!-- 方块2 --><view class="item cubes"></vie…

C# 将HTML网页、HTML字符串转换为PDF

将HTML转换为PDF可实现格式保留、可靠打印、文档归档等多种用途&#xff0c;满足不同领域和情境下的需求。本文将通过以下两个示例&#xff0c;演示如何使用第三方库Spire.PDF for .NET和QT插件在C# 中将Html 网页&#xff08;URL&#xff09;或HTML字符串转为PDF文件。 HTML转…

【C语言】深入理解指针(3)数组名与函数传参

目录 &#xff08;一&#xff09;数组名的理解 &#xff08;1&#xff09;数组名是数组首元素的地址 &#xff08;2&#xff09;两个例外 &#xff08;二&#xff09;函数内数组传参 &#xff08;1&#xff09;一维数组传参 &#xff08;2&#xff09;二维数组传参 &…

以太网交换基础VLAN原理与配置

目录 7.以太网交换基础 7.1.以太网协议 7.2.以太网帧介绍 7.3.以太网交换机 7.4.同网段数据通信全过程 8.VLAN原理与配置 8.1.VLAN的基本概念 8.2.VLAN的应用 7.以太网交换基础 7.1.以太网协议 以太网是当今现有局域网(Local Area Network,LAN)采用的最通用的通信协议…

git使用指南——以gitlab为例

注册gitlab 自行注册 新建项目 选择新建一个空白的项目 上传项目 clone项目地址到本地 执行完之后&#xff0c;会在目录下生成如下内容&#xff1a;进入里面&#xff0c;选择.git&#xff0c;要上传的内容&#xff08;资料或代码复制到该目录下&#xff09;&#xff1a;…

界面组件DevExpress .NET MAUI中文教程 - 如何优化手机屏幕空间?

DevExpress拥有.NET开发需要的所有平台控件&#xff0c;包含600多个UI控件、报表平台、DevExpress Dashboard eXpressApp 框架、适用于 Visual Studio的CodeRush等一系列辅助工具。 获取DevExpress v23.2正式版下载 Bottom Sheet是一个组件&#xff0c;它显示固定在屏幕底部的…

LeetCode:376.摆动序列

个人主页&#xff1a;仍有未知等待探索-CSDN博客 专题分栏&#xff1a;算法_仍有未知等待探索的博客-CSDN博客 题目链接&#xff1a;376. 摆动序列 - 力扣&#xff08;LeetCode&#xff09; 一、题目 如果连续数字之间的差严格地在正数和负数之间交替&#xff0c;则数字序列称…

【排序5】基数排序:数字的组织与整理艺术

&#x1f3a1;基数排序 &#x1f38a;1、基本思想&#x1f38a;2、基本步骤&#x1f38a;3、代码示例&#x1f38a;4、特性总结 &#x1f38a;1、基本思想 基数排序&#xff08;Radix Sort&#xff09;是一种非比较排序算法&#xff0c;它根据数字的每一位来对元素进行排序。它…

提示unzip :commad not found; 安装unzip教程

1.当使用unzip解压时 提示&#xff1a; unzip :commad not found; 2.安装命令 sudo yum install unzip 3.输入 y 确认 4.提示&#xff1a;完成 5.输入 unzip 文件名 解压-验证 6.完成

34.基于51单片机的智能停车位计时收费系统设计

一、系统功能介绍&#xff1a; 本设计基于 RFID智能识别和高速的视频图像和存储比较相结合&#xff0c;通过计算机的图像处理和自动识别&#xff0c;对车辆进出停车场的收费、车牌识别和车位诱导等&#xff0c;以实现停车场全方位智能管理。 本设计是以AT89C51 型单片机为主控芯…

Kubernetes (十七) 资源监控

一. 资源监控 二. metrics-server资源下载配置 官网:资源下载&#xff1a;http…

搭建Mybatis环境

1.导入依赖 pom.xml <dependencies> <!-- Mybatis依赖--><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.7</version></dependency> <!-- Mysql依…

Tonka Finance 测试网活动,开启新铭文时代财富之门

Tonka Finance 是铭文赛道首个借贷市场&#xff0c;通过搭建一套铭文资产借贷质押方案&#xff0c;为铭文资产以借贷的形式释放价值、捕获流动性等方面提供了基础。作为铭文赛道最重要的基建设施之一&#xff0c;Tonka Finance 在面向市场后备受关注&#xff0c;并迅速作为铭文…

【UE】在控件蓝图中通过时间轴控制材质参数变化

效果 步骤 1. 新建一个控件蓝图和一个材质 2. 打开材质&#xff0c;设置材质域为用户界面&#xff0c;混合模式设置为“半透明” 在材质图表中添加两个参数来控制材质的颜色和不透明度 3. 对材质创建材质实例 4. 打开控件蓝图&#xff0c;在画布面板中添加一个图像控件 将刚…

vue常用指令(v-html)

一、v-html 指令 作用: 获取文本数据设置元素的innerHTML&#xff0c;此为和v-text的区别 二、代码演示 1、获取普通文本数据 代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewpor…