什么是Mixin(混入)

Mixin是一种思想,用来实现代码高度可复用性,可以针对属性复制实现代码复用的想法进行一个扩展,就是混入(mixin)。混入并不是复制一个完整的对象,而是从多个对象中复制出任意的成员并将这些成员组合成一个新的对象。

 const obj1 = {a:1,b:2,c:3,d:4,e:5};
const obj2 = {f:6,g:7,h:8,i:9,a:10};
let obj3 = {};
Object.assign(obj3,obj1,obj2);
console.log(obj3);
// 输出结果 {"a":10,"b":2,"c":3,"d":4,"e":5,"f":6,"g":7,"h":8,"i":9};

上面是一个对象混入,把两个对象,合并成一个对象,如果有相同属性存在则后者会覆盖原有的属性值,如果存在方法名相同同样会覆盖,因为在对象内部是以key来区分的,并且每个key是唯一的。

为什么要使用混入

Mixin的优点

混入可以减少程序中重复的功能,增强函数的复用性。当一个应用程序可能需要在各种对象中共享行为时,我们可以通过Mixin中维持这种共享功能并专注于程序中真正不同的功能,轻松避免任何重复,使项目结构更加清晰更加易于维护。

Mixin的缺点

Mixin是一种很灵活的代码复用方式,但把功能属性和方法导入,如果文件过多,会导致属性方法来源方面的不确定性,在大型系统中需要对项目文件的划分以及整体的掌控。

Vue Mixins 应用

官方解释

混入 (mixins) 是一种分发 Vue 组件中可复用功能的非常灵活的方式。混入对象可以包含任意组件选项。当组件使用混入对象时,所有混入对象的选项将被混入该组件本身的选项。

mixins.js

export default {
data: function () {
return {
message: 'hello',
foo: 'abc'
}
}
}

index.js

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

在实际项目中可以根据业务领域把相同的业务场景按文件进行划分,比如好多页面都需要插入/删除/更改,这些方法都是相同的,可以单独放在一个js文件里面去统一的管理。

再举一个例子,比如有很多页面里面都有表单,然而这些页面内的表单都需要方法去校验,每个页面都写一次的话,会导致大量的重复代码的出现,而且不易于管理,维护,我们可以把所有的表单的校验方法放在一个js文件里面导出去,哪些组件或者页面需要进行格式校验,使用mixin混入这些方法。即使是以后需要添加或者更改校验方法就直接更改这个js文件就好了。

唯一一点很重要的就是,混入的方法会覆盖掉之前页面内部的同名属性或方法。

官方文档:Vue Mixins 文档

小程序Mixins应用

小程序的Page并没有给出混入的API以及解方案,如果想要实现混入,需要自己封装Mixins方法,来实现对象方法以及属性的混入,达到代码的复用的目的。

Mixins实现

在小程序初始化使用App去创建每个页面,通过Page可以获取到创建页面时所需要的属性和方法,如果把Page看做是一个函数,然而在函数里面写的方法或者属性,其实都放在了一个对象里面,data也好方法也好其实都是这个对象里面唯一的属性和方法,为页面提供消费。

export let CreatePage = (obj) => {
let {mixins} = obj;
Reflect.deleteProperty(obj, 'mixins');
obj.data = obj.data || {};
mixins.forEach((el) => {
merge(el,obj)
})
return obj;
}
let merge = (el,obj) => {
let elKeys = Object.keys(el);
el.data = el.data || {};
elKeys.forEach((e) => {
e === "data" && Object.assign(obj.data,el.data);
(e !== "data") && (obj[e] = el[e]);
})
}

上面代码中创建了一个名为CreatePage的函数,函数接收了一个对象作为参数,然而这个对象就是我们在使用Page的时候传入供页面消费的对象,在对象内部添加了一个属性Mixins,这个属性是一个数组,里面的每一项都是需要混入到里面的属性和方法。遍历Mixins数组,获取到其中的每一项,使用merge函数把里面的每一项都进行合并。由于data是一个对象,直接和并可能会导致只有合并后的data数据,合并之前的数据丢失,所以做了判读如果遇到data就单独去处理data的合并。其他的属性或者方法直接合并到obj里面,最后把obj返回出去。

应用

index.js

