微信小程序 - 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):驴妈妈景区门票即买即游
驴妈妈因为出色的运营能力,被腾讯选为首批小程序内测单位.驴妈妈的技术开发团队在很短的时间内完成了开发任务,并积极参与到张小龙团队的内测问题反馈.驴妈妈认为,移动互联网时代,微信是巨大的流量入口,也是旅 ...
随机推荐
- 更新后android studio 2.0 构建gradle卡在Refreshing Gradle Project 解决办法
首先打开android studio项目 找到项目目录gradle\wrapper\gradle-wrapper.properties这个文件 你会看到 #Wed Apr 10 15:27:10 PD ...
- angularjs中使用ng-bind-html和ng-include
下面这个例子,往div标签内添加html内容: <!doctype html> <html ng-app="myApp"> <head> < ...
- hdu 3065 AC自动机模版题
题意:输出每个模式串出现的次数,查询的时候呢使用一个数组进行记录就好. 同上题一样的关键点,其他没什么难度了. #include <cstdio> #include <cstring ...
- 取石子 (四)_nyoj_161(博弈-奇异矩阵).java
取石子 (四) 时间限制: 1000 ms | 内存限制: 65535 KB 难度: 4 描述 有两堆石子,数量任意,可以不同.游戏开始由两个人轮流取石子.游戏规定,每次有两种不同的取法,一是 ...
- tarjan+缩点+强连通定理
C - Network of Schools Time Limit:1000MS Memory Limit:10000KB 64bit IO Format:%I64d & %I ...
- 网站banner图片制作(简易版)
1.新建图层 根据baner需求,新建图层尺寸: 2.将图片拖进图层 按住shift对图片进行等比例缩放,将等比例缩放后的图片平铺到图层上. 3.添加文字 设置字体以及字体颜色 4.添加描边 选择文字 ...
- Patterns-Proxy
http://blog.csdn.net/jianghuxiaoxiami/article/details/3403924 1.代理模式 代理模式的作用是:为其他对象提供一种代理以控制对这个对象的访问 ...
- ubuntu——Kconfig、.config、Makefile的关系
原文地址:http://blog.csdn.net/estate66/article/details/5886816 ,本人对此文有改进. 当我们编写完一个驱动后,我们要把它以模块形式编译或者直接编译 ...
- ubuntu 14.04为/检查磁盘时发生严重错误的解决方法
http://jingyan.baidu.com/article/0aa22375bbffbe88cc0d6419.html
- OpenCV iOS开发(一)——安装(转)
OpenCV是一个开源跨平台的的计算机视觉和机器学习库,可以用来做图片视频的处理.图形识别.机器学习等应用.本文将介绍OpenCV iOS开发中的Hello World起步. 安装 OpenCV安装的 ...