Vue Mixin 与微信小程序 Mixins 应用

摘要:
什么是Mixin?Mixin是一种用于实现高代码重用性的思想。您可以通过复制属性(即混合)来扩展代码可重用性的概念。VueMixins应用程序的官方解释是,混合是在Vue组件中分发可重用函数的一种非常灵活的方式。遍历Mixins数组,获取每个项,然后使用merge函数合并每个项。

什么是Mixin(混入)

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

1 const obj1 = {a:1,b:2,c:3,d:4,e:5};

2 const obj2 = {f:6,g:7,h:8,i:9,a:10};

3 let obj3 = {};

4Object.assign(obj3,obj1,obj2);

5console.log(obj3);

6// 输出结果 {"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 应用》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇VBA在32位下没问题,到64位异常报错Uploadify v3.2.1 参数说明下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

基于echarts的中国地图

HTML:<div style='100%x;height:600px;'></div>以下是echarts地图相关代码 dataList () {     // 初始化echarts实例     this.chinachart = echarts.init(document.getElementById('china_ma...

正则表达式实现跨行匹配

正则表达式(Regular expression)可用来检查文本中是否包含指定模式的字符串,通常是按行来处理(POSIX标准),因为.操作符通常不匹配换行符,如果要匹配多行怎么处理呢?本文介绍正则表达式跨行匹配实现方法。 目录 1. sed 命令删除多行 2. Python正则表达式匹配多行 ① re.DOTALL 或者 re.S 参数 ② 表达式...

Linux下安装mysql-5.7.30详细步骤

前言下面记录了我在Linux环境下安装Mysql的完整过程,实操记录,只为让更多人少踩坑,本次安装版本为:mysql-5.7.30,64位操作系统官网下载地址:mysql-5.7.30-el7-x86_64.tar.gz百度网盘地址:百度网盘地址 提取码:lyqh 1、安装前准备检测系统是否自带mysql [root@localhost /]# rpm -...

扩展Django中的分页

Django中封装了分页模块,定义了两个类分别是Paginator和Page。虽然可以满足一般的需求,但是稍想添加点新的功能就显得鸡肋,而且创建paginator类对象时需要传人所有的数据对象(由于django的惰性查询所以适用django),没有可移植性。 下面先在原分类模块基础上另外封装两个功能,分别实现设置页面最多显示页码数 和切换页码时保留原搜索条...

详细解释VB连接access几种方法数据库

在VB在,连接ACCESS数据库的方法主要表现在以下三种 使用ADO对象。通过编写代码訪问数据库 Connection 对象 ODBC数据源 使用ADO Data 控件高速创建数据库连接 有三种连接方法 Data Link文件 使用ODBC数据源名称 使用连接字符串 使用数据环境设计器创建数据库连接 首先加入环境引用。 然后...

Oracle千万级数据入库

Oracle千万级数据入库 最近在写一个解析文件数据(txt、json、csv)并插入到数据库中的脚本(基于Python和Oracle)。 刚开始做的时候就是只是用cx_Oracle模块连接数据库,建立insert SQL语句,然后循环给里面插。很简单也很容易就实现了。 后面就遇到了唯一一个问题。就是大数据的解析处理。刚开始我用的是一个50多M的json数...