// 引入mixin
import {CreatePage} from "../../utils/mixin.js";
// 引入静态数据 mixin1
import mixin1 from "../../mixins/public/mixin1.js";
Page(CreatePage({
mixins:[mixin1],
data:{
one:"我是index里面的数据"
},
a(){
console.log("我是a函数",this.data.two)
},
onLoad(){
this.a();
this.b();
}
}))

mixin1.js

module.exports = {
data:{
two:"我是Mixin里面的数据"
},
b(){
console.log("我是b函数",this.data.one)
}
}

通过这种方法可以把项目中业务重复的方法以及静态数据放到mixins文件中,统一管理统一维护。一旦项目需求发生变化更改一个地方就可以了,没有必要在成百行代码中找到某行代码,无疑是增加大量的查找以及修改的作业。

mixins 改进

let native = Page;
Page = (obj) => {
let {mixins = []} = obj;
let merge = new Merge();
Reflect.deleteProperty(obj, "mixins");
let pageData = mixins.length<=0?obj:merge.start(obj,...mixins);
native(pageData);
}
class Merge {
constructor(){}
start(rootObj,...objs){
let root = {};
objs.forEach((el) => {
root = Merge.recursive(rootObj,el);
})
return root;
}
static recursive = (rootObj,obj) => {
for(let attr in obj){
if(rootObj[attr] === undefined){
rootObj[attr] = obj[attr];
}
else if(Merge.isObject(obj[attr])){
Merge.recursive(rootObj[attr],obj[attr])
}
else{
rootObj[attr] = obj[attr];
}
}
return rootObj;
}
static isObject = (obj) => {
return Object.prototype.toString.call(obj).includes("Object");
}
}

在第一种方法上做了进一步的改进,上面的代码中首先存储了一份Page函数,然后获取到Page里面的参数进行深度拷贝处理,深度拷贝完毕之后,把拷贝后的对象return出去。把存储的Page执行一下,最后把合并后的data传进去就好了。

改进应用

index.js

// 引入静态数据 mixin1
import mixin1 from "../../mixins/public/mixin1.js";
Page({
mixins:[mixin1],
data:{
one:"我是index里面的数据"
},
a(){
console.log("我是a函数",this.data.two)
},
onLoad(){
this.a();
this.b();
}
})

mixin1.js

module.exports = {
data:{
two:"我是Mixin里面的数据"
},
b(){
console.log("我是b函数",this.data.one)
}
}

改进之后无需再使用createPag函数,之前使用Page的时候,使用方法是一样的,只是里面添加一个`mixins`属性而已,用来混入那些公用的属性或者方法。

优点

代码改进后不仅仅只有Page可以使用呢mixins,`Component`也可以通过上面的方法,重新改写一下`Component`在组件中使用mixins。

总结

随然mixins模式,使代码变得复用性很强,但是任何事物都有两面性,如果只是为了应用而应用的话很可能会适得其反,没有达到理想的效果。个人认为,强大的文档有助于将与混入函数来源有关的困惑减至最低,但对于每一种模式,如果在实现期间多加注意,多做考虑,一定会应用的很顺利的。

Vue Mixin 与微信小程序 Mixins 应用的更多相关文章

  1. 像VUE一样写微信小程序-深入研究wepy框架

    像VUE一样写微信小程序-深入研究wepy框架 微信小程序自发布到如今已经有半年多的时间了,凭借微信平台的强大影响力,越来越多企业加入小程序开发. 小程序于M页比相比,有以下优势: 1.小程序拥有更多 ...

  2. 用Vue.js开发微信小程序:开源框架mpvue解析

    前言 mpvue 是一款使用 Vue.js 开发微信小程序的前端框架.使用此框架,开发者将得到完整的 Vue.js 开发体验,同时为 H5 和小程序提供了代码复用的能力.如果想将 H5 项目改造为小程 ...

  3. MPVUE - 使用vue.js开发微信小程序

    MPVUE - 使用vue.js开发微信小程序 什么是mpvue? mpvue 是美团点评前端团队开源的一款使用 Vue.js 开发微信小程序的前端框架.框架提供了完整的 Vue.js 开发体验,开发 ...

  4. 微信小程序 - mixins

    mixins 概念 可百度  参考 http://ask.seowhy.com/article/21007 大意和Python中的多重继承, java中的接口类似(java接口只是定义,实现需要子类自 ...

  5. 移动端 | Vue.js对比微信小程序基础语法

    (1)vue 自定义组件与父组件的通信,props:[abb],可以看成自组建的一个自定义属性 (2)vue 模版语法{{}} 只能是在DOM中插入,<div>{{acc}}</di ...

  6. VUE(uni-app)+SSM 微信小程序

    环境 jdk:1.8.0_181 tomcat:7.0.100 mysql:8.0.25 工具 ideaIU+Hbuilder 遇到的问题 1.需要跳转到注册在tobar中页面时,需使用 uni.sw ...

  7. mpvue-docs基于vue来开发微信小程序

    http://mpvue.com/和https://tencent.github.io/wepy/

  8. 使用uni-app(Vue.js)创建运行微信小程序项目步骤

    使用uni-app(Vue.js)开发微信小程序项目步骤 1. 新建一个uni-app项目   创建完成后的目录结构 2. 打开微信小程序开发工具端的端口调试功能 3. 运行创建的项目 效果

  9. 微信小程序周报(第十三期)-极乐商店(store.dreawer.com)出品

    重要:极乐商店域名变更:wxapp.dreawer.com/变更为store.dreawer.com/ 每周一笑 当年刚学打篮球的时候,疯狂地迷恋上了乔丹,然后迷恋上了NIKE,更熟记了NIKE的那句 ...

