Vue mixin 混入

news2024/12/20 2:31:06

可以复用的组件,我们一般会抽离,写成公共的模块。

可以复用的方法,我们一般会抽离,写成公共的函数。

那么 在 Vue 中,如果 某几个组件实例 VueComponent 中或者 整个 Vue 项目中 都存在相同的配置,那就需要用到 mixin 这个方法了

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

 首先、我们需要明白第一点,mixin 是一个对象,而且是包含组件中任意配置项的对象,也就是说,创建组件的时候,我们传递的 data、component、methods、computed、directives、生命周期钩子函数 等等 一系列配置项 都可以作为 mixin 对象的键值对。

其次、我们创建的 mixin 对象,在组件中引用的时候,mixin 对象 中的键值对会 混入 该组件的配置详项中,至于是怎么混入的,下面在讲。 

创建 mixin 

 这个 mixin 对象 中,配置了一个 created 钩子函数,和 methods 对象,如果我们单独把这个配置写在组件中的话,那就是组件在初始化的时候,就会调用 hello() 

// 定义一个混入对象
var myMixin = {
  created: function () {
    this.hello()
  },
  methods: {
    hello: function () {
      console.log('hello from mixin!')
    }
  }
}

创建一个 mixin 混入对象是很简单的,只是我们需要注意的是,配置的键值对,只能是创建组件时传入的配置项,如果,你传了一个 其他不存在的属性 ,组件接收之后,是不会对其解析的,就相当于你在组件内部,定义了一个不存在属性,Vue 底层是不会管这个玩意的。

export const mixin = {
  msg: {
    success: "1",
  },
};


export default {
  name: 'HelloWorld',
  msg: {
    success: "1",
  }
}

使用 mixin 混入 

创建了一个 mixin 对象之后,组件需要使用的时候,就和引入公共组件和公共方法一样。至于其中的内容,还是使用上面定义的

比如:我在 src 目录下新建了一个 mixin 文件夹,和一个 index.js 文件,那我在引用的时候就正常引入,至于 你是 默认暴露还是分别暴露,那就看个人习惯了。

import {mixin} from '@/mixin/index'

然后在组件配置项中,配置一个 mixins 属性,值是一个数组。

export default {
  name: 'HelloWorld',
  mixins:[mixin]
}

刷新页面,你会发现控制台上已经输出了 我想要的结果

 mixin 选项合并

 因为 mixin 混入对象 中的配置,是包含组件中任意配置项的对象,如果我的 mixin 混入对象中定义的配置,和组件内部定义的配置出现了同名了,那 Vue 是怎么合并这两个选项的呢?

data数据对象:在内部会进行递归合并,并在发生冲突时以组件数据优先

var mixin = {
  data: function () {
    return {
      message: 'hello',
      foo: 'abc'
    }
  }
}

new Vue({
  mixins: [mixin],
  data: function () {
    return {
      message: 'goodbye',
      bar: 'def'
    }
  },
  created: function () {
    console.log(this.$data)
    // => { message: "goodbye", foo: "abc", bar: "def" }
  }
})

同名钩子函数 将合并为一个数组,因此都将被调用。另外,混入对象的钩子将在组件自身钩子 之前 调用。

export const mixin = {
  created: () => {
    console.log("mixin混入对象的钩子被调用!");
  },
};

export default {
  name: 'HelloWorld',
  mixins: [mixin],
  created: function () {
    console.log('组件钩子被调用')
  }
}

 值为对象的选项例如 methodscomponents 和 directives,将被合并为同一个对象。两个对象键名冲突时,取组件对象的键值对。

export const mixin = {
  created: () => {
    console.log("mixin混入对象的钩子被调用!");
  },
  methods: {
    foo: () => {
      console.log("foo");
    },
    conflicting: () => {
      console.log("from mixin");
    },
  },
};

export default {
  name: "HelloWorld",
  mixins: [mixin],
  created: () => {
    console.log("组件钩子被调用");
  },
  methods: {
    bar: () => {
      console.log("bar");
    },
    conflicting: () => {
      console.log("from self");
    },
  },
};

在组件中调用这三个方法,看看在控制台上输出的是啥

