├── .gitignore ├── README.md ├── index.js ├── lib ├── index.js ├── observer.js └── util.js └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## simple-wxmp-vueify 2 | 3 | 4 | ### 介绍 5 | 6 | 既有项目无法重构,但想在某些页面的JS中使用vue的语法?不想手动调用小程序内的setData()?这个库可能帮你解决一些问题 7 | 8 | ### 特性 9 | 10 | - 支持在代码中使用this.xxx表示data属性 11 | - 支持计算属性 12 | - 支持响应式更新视图,不用手动setData 13 | ### 使用Demo 14 | 15 | 16 | ```bash 17 | $ git clone https://github.com/qk44077907/simple-wxmp-vueify.git 18 | ``` 19 | 之后文件夹拷贝至项目根目录 20 | ```javascript 21 | //你的路径 22 | import '/simple-wxmp-vueify/index.js' 23 | 24 | Page({ 25 | reactive: true,//在初始化页面时传入此字段,库将自动把页面转化为响应式 26 | data: { 27 | questionName: '', 28 | questionDesc: '', 29 | questionList: [ 30 | { 31 | content: '', 32 | }, 33 | { 34 | content: '', 35 | }, 36 | ], 37 | questionTypeList: ['单选', '多选'], 38 | questionTypeIndex: 0, 39 | }, 40 | computed: { 41 | questionType: function () { 42 | return this.questionTypeList[this.questionTypeIndex] 43 | } 44 | }, 45 | addItem() { 46 | this.questionList.push({ 47 | content: '', 48 | }) 49 | }, 50 | removeItem(e) { 51 | let index = e.target.dataset.index 52 | if (this.questionList.length <= 2) { 53 | return 54 | } 55 | this.questionList.splice(index, 1) 56 | } 57 | }); 58 | 59 | ``` 60 | 61 | wxml模板 62 | ```html 63 | 64 | 71 | 78 | 87 | 92 | 删除 93 | 94 | 99 | 添加 100 | 101 | 102 | 103 | ``` 104 | 105 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | import Page from './lib/index.js' 2 | export default Page -------------------------------------------------------------------------------- /lib/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by qiankun6 on 2018/6/9. 3 | */ 4 | 5 | import {observe, proxyData} from "./observer.js"; 6 | import {setNestedValue} from "./util.js"; 7 | 8 | const originPage = Page; 9 | function extend(options, key, func) { 10 | if (options[key]) { 11 | let originFunc = options[key]; 12 | options[key] = function (...args) { 13 | func.call(this, ...args); 14 | return originFunc.call(this, ...args) 15 | } 16 | } else { 17 | options[key] = function (...args) { 18 | return func.call(this, ...args) 19 | } 20 | } 21 | } 22 | 23 | Page = function (options) { 24 | if (options.reactive) { 25 | extend(options, "onLoad", function () { 26 | let pageInstance = this 27 | let render = function () { 28 | pageInstance.setData(pageInstance.data) 29 | } 30 | observe(pageInstance, 'data', render) 31 | if(pageInstance.computed){ 32 | proxyData.call(this, pageInstance.data, pageInstance.computed); 33 | } 34 | proxyData.call(this, pageInstance, pageInstance.data) 35 | }); 36 | let timer= null 37 | extend(options, "updateVM", function (e) { 38 | //节流,防止某些手机快速输入会更新上次data的bug 39 | clearTimeout(timer); 40 | timer = setTimeout(()=>{ 41 | let pageInstance = this 42 | let path = e.target.dataset.path; 43 | let value = e.detail.value; 44 | setNestedValue(pageInstance,path,value) 45 | },200) 46 | }); 47 | extend(options, "setNestedValue", function (path,value) { 48 | setNestedValue(this, path, value) 49 | }) 50 | } 51 | originPage(options); 52 | } 53 | export default Page -------------------------------------------------------------------------------- /lib/observer.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by qiankun6 on 2018/6/9. 3 | */ 4 | import { 5 | isObject, 6 | isFunction 7 | } from './util.js' 8 | 9 | let isRendering =false 10 | let isRenderInStack =false 11 | export function observe(origin,key,render) { 12 | let originData = origin[key] 13 | if(!isObject(originData)){ 14 | return 15 | } 16 | for(let childKey in originData){ 17 | let child = originData[childKey] 18 | if(isObject(child)){ 19 | observe(originData,childKey,render) 20 | } 21 | } 22 | let proxyObj = new Proxy(originData, { 23 | get: function(target, key, receiver) { 24 | return target[key]; 25 | }, 26 | set: function(target, key, value, receiver) { 27 | if(isRendering || target[key] === value){ 28 | return true 29 | } 30 | target[key] = value; 31 | observe(target,key,render) 32 | if(isRenderInStack){ 33 | return true 34 | } 35 | isRenderInStack = true 36 | Promise.resolve().then(()=>{ 37 | isRendering = true; 38 | render() 39 | isRendering = false; 40 | isRenderInStack = false; 41 | }) 42 | return true; 43 | }, 44 | }); 45 | origin[key] = proxyObj 46 | } 47 | 48 | export function proxyData(origin,data) { 49 | let context = this 50 | for(let key in data){ 51 | Object.defineProperty(origin,key,{ 52 | enumerable: true, 53 | configurable: true, 54 | get:function () { 55 | if(isFunction(data[key])){ 56 | return data[key].call(context) 57 | } 58 | return data[key] 59 | }, 60 | set:function (newVal) { 61 | data[key] = newVal 62 | } 63 | }) 64 | } 65 | return origin 66 | } 67 | 68 | 69 | -------------------------------------------------------------------------------- /lib/util.js: -------------------------------------------------------------------------------- 1 | export function isObject (obj){ 2 | return obj !== null && typeof obj === 'object' 3 | } 4 | 5 | export function isFunction (obj){ 6 | return Object.prototype.toString.call(obj) === '[object Function]' 7 | } 8 | 9 | const bailRE = /[^\w.$]/ 10 | export function setNestedValue(obj,path,value) { 11 | if (bailRE.test(path)) { 12 | return 13 | } 14 | let segments = path.split('.') 15 | for (let i = 0; i < segments.length-1; i++) { 16 | if (obj && isObject(obj[segments[i]])){ 17 | obj = obj[segments[i]] 18 | }else { 19 | throw new Error('error path: '+segments[i]) 20 | } 21 | } 22 | obj[segments[segments.length-1]] = value 23 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "simple-wxmp-vueify", 3 | "version": "1.0.3", 4 | "description": "a simple lib to let you code wechat miniprogram like vue", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [ 10 | "wechat", 11 | "miniprogram", 12 | "vueify" 13 | ], 14 | "author": "qk44077907", 15 | "license": "ISC" 16 | } 17 | --------------------------------------------------------------------------------