随机推荐

  1. BZOJ_3747_[POI2015]Kinoman_线段树

    BZOJ_3747_[POI2015]Kinoman_线段树 Description 共有m部电影,编号为1~m,第i部电影的好看值为w[i]. 在n天之中(从1~n编号)每天会放映一部电影,第i天放 ...

  2. python接口自动化(二十五)--unittest断言——下(详解)

    简介 本篇还是回归到我们最初始的话题,想必大家都忘记了,没关系看这里:传送门  没错最初的话题就是登录,由于博客园的登录机制改变了,本篇以我找到的开源免费的登录API为案例,结合 unittest 框 ...

  3. WebGL three.js学习笔记 使用粒子系统模拟时空隧道(虫洞)

    WebGL three.js学习笔记 使用粒子系统模拟时空隧道 本例的运行结果如图: 时空隧道demo演示 Demo地址:https://nsytsqdtn.github.io/demo/sprite ...

  4. Java转Ruby【快速入门】

    最近参加实习了,公司的技术栈中需要用到 Ruby 以及 Rails 框架,所以算是开始了踩坑之旅吧.. Ruby 简介 网上的简介要搜都能搜到,具体涉及的包括历史啦之类这里不再赘述,提几个关键词吧: ...

  5. 【转】超酷的 mip-infinitescroll 无限滚动(无限下拉)

    写在前面 无限滚动技术(又叫做无限下拉技术)被广泛应用于新闻类,图片预览类网站.对用户来讲,使用无限滚动的页面有源源不断的信息可以预览,增加用户在页面的停留时长.技术上原理也很简单,在页面加载时加载一 ...

  6. Apache Mina-1

    一.mina基础知识: Mina 官方网站:(http://mina.apache.org/) 1.1.Apache Mina是一个能够帮助用户开发高性能和高伸缩性网络应用程序的框架.它通过Java ...

  7. Java开发必须掌握的线上问题排查命令

    作为一个合格的开发人员,不仅要能写得一手还代码,还有一项很重要的技能就是排查问题.这里提到的排查问题不仅仅是在coding的过程中debug等,还包括的就是线上问题的排查.由于在生产环境中,一般没办法 ...

  8. GC参考手册 —— GC 调优(命令篇)

    运用jvm自带的命令可以方便的在生产监控和打印堆栈的日志信息帮忙我们来定位问题!虽然jvm调优成熟的工具已经有很多:jconsole.大名鼎鼎的VisualVM,IBM的Memory Analyzer ...

  9. Python3|ddt|unittest|浅议数据驱动测试

    目录 1.DDT简介 2.data装饰器 3.unpack装饰器 4.file_data装饰器 5.总结 1.DDT简介 Data-Driven Tests(DDT)即数据驱动测试.它允许您通过不同的 ...

  10. 给WEB初学者一些有效率的建议

    因为IT互联网发展的非常迅速,而web前端这块很火,目前工资水平给的很高,在市场上也是非常的稀缺人才,现在各个行业转行做web前端的很多,今天给大家一些建议,希望新手少走点弯路吧! 建议一:有一个比较 ...