<div @click="bar">bar</div>
<div @click="conflicting">conflicting</div>
<div @click="foo">foo</div>

 可以看到,mixin 混入对象中存在的 foo 函数,和 conflicting函数,而组件中 存在 bar函数 和 conflicting 函数。在组件中能成功调用这三个方法,说明 mixin 混入对象中的 foo 函数,已经被合并到了组件的 methods 对象中。而 conflicting 函数执行之后,根据打印出的值,发现该函数执行的是 组件内部定义的 conflicting 函数。这就说明两个对象键名冲突时,取组件对象的键值对。

全局混入

上面讲的都是在组件内部混入,其实也可以在全局中混入。在 mian.js 中,当 执行 new Vue ( ) 之前,可以通过 Vue.mixin() 函数,向其内部传入一个 mixin 混入对象,Vue 底层就会将混入对象挂载到Vue全局上。

Vue.mixin({
  created:  () => {
    console.log('我在全局混入了created钩子函数');
  },
});

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

但是这样存在一个问题,就是如果我在全局通过 Vue.mixin() 混入了配置,那么我所有的组件 (包括第三方组件) 都会混入这个配置,这样可能会导致组件配置混乱冗余,甚至覆盖第三方组件的配置导致程序出错。

 上面我在全局混入了 一个 钩子函数,导致这个钩子函数执行了三次,这是因为,在 new Vue() 的时候执行了一次,App组件中执行了一次,在 HelloWorld 组件也执行了一次。这就看出来很多余了。

 自定义混入

区别:通过 Vue.mixin() 混入的是正常混入,直接写在 new Vue() 中(或者是组件中)的是自定义混入。通过Vue.config.optionMergeStrategies 添加的也是自定义混入

Vue.mixin({
  created: function () {
    var myOption = this.$options.myOption
    if (myOption) {
      console.log(myOption)
    }
  }
})

new Vue({
  myOption: 'hello!'
})

 这里只打印了一次,代表只在 new Vue()的时候执行了一次。大多数情况下,全局的混入只应当应用于自定义选项,这样可以避免上面的副作用。

自定义选项将使用默认策略,即简单地覆盖已有值。

我先正常混入了一个  myOption 属性,值为 123。

Vue.mixin({
  myOption:'123',
});

打印vm实例,$options 对象中存在该键值对

 直接在 new Vue() 中定义 同名属性,值为 abc

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

打印 vm实例对象,发现属性值已经更改。

如果想让自定义选项以自定义逻辑合并,可以向 Vue.config.optionMergeStrategies 添加一个函数,那我们来看看 Vue.config.optionMergeStrategies 是个啥

打印出来一看, 好家伙,这不就是 Vue 实例上的所有方法么。按文档的意思,我好像也可以自定义的往这里面加我自己的方法。

var strategies = Vue.config.optionMergeStrategies;
strategies.myOption = "123";

 我随便往里面加了一个 myOption 属性,值为 123,打印出来之后,确实存在设置的属性和值

我默认在 new Vue()的时候,注入了一个自定义的选项。这个时候,我们打印这个接收到的vm实例对象,能在 $options 里面找到该属性,且它的值就是我设置的 hello

 通过  Vue.config.optionMergeStrategies 添加一个同名的属性 ,但是这个属性值是一个函数,且没有返回值。然后打印vm实例对象会发现 $options 里面的 myOption 属性值 变成了undefined,函数没有返回值,那肯定是undefined。

 增加一个 返回值 abc,再来看看。

上面的例子只是做一个演示,表示这个 也可以 通过  Vue.config.optionMergeStrategies 来覆盖之前的 自定义 选项,同时还可以让自定义选项以自定义逻辑合并

Vue.config.optionMergeStrategies.myOption = function (toVal, fromVal) {
  // 接收两个参数,返回合并后的值,toVal - 现在定义的值,fromVal - 之前定义的值
  console.log(toVal, fromVal, "toVal, fromVal");
  return "aaaaaaa";
};

Vue.config.optionMergeStrategies 对象

 Vue.config.optionMergeStrategies 对象 中存在的属性之前说过了,就是 实例对象上的属性和方法。那这么多方法 在合并的时候都是怎么合并的呢?这个就需要去源码里面瞅一瞅了。

总结

总结:

1、mixin 混入是一个对象,对象的配置项就是 创建组件 时传入的 options 配置项

2、在组件内混入时,增加引入 mixin 对象,配置项中新增 mixins:['xxx']。全局混入时 Vue.mixin()

