微信小程序 - mixins
mixins 概念 可百度 参考 http://ask.seowhy.com/article/21007
大意和Python中的多重继承, java中的接口类似(java接口只是定义,实现需要子类自己写).
而JS中没有接口的概念, 利用对象的key遍历,并合并到子类(或者叫对象)中.
伪代码:
var mixin = { //混入对象包含一个方法
demoFunction(){
}
} ;
var PageOption = { //需要继承mixin的对象
};
//内部处理mixin的逻辑
processMixins(PageOption , mixin);
//最终得到的 PageOption
PageOption = {
demoFunction(){
}
};
mixins 可以有多个,遭遇名称冲突时的规则 见下图: vue的component可以简单理解为 微信小程序的PageOption

我们的框架中,mixins的处理,集中在 utils/BasePageOptionClass 中.并且暂时内置了2个 顶层mixin对象
/**
* 处理mixins
*/
function _processMixins__(actualOption){ var app = getApp();
var pageOption = actualOption.PageOption;
var mixins = pageOption.mixins||[]; mixins.unshift(basePage, basePageExt); var data={};
var methods = {};
var lifecycleMethods = {
"onLoad": [], "onReady": [], "onShow": [], "onHide": [], "onUnload": [],
"onPullDownRefresh": [], "onReachBottom": [], "onShareAppMessage": [], "onPageScroll": []
};
for (var i=0;i< mixins.length;i++){
var mixin = mixins[i];
var d = mixin.data;
if(d){
app.util.extend(data,d);
}
var keys=Object.keys(mixin);
for(key of keys){
if(key=="data")continue;
if (lifecycleMethods[key] ){ //生命周期函数
if (typeof mixin[key] =="function"){ //是函数
lifecycleMethods[key].push(mixin[key]); //先加入的mixin生命周期函数先执行
} else {//不是函数, 不在规范内, 作为属性,如果Page定义,舍弃,没有则并入
if (!actualOption[key]){ //防止mixin破坏页面定义
actualOption[key]=mixin[key];
}
}
}else{ //普通函数
actualOption[key] = mixin[key];
}
} }
//合并到Page定义的data
actualOption.PageOption.data = app.util.extend(data, actualOption.PageOption.data);
actualOption.PageOption.__lifecycleMethods = lifecycleMethods;
}
这样大致实现了 vue定义的冲突解决方案.
执行方法代码逻辑
// mixins 生命周期函数 执行方案,总是先执行
var __lifecycleMethods = actualOption.PageOption.__lifecycleMethods || {};
var __lifecycleMethod = __lifecycleMethods[key];
var mixinsRunsReturn = false;
if (__lifecycleMethod && __lifecycleMethod.length>0){
for (let ii = 0; ii < __lifecycleMethod.length;ii++){
try{
var ret = __lifecycleMethod[ii].apply($target, arguments);
if(ret===false){ //这里预留增加了 mixin方法的返回值,如果是false,那么逻辑终止
mixinsRunsReturn = true;
break;
}
}catch(err){
console.log("执行mixin函数报错",err);
throw err;
}
}
}
if (mixinsRunsReturn){
console.log("mixin函数返回false,执行被终止");
return;
}
/**
* 左划需要的事件
* wxss中 增加 @import "/style/modules/left_touch.wxss";
*
* 用法 Page页面增加
* let left_touch = require("../../../mixins/left_touch.js");
* PageOption 增加 mixins:[left_touch]
*
* wxml 示例
<view class='left_touch_block'>
<view class="items">
<view wx:for="{{list}}" wx:key="{{index}}" class="touch_block_item">
<view data-data_path="list[{{index}}]._txtStyle" bindtouchstart="_touchS" bindtouchmove="_touchM" bindtouchend="_touchE" data-index="{{index}}" style="{{item._txtStyle}}" class="inner touch_block_content">
<view>{{index}}</view>
<view>{{item.txt}}</view>
</view>
<view data-index="{{index}}" bindtap = "_btn_touched" class="inner touch_block_btn">删除</view>
</view>
</view>
</view> 其中 data-data_path 标志 数据的层级,用户 设置单项的_txtStyle 属性,此属性为插件内部使用,外部数据不需要初始化这个属性
_btn_touched 方法需要自己写,见下方代码示例部分,根据具体逻辑编写 本插件更多的是为了基本的排版和通用事件的编写 *
*/
var obj = { data:{
_delBtnWidth: 180 //删除按钮宽度单位(rpx)
},
onLoad: function (options) {
// 页面初始化 options为页面跳转所带来的参数
this._initEleWidth();
},
/**
* 触摸开始事件,记录 开始坐标
*/
_touchS: function (e) {
if (e.touches.length == 1) {
this.setData({
//设置触摸起始点水平方向位置
_startX: e.touches[0].clientX
});
}
},
/**
* 触摸移动中事件
* 构建简单动画, 即 删除按钮 动态展现
*/
_touchM: function (e) {
var that = this if (e.touches.length == 1) {
//手指移动时水平方向位置
var moveX = e.touches[0].clientX;
//手指起始点位置与移动期间的差值
var disX = this.data._startX - moveX;
var _delBtnWidth = this.data._delBtnWidth;
var txtStyle = "";
if (disX == 0 || disX < 0) {//如果移动距离小于等于0,文本层位置不变
txtStyle = "left:0px";
} else if (disX > 0) {//移动距离大于0,文本层left值等于手指移动距离
txtStyle = "left:-" + disX + "px";
if (disX >= _delBtnWidth) {
//控制手指移动距离最大值为删除按钮的宽度
txtStyle = "left:-" + _delBtnWidth + "px";
}
}
//获取手指触摸的是哪一项
var dataset = e.currentTarget.dataset;
var index = dataset.index; var data_path = dataset.data_path
var updateObject = {};
updateObject[data_path] = txtStyle;
this.setData(updateObject);
}
},
/**
* 触摸结束事件
* 结合触摸开始时的坐标,算出移动的距离
* 如果距离超出删除按钮的一半,那么 算是移动成功,展示全部删除按钮,否则 删除按钮隐藏
* 注意 更新数据方式,并不是网上示例的全部数据更新
*/
_touchE: function (e) {
var self= this;
if (e.changedTouches.length == 1) {
//手指移动结束后水平位置
var endX = e.changedTouches[0].clientX;
//触摸开始与结束,手指移动的距离
var disX = this.data._startX - endX;
var _delBtnWidth = this.data._delBtnWidth;
var index = e.currentTarget.dataset.index; var data_path = e.currentTarget.dataset.data_path;
var updateObject = {};
//如果距离小于删除按钮的1/2,不显示删除按钮
var txtStyle = "left:0px";
if( disX > _delBtnWidth / 2 ){
txtStyle = "left:-" + _delBtnWidth + "px"
if (self._lastMovedElePath) {
updateObject[self._lastMovedElePath] = "left:0px";
}
self._lastMovedElePath = data_path
} else{ }
//获取手指触摸的是哪一项 updateObject[data_path] = txtStyle; //更新列表的状态
this.setData(updateObject);
}
},
//获取元素自适应后的实际宽度
_getEleWidth: function (w) {
var real = 0;
try {
var res = wx.getSystemInfoSync().windowWidth;
var scale = (750 / 2) / (w / 2);//以宽度750px设计稿做宽度的自适应
// console.log(scale);
real = Math.floor(res / scale);
return real;
} catch (e) {
return false;
// Do something when catch error
}
},
_initEleWidth: function () {
var _delBtnWidth = this._getEleWidth(this.data._delBtnWidth);
this.setData({
_delBtnWidth: _delBtnWidth
});
},
/**
* 点击删除按钮事件
* 这是个示例方法,请在具体的页面Page中重写此方法逻辑
*/
_btn_touched: function (e) {
var that = this
wx.showModal({
title: '提示',
content: '是否删除?',
success: function (res) {
if (res.confirm) {
//获取列表中要删除项的下标
var index = e.target.dataset.index; // var list = that.data.list;
// //移除列表中下标为index的项
// list.splice(index, 1);
// //更新列表的状态
// that.setData({
// list: list
// });
} else {
//做页面重新渲染,或什么都不做
}
}
}) } };
module.exports= obj;
微信小程序 - mixins的更多相关文章
- Vue Mixin 与微信小程序 Mixins 应用
什么是Mixin(混入) Mixin是一种思想,用来实现代码高度可复用性,可以针对属性复制实现代码复用的想法进行一个扩展,就是混入(mixin).混入并不是复制一个完整的对象,而是从多个对象中复制出任 ...
- 微信小程序开发库grace vs wepy
grace和wepy都是辅助小程序开发的开源库,本文对两者做个对比. 注:本文是作者本人的一些拙见,纯粹的技术讨论,不想引起技术信仰之争,欢迎积极.正向的讨论及建议. 如果你还不了解Grace, 请参 ...
- 小程序开发过程中常见问题[微信小程序、支付宝小程序]
目录 一.样式中如何使用background-image呢? 二.使用自适应单位rpx类似于rem,布局尽量使用flex布局 三.万能的{{双大括号,用于在模版中输出变量 四.你想要的基础组件和API ...
- 微信小程序组件化实践
Do Not Repeat Yourself 如何提高代码质量,方法有许多:抽象.模块.组件化,我认为它们的中心点都是--Do Not Repeat Yourself. 小程序组件化 我们先看看小程序 ...
- 微信小程序开发中的二三事之网易云信IMSDK DEMO
本文由作者邹永胜授权网易云社区发布. 简介 为了更好的展示我们即时通讯SDK强悍的能力,网易云信IM SDK微信小程序DEMO的开发就提上了日程.用产品的话说就是: 云信 IM 小程序 SDK 的能力 ...
- 微信小程序 - toptip效果
在Page顶部下滑一个提示条 , 代码见 /mixins/UIComponent.js ,其中的self 可以认为是微信小程序的Page对象 效果: 默认2秒展示,上移动画隐藏 /** * 展示顶部 ...
- 微信小程序项目转换为uni-app项目
一.它是谁? [miniprogram-to-uniapp]转换微信小程序"项目为uni-app项目.原则上混淆过的项目,也可以进转换,因为关键字丢失,不一定会完美. 二.它的原理是什么? ...
- 微信小程序开发心得
微信小程序也已出来有一段时间了,最近写了几款微信小程序项目,今天来说说感受. 首先开发一款微信小程序,最主要的就是针对于公司来运营的,因为,在申请appid(微信小程序ID号)时候,需要填写相关的公司 ...
- 微信小程序体验(2):驴妈妈景区门票即买即游
驴妈妈因为出色的运营能力,被腾讯选为首批小程序内测单位.驴妈妈的技术开发团队在很短的时间内完成了开发任务,并积极参与到张小龙团队的内测问题反馈.驴妈妈认为,移动互联网时代,微信是巨大的流量入口,也是旅 ...
随机推荐
- 读TIJ -7 多形性
<Think in java·第 7 章 多形性> [面向对象的程序设计语言三种最主要的特征:数据抽象.继承和多态] 在这个层面是没有什么"思想"好谈的!当你依照人们 ...
- Discuz常见小问题-如何设置163邮箱注册验证
参考网址: https://jingyan.baidu.com/album/c843ea0b804a6e77931e4aa7.html?picindex=3 http://www.discuz.net ...
- python的加密模块(md5,sha,crypt)学习
python的加密模块(md5,sha,crypt)学习 命令行使用python MD5: yinguicai@Cpl-IBP-Product:~/data/work/svn/v1.4.0_dev/A ...
- HDoj-2095-与众不同
Problem Description In the new year party, everybody will get a "special present".Now it's ...
- ant design pro (四)新增页面
一.概述 参看地址:https://pro.ant.design/docs/new-page-cn 这里的『页面』指配置了路由,能够通过链接直接访问的模块,要新建一个页面,通常只需要在脚手架的基础上进 ...
- HDU 5361 In Touch (2015 多校6 1009 最短路 + 区间更新)
题目:http://acm.hdu.edu.cn/showproblem.php?pid=5361 题意:最短路.求源点到全部点的最短距离.但与普通最短路不同的是,给出的边是某点到区间[l,r]内随意 ...
- js&jquery 获取select下拉框的值、文本内容、自定义属性
js&jquery 获取select下拉框的值.文本内容.自定义属性 CreationTime--2018年7月2日09点22分 Author:Marydon html <selec ...
- c++实现医院检验科排班程序
c++实现医院检验科排班程序 1.背景: 医院急诊检验科24h×7×365值班.工作人员固定.採取轮班制度.确保24h都有人值班. 本文就通过C++实现编敲代码自己主动排班,并能够转为Excel打印. ...
- FastDFS简易概括
FastDFS是一个文件系统,可以部署在Linux上. 该文件系统具备高可用和负载均衡特性,还可以动态扩充容量. 此文件系统有两个服务组成:跟踪服务和存储服务,也就是说你必须部署了这两种服务,这个文件 ...
- beyond compare 与git diff整合
这两天花了点时间最终在Window和Mac上把Beyong Compare和git整合好.当中遇到到非常多坑,如今把这些都分享出来.希望对大家有帮助. 首先如果你已经装好了Beyong Compare ...