d53a17cea5 | ||
---|---|---|
.. | ||
components | ||
pages | ||
utils | ||
README.md | ||
app.js | ||
app.json | ||
app.wxss | ||
project.config.json | ||
sitemap.json | ||
store.js |
README.md
omix
极小却精巧的小程序框架,对小程序入侵性几乎为零
5分钟精通
API
去中心化 API
create.Page(option)
创建页面,option.context 页面级别共享create.Component(option)
创建组件this.oData
操作页面或组件的数据(会自动更新视图)this.context
页面注入的 context,页面和页面所有组件可以拿到create.mitt()
事件发送和监听器
中心化 API
create(store, option)
创建页面, store 可跨页面共享create(option)
创建组件this.store.data
全局 store 和 data,页面和页面所有组件可以拿到, 操作 data 会自动更新视图create.emitter
事件发送和监听器,不同于 mitt() 每次会创建新的实例,emitter 是全局唯一,可以用于跨页面通讯
实战去中心化 API
页面
import create from '../../utils/create'
const app = getApp()
create.Page({
//页面级别上下文,跨页面不共享
context: {
abc: '公共数据从页面注入到页面的所有组件'
//事件发送和监听器,或者 create.mitt()
emitter: create.emitter
},
data: {
motto: 'Hello World',
userInfo: { },
hasUserInfo: false,
canIUse: wx.canIUse('button.open-type.getUserInfo')
},
...
...
onLoad: function () {
...
...
...
//监听事件
this.context.emitter.on('foo', e => console.log('foo', e) )
setTimeout(() => {
this.oData.userInfo = {
nickName: 'dnt',
avatarUrl: this.data.userInfo.avatarUrl
}
}, 2000)
setTimeout(() => {
this.oData.userInfo.nickName = 'dntzhang'
}, 4000)
}
})
这里需要注意,oData 必须直接操作 data 里定义好的数据才能直接更新视图,比如 nickName
一开始没有定义好,更新它是不会更新视图,只有通过下面代码执行之后,才能更新 nickName,因为 userInfo 的变更会自动监听 userInfo 内的所有属性:
this.oData.userInfo = {
nickName: 'dnt',
avatarUrl: this.data.userInfo.avatarUrl
}
当然你也可以直接在 data 里声明好:
data: {
motto: 'Hello World',
userInfo: { nickName: null },
...
组件
import create from '../../utils/create'
create.Component({
data: {
a: { b: Math.random() }
},
ready: function () {
//这里可以获取组件所属页面注入的 store
console.log(this.context)
//触发事件
this.context.emitter.emit('foo', { a: 'b' })
setTimeout(()=>{
this.oData.a.b = 1
},3000)
},
})
数组
import create from '../../utils/create'
import util from '../../utils/util'
create.Page({
data: {
logs: []
},
onLoad: function () {
this.oData.logs = (wx.getStorageSync('logs') || []).map(log => {
return util.formatTime(new Date(log))
})
setTimeout(() => {
this.oData.logs[0] = 'Changed!'
}, 1000)
}
})
这里需要注意,改变数组的 length 不会触发视图更新,需要使用 size 方法:
this.oData.yourArray.size(3)
其他
this.oData.arr.push(111) //会触发视图更新
//每个数组的方法都有对应的 pureXXX 方法
this.oData.arr.purePush(111) //不会触发视图更新
this.oData.arr.size(2) //会触发视图更新
this.oData.arr.length = 2 //不会触发视图更新
函数属性
data: {
motto: 'Hello World',
reverseMotto() {
return this.motto.split('').reverse().join('')
}
},
其中 reverseMotto 可以直接绑定在 wxml 里,motto 更新会自动更新 reverseMotto 的值。
mitt 语法
const emitter = mitt()
// listen to an event
emitter.on('foo', e => console.log('foo', e) )
// listen to all events
emitter.on('*', (type, e) => console.log(type, e) )
// fire an event
emitter.emit('foo', { a: 'b' })
// working with handler references:
function onFoo() {}
emitter.on('foo', onFoo) // listen
emitter.off('foo', onFoo) // unlisten
omix 为 mitt 新增的语法:
emitter.off('foo') // unlisten all foo callback
实战中心化 API
定义 store:
export default {
data: {
logs: []
}
}
定义页面:
import create from '../../utils/create'
import util from '../../utils/util'
import store from '../../store'
create(store, {
onLoad: function () {
this.store.data.logs = (wx.getStorageSync('logs') || []).map(log => {
return util.formatTime(new Date(log))
})
setTimeout(() => {
this.store.data.logs[0] = 'Changed!'
}, 1000)
setTimeout(() => {
this.store.data.logs.push(Math.random(), Math.random())
}, 2000)
setTimeout(() => {
this.store.data.logs.splice(this.store.data.logs.length - 1, 1)
}, 3000)
}
})
<view class="container log-list">
<block wx:for="{{store.logs}}" wx:for-item="log">
<text class="log-item">{{index + 1}}. {{log}}</text>
</block>
<view>
<test-store></test-store>
</view>
</view>
可以看到里面使用 test-store 组件, 看下组件源码:
import create from '../../utils/create'
create({
})
<view class="ctn">
<view>
<text>Log Length: {{store.logs.length}}</text>
</view>
</view>
喜欢中心化还是喜欢去中心化任你挑选,或者同一个小程序可以混合两种模式。