computedBehavior.js 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. import isEmpty from './isEmpty'
  2. import shallowEqual from './shallowEqual'
  3. const ALL_DATA_KEY = '**'
  4. const trim = (str = '') => str.replace(/\s/g, '')
  5. export default Behavior({
  6. lifetimes: {
  7. attached() {
  8. this.initComputed()
  9. },
  10. },
  11. definitionFilter(defFields) {
  12. const { computed = {} } = defFields
  13. const observers = Object.keys(computed).reduce((acc, name) => {
  14. const [field, getter] = Array.isArray(computed[name]) ? computed[name] : [ALL_DATA_KEY, computed[name]]
  15. return {
  16. ...acc,
  17. [field]: function(...args) {
  18. if (typeof getter === 'function') {
  19. const newValue = getter.apply(this, args)
  20. const oldValue = this.data[name]
  21. if (!isEmpty(newValue) && !shallowEqual(newValue, oldValue)) {
  22. this.setData({ [name]: newValue })
  23. }
  24. }
  25. },
  26. }
  27. }, {})
  28. Object.assign(defFields.observers = (defFields.observers || {}), observers)
  29. Object.assign(defFields.methods = (defFields.methods || {}), {
  30. initComputed: function(data = {}, isForce = false) {
  31. if (!this.runInitComputed || isForce) {
  32. this.runInitComputed = false
  33. const context = this
  34. const result = { ...this.data, ...data }
  35. Object.keys(observers).forEach((key) => {
  36. const values = trim(key).split(',').reduce((acc, name) => ([...acc, result[name]]), [])
  37. observers[key].apply(context, values)
  38. })
  39. this.runInitComputed = true
  40. }
  41. },
  42. })
  43. },
  44. })