3、正常混入( 在组件中新增配置项 或在全局中使用 Vue.mixin()  ) 和  自定义混入的方式( new Vue() 中增加自定义项 或使用 Vue.config.optionMergeStrategies )还是存在区别的

4、混入的规则

  • 普通的js原始值(string,number,boolean等)直接覆盖,以组件值为主。
  • 对象的合并,如果合并双方都是对象,则使用递归的方式将其合并,以组件对象为主。
  • 对于函数,如果需要他们合并后都可以执行,则可以考虑将函数合并成数组,然后你可以将其包装成一个新函数,依次调用合并后数组中的函数。生命周期钩子函数就是这样,最后是先执行混入的钩子,在执行自己的钩子。
  • 如果合并的是一些特殊对象,不能递归合并,那么根据情况,你还可以使用原型链的方式进行合并。

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

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

相关文章

jmeter-断言

断言作用&#xff1a;让脚本自动化执行过程中&#xff0c;能够自动判定执行结果是否正确&#xff0c;需要添加断言 响应断言 添加方式&#xff1a;测试计划–》线程组–》HTTP请求–》(右键添加)断言–》响应断言 案例 请求:https://www.baidu.com 检查&#xff1a;让程序检查…

13.4 【Linux】使用者身份切换

使用一般帐号&#xff1a;系统平日操作的好习惯 尽量以一般身份使用者来操作Linux的日常作业。等到需要设置系统环境时&#xff0c; 才变换身份成为 root 来进行系统管理&#xff0c;相对比较安全。避免作错一些严重的指令&#xff0c;例如恐怖的“ rm -rf / ”。 用较低权限…

OpenTDF数据加密引擎

OpenTDF是Virtru公司的开源项目。 Virtru基于OpenTDF开发了用于google Workspace和Microsoft 365的相关数据安全产品。 简介 virtru公司基于opentdf开发挺多产品的,都是数据安全类产品。 能把opentdf开源,已经非常不容易了。 opentdf的代码看起来还是比较整齐和成熟的。…

flink写入到kafka 大坑解析。

1.kafka能不能发送null消息&#xff1f; 能&#xff01; 2 flink能不能发送null消息到kafka&#xff1f; 不能&#xff01; public static void main(String[] args) throws Exception {StreamExecutionEnvironment env StreamExecutionEnvironment.getExecutionEnvironment(…

mysql 第九章

目录 1.mha 搭建 2.总结 1.mha 搭建 主从同步&#xff1a; 安装 mha 软件&#xff1a; mha 模拟 vip 飘移、master 切换&#xff1a; 2.总结 mha 是一套优秀的 mysql 高可用环境下故障切换和主从复制的软件。mha 解决 mysql 单点的问题。mysql 故障切换过程中&#xff0c;mh…

Linux 学习记录57(ARM篇)

Linux 学习记录57(ARM篇) 本文目录 Linux 学习记录57(ARM篇)一、外部中断1. 概念2. 流程图框 二、相关寄存器1. GIC CPU Interface (GICC)2. GIC distributor (GICD)3. EXTI registers 三、EXTI 寄存器1. 概述2. 内部框图3. 寄存器功能描述4. EXTI选择框图5. EXTI_EXTICR1 &…

Qt Creator mainwindow.obj:-1: error: LNK2019

构建的时候报错&#xff1a; mainwindow.obj:-1: error: LNK2019: 无法解析的外部符号 "public: __thiscall mynotedig::mynotedig(class QWidget *)" (??0mynotedigQAEPAVQWidgetZ)&#xff0c;该符号在函数 "public: void __thiscall MainWindow::mynoteab…

C语言宏替换的注意事项

先思考一个问题&#xff1a; #include <string> #include <Windows.h>namespace ui { int MessageBox(HWND hwnd, const std::wstring &text, const std::wstring &caption,UINT flags) {UINT actual_flags flags;const wchar_t *text_ptr text.c_str();…

推荐 3 个实用的 GitHub 项目

本期推荐开源项目目录&#xff1a; 1. 开源知识库 2. 去中心化的社交平台 3. h2oGPT 01 开源知识库 AFFINE 是 Notion、Miro 等知识库产品的开源替代品&#xff0c;目前已经获得了近 20k 的 Stark。通过 AFFINE 你可以进行写作、绘画、计划管理。 类似于 Notion 的 Block &…

