diff --git a/example/app.json b/example/app.json index 588e5965..2f0f8b74 100644 --- a/example/app.json +++ b/example/app.json @@ -36,6 +36,5 @@ "navigationBarTextStyle": "black", "backgroundTextStyle": "dark", "backgroundColor": "#f8f8f8" - }, - "debug": true + } } diff --git a/example/pages/button/index.wxml b/example/pages/button/index.wxml index 9d4f8352..a47ef526 100644 --- a/example/pages/button/index.wxml +++ b/example/pages/button/index.wxml @@ -1,7 +1,7 @@ - 默认按钮 + 默认按钮 主要按钮 警告按钮 @@ -10,7 +10,7 @@ - 默认按钮 + 默认按钮 主要按钮 警告按钮 @@ -19,7 +19,7 @@ 大号按钮 - 普通按钮 + 普通按钮 小型按钮 迷你按钮 diff --git a/packages/button/index.js b/packages/button/index.js index 6596c4a3..a7f0a165 100644 --- a/packages/button/index.js +++ b/packages/button/index.js @@ -1,35 +1,37 @@ import { create } from '../common/create'; -import { classNames } from '../common/class-names'; import { button } from '../mixins/button'; -const booleanProp = { - type: Boolean, - observer: 'setClasses' -}; - create({ mixins: [button], props: { + plain: Boolean, + block: Boolean, + square: Boolean, + loading: Boolean, + disabled: Boolean, type: { type: String, - value: 'default', - observer: 'setClasses' + value: 'default' }, size: { type: String, - value: 'normal', - observer: 'setClasses' - }, - plain: booleanProp, - block: booleanProp, - square: booleanProp, - loading: booleanProp, - disabled: booleanProp + value: 'normal' + } }, - attached() { - this.setClasses(); + computed: { + classes() { + const { type, size, plain, disabled, loading, square, block } = this.data; + return this.classNames(`van-button--${type}`, `van-button--${size}`, { + 'van-button--block': block, + 'van-button--plain': plain, + 'van-button--square': square, + 'van-button--loading': loading, + 'van-button--disabled': disabled, + 'van-button--unclickable': disabled || loading + }); + } }, methods: { @@ -37,20 +39,6 @@ create({ if (!this.data.disabled && !this.data.loading) { this.$emit('click'); } - }, - - setClasses() { - const { type, size, plain, disabled, loading, square, block } = this.data; - this.setData({ - classes: classNames(`van-button--${type}`, `van-button--${size}`, { - 'van-button--block': block, - 'van-button--plain': plain, - 'van-button--square': square, - 'van-button--loading': loading, - 'van-button--disabled': disabled, - 'van-button--unclickable': disabled || loading - }) - }); } } }); diff --git a/packages/common/create.js b/packages/common/create.js index a6174a82..6d76447b 100644 --- a/packages/common/create.js +++ b/packages/common/create.js @@ -1,4 +1,5 @@ import { basic } from '../mixins/basic'; +import { observe } from '../mixins/observer/index'; export function create(sfc) { // map props to properties @@ -34,5 +35,6 @@ export function create(sfc) { sfc.behaviors.push('wx://form-field'); } + observe(sfc); Component(sfc); }; diff --git a/packages/mixins/basic.js b/packages/mixins/basic.js index b6532124..bad37d45 100644 --- a/packages/mixins/basic.js +++ b/packages/mixins/basic.js @@ -1,5 +1,9 @@ +import { classNames } from '../common/class-names'; + export const basic = Behavior({ methods: { + classNames, + $emit() { this.triggerEvent.apply(this, arguments); }, diff --git a/packages/mixins/observer/behavior.js b/packages/mixins/observer/behavior.js new file mode 100644 index 00000000..47e988c3 --- /dev/null +++ b/packages/mixins/observer/behavior.js @@ -0,0 +1,34 @@ +export const behavior = Behavior({ + created() { + if (!this.$options) { + return; + } + + const cache = {}; + const { setData } = this; + const { computed } = this.$options(); + const keys = Object.keys(computed); + + const calcComputed = () => { + const needUpdate = {}; + keys.forEach(key => { + const value = computed[key].call(this); + + if (cache[key] !== value) { + cache[key] = needUpdate[key] = value; + } + }); + + return needUpdate; + }; + + this.setData = (data, callback) => { + data && setData.call(this, data, callback); + setData.call(this, calcComputed()); + }; + }, + + attached() { + this.setData(); + } +}); diff --git a/packages/mixins/observer/index.js b/packages/mixins/observer/index.js new file mode 100644 index 00000000..0cba0aec --- /dev/null +++ b/packages/mixins/observer/index.js @@ -0,0 +1,14 @@ +import { behavior } from './behavior'; +import { observeProps } from './props'; + +export function observe(sfc) { + if (sfc.computed) { + sfc.behaviors.push(behavior); + sfc.methods = sfc.methods || {}; + sfc.methods.$options = () => sfc; + + if (sfc.properties) { + observeProps(sfc.properties); + } + } +} diff --git a/packages/mixins/observer/props.js b/packages/mixins/observer/props.js new file mode 100644 index 00000000..98871de1 --- /dev/null +++ b/packages/mixins/observer/props.js @@ -0,0 +1,25 @@ +export function observeProps(props) { + if (!props) { + return; + } + + Object.keys(props).forEach(key => { + let prop = props[key]; + if (!prop.type) { + prop = { type: prop }; + } + + let { observer } = prop; + prop.observer = function() { + if (observer) { + if (typeof observer === 'string') { + observer = this[observer]; + } + observer.apply(this, arguments); + } + this.setData(); + }; + + props[key] = prop; + }); +}