[improvement] support computed (#557)

This commit is contained in:
neverland 2018-09-11 15:18:54 +08:00 committed by GitHub
parent c894adeff7
commit 406af0f8b5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 103 additions and 37 deletions

View File

@ -36,6 +36,5 @@
"navigationBarTextStyle": "black",
"backgroundTextStyle": "dark",
"backgroundColor": "#f8f8f8"
},
"debug": true
}
}

View File

@ -1,7 +1,7 @@
<demo-section>
<demo-block title="按钮类型" padding>
<view class="row">
<van-button type="default" custom-class="demo-margin-right">默认按钮</van-button>
<van-button custom-class="demo-margin-right">默认按钮</van-button>
<van-button type="primary">主要按钮</van-button>
</view>
<van-button type="warning" custom-class="demo-margin-right">警告按钮</van-button>
@ -10,7 +10,7 @@
<demo-block title="朴素按钮" padding>
<view class="row">
<van-button type="default" plain custom-class="demo-margin-right">默认按钮</van-button>
<van-button plain custom-class="demo-margin-right">默认按钮</van-button>
<van-button type="primary" plain>主要按钮</van-button>
</view>
<van-button type="warning" plain custom-class="demo-margin-right">警告按钮</van-button>
@ -19,7 +19,7 @@
<demo-block title="按钮尺寸" padding>
<van-button size="large" block custom-class="demo-margin-bottom">大号按钮</van-button>
<van-button size="normal" class="demo-margin-right">普通按钮</van-button>
<van-button class="demo-margin-right">普通按钮</van-button>
<van-button size="small" class="demo-margin-right">小型按钮</van-button>
<van-button size="mini">迷你按钮</van-button>
</demo-block>

View File

@ -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
})
});
}
}
});

View File

@ -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);
};

View File

@ -1,5 +1,9 @@
import { classNames } from '../common/class-names';
export const basic = Behavior({
methods: {
classNames,
$emit() {
this.triggerEvent.apply(this, arguments);
},

View File

@ -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();
}
});

View File

@ -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);
}
}
}

View File

@ -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;
});
}