STC12C5A系列单片机片内看门狗的应用

wdt.c #include "wdt.h"void wdt_init(void) {WDT_CONTR 0x24; // 0010 0100 - 1.1377s }void wdt_feed(void) {WDT_CONTR | 0x10; // 喂狗 }wdt.h #ifndef _WDT_H_ #define _WDT_H_#include "stc12c5a60s2.h"// 函数声明 extern void wdt_init(void); …

Ajax 黑马学习

Ajax 资源 数据是服务器对外提供的资源,通过 请求 - 处理 - 响应方式获取 请求服务器数据, 用到 XMLHttpRequest 对象 XMLHttpRequest 是浏览器提供的js成员, 通过它可以请求服务器上的数据资源 let xmlHttpRequest new XMLHttpRequest(); 请求方式 : get向服务器获取数据…

requests---jsonpath在接口自动化中的应用

前言 我们在做接口测试时&#xff0c;大多数返回的都是json属性&#xff0c;我们需要通过接口返回的json提取出来对应的值&#xff0c;然后进行做断言或者提取想要的值供下一个接口进行使用&#xff0c;但是如果返回的json数据嵌套了很多层&#xff0c;通过查找需要的词&#x…

软件进行用户体验测试有哪些要点?

无论是移动应用还是网页应用&#xff0c;优秀的用户体验是软件成功的关键所在。软件用户体验测试是一种关键的测试方法&#xff0c;旨在评估用户在使用软件过程中的感受和体验。通过深入了解用户需求&#xff0c;模拟真实场景&#xff0c;以及综合用户反馈&#xff0c;软件开发…

【C++】C++11——右值引用和移动语义|可变参数模板

文章目录 一、左值引用和右值引用左值引用和右值引用的定义左值引用和右值引用的比较 二、右值引用的使用场景和意义左值引用的短板移动构造和移动赋值万能引用和完美转发 三、新的类功能类成员变量初始化default 和 delete 四、可变参数模板 一、左值引用和右值引用 传统的C语…

操作系统资源限制问题(Memory Analyzer使用OutOfMemoryError)

java8使用Memory Analyzer大概是10左右的版本&#xff0c;用最新版本要java17 MemoryAnalyzer-1.10.0.20200225-win32.win32.x86_64 MAT(Memory Analyzer Tool)下载 https://www.cnblogs.com/zwh0910/p/15774590.html Eclipse downloads - Select a mirror | The Eclipse F…

"科技与狠活"企业级无代码开发MES系统,一周实现数字化

随着科技的不断发展&#xff0c;企业级无代码开发平台成为了一种新型的解决方案&#xff0c;能够有效降低软件开发门槛&#xff0c;提升开发效率。在制造业领域&#xff0c;MES系统&#xff08;Manufacturing Execution System&#xff09;作为一种关键的生产管理工具&#xff…

小程序开发收费多少

一、小程序开发费用一览表 ① 域名费用 域名的价格取决于选择的域名类型&#xff0c;常见的有如.com、.cn等这些&#xff0c;以及注册商的定价策略。比如&#xff0c;一个.com 域名一年的的注册费用大约在 50-200 元人民币之间。 ②服务器费用 服务器费用是根据服务器的配置…

day37-Pokedex(神奇宝贝图鉴卡牌展示)

50 天学习 50 个项目 - HTMLCSS and JavaScript day37-Pokedex&#xff08;神奇宝贝图鉴卡牌展示&#xff09; 效果 index.html <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport&qu…

vscode默认gbk编码格式打开

目录 1. 问题描述2. 解决方案 1. 问题描述 每次打开vscode都是utf-8格式打开文件&#xff0c;然后满屏的中文乱码&#xff0c;自己手动换成gbk编码 后中文显示正常&#xff0c;但是换多了很烦。 2. 解决方案 ctrlshiftP 点首选项&#xff1a;打开用户设置 加上这行在最后&…

文件包含漏洞利用思路

简介 通过PHP函数引入文件时&#xff0c;传入的文件名没有经过合理的验证&#xff0c;从而操作了预想之外的文件&#xff0c;导致意外的文件泄漏甚至恶意代码注入。 常见的文件包含函数 php中常见的文件包含函数有以下四种&#xff1a; include()require()include_once()re…