Code Monkey home page Code Monkey logo

computed's People

Contributors

2hu12 avatar aweikalee avatar chenzhutian avatar dependabot[bot] avatar itsryanwu avatar juneandgreen avatar lastleaf avatar sgly avatar tttrz avatar zhj135 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

computed's Issues

v2.0.2 如果 `data` 中的值是 `object`,`computed` 中的方法,无法获取该值(返回该值为`{}`)

如果 data 的一个值是 object, 从 computed 中定义的方法,传入的 data 获取该值,一直为 {}。比如下面这样的例子:

data 中有一个 child

data: {
  child: {
    key: value
  }
}

computed 方法中想要获取 data.child,只会得到 {}

computed: {
  computedChild (data) {
    console.info(data.child)
    return data.child
  }
}

用 README 里提供的代码片段做了简单修改跑了下(定义了 data.c,尝试从 computed 的函数中获取该 data.c),如图 console 返回 {}

Screenshot 2019-09-11 16 33 17

v4 版本存在于外部组件库中并引入当前项目后页面无法渲染

在项目源码中使用 v4 无问题,在我这边由 npm 管理的外部组件库中同样会使用 computed behavior。

经过一系列对比测试后发现,一旦当前小程序页面引用了来自 miniprogram_npm 的外部组件并且该组件使用了 computed behavior 时,页面无法渲染并且无任何报错信息。

在升级至 v4 之前一直用使用的 v2,升级之前各方面工作正常。

更新一:新增 v3 作为测试项后发现 v2, v3 均不会导致页面无法渲染,只有 v4 不正常

更新二:v3 虽然可以使页面渲染,但是页面内部的某个 setData 无法触发视图更新,无报错,未知原因。所以我还是退到了 v2,退回后一切正常。

总结:v2, v3, v4 各自有着自己的 bug,但 v2 最为稳定(除了无法 track 到另外的自定义 behavior 里面的 data)

第二次进入时computed属性无效

在含有computed计算属性的页面,第一次进入时都正常计算,如果马上返回,再次进入时,计算属性就无法计算,发现是behavis里的computedCache里缓存了在第一次打开页面时的computed属性值,但第二次进入时,页面的data会初始化,页面上的computed是没有值的,因此造成第二次及之后打开此页面computed属性无效的问题。

数组变成对象的bug

data:{
a:[{...},{...},{...}]
},
computed:{
b(data){
return data.a
}
}

这里的b会变成{0:{...},1:{...},2:{...}}

properties 未考虑null的情况

const getDataDefinition = function (data, properties) {
  const ret = {}
  Object.keys(data).forEach((key) => {
    ret[key] = data[key]
  })
  if (properties) {
    Object.keys(properties).forEach((key) => {
      let value = null
      const def = properties[key]
      const typeIndex = TYPES.indexOf(def)
      if (typeIndex >= 0) {
        value = TYPE_DEFAULT_VALUES[typeIndex]
      } else if (def.value) {
        value = def.value
      } else {
        const typeIndex = TYPES.indexOf(def.type)
        if (typeIndex >= 0) {
          value = TYPE_DEFAULT_VALUES[typeIndex]
        }
      }
      ret[key] = value
    })
  }
  return ret
}

properties 是可以设置为null的 如果是null的时候 def.value 就会报错

可以在计算属性中使用其他计算属性吗?

计算属性再引用其他计算属性就会出现数据不一致的BUG

computed: {
    store() {
      if (this.data.cartItem) {
        return this.data.cartItem.total - this.data.sales;
      }
      return 0;
    },
    maxCountLimit() {
      if (this.data.cartItem) {
        const {
          limitByUser
        } = this.data.cartItem;
// 重点在这里  这里我不用计算属性则没问题
        const { userBuy ,store} = this.data;
        // const store = this.data.cartItem.total - this.data.sales;
        console.debug(store, this.data.cartItem.total, this.data.sales);
        return limitByUser ? Math.min(store - limitByUser - userBuy, limitByUser - userBuy) : store;
      }
      return 1;
    },
    canPlus() {
      if (this.data.cartItem) {
        const {
          count,
        } = this.data.cartItem;
        return count < this.data.maxCountLimit;
      }
      return false;
    },
    
    canMinus() {
      if (this.data.cartItem) {
        const {
          count
        } = this.data.cartItem;
        return count > 1;
      }
      return false;
    }
  }

在测试用例中, 为什么预期computed运行了两次?

具体是这个用例:
https://github.com/wechat-miniprogram/computed/blob/master/test/index.test.js#L323

这里预期 expect(func2TriggeringCount).toBe(2), 请问是为什呢? 我自己看的话总感觉d只被算了一次
我自己用ts实现了一遍, 现在在补测试用例, 这个用例一直返回只算了一次
谢谢

test('computed chains', () => {
  let func1TriggeringCount = 0
  let func2TriggeringCount = 0
  const componentId = _.load({
    template: '<view>{{a}}+{{b}}={{c}}, {{a}}+{{c}}={{d}}</view>',
    behaviors: [computedBehavior],
    data: {
      a: 1,
      b: 2,
    },
    computed: {
      c(data) {
        func1TriggeringCount++
        return data.a + data.b
      },
      d(data) {
        func2TriggeringCount++
        return data.a + data.c
      }
    }
  })
  const component = _.render(componentId)
  component.triggerLifeTime('attached')
  expect(_.match(component.dom, '<wx-view>1+2=3, 1+3=4</wx-view>')).toBe(true)
  expect(func1TriggeringCount).toBe(1)
  expect(func2TriggeringCount).toBe(2)

  ...
})

behavior 嵌套使用时 computed data 不会在初始视图中渲染

自定义 behavior A 使用 computed behavior 后,page/component 再使用该 behavior A,computed data 不会在视图中渲染,

但是可以在 instance.data 里找到该 computed data, 也可以在 onReady 等方法中 log 出该 data

目前我自己试出来的指标不治本的解决方案有两个

  1. 声明一个和 computed data 同 key name 的 data 在 behavior A 中

2.在 behavior A 中的 onReady 方法里 this.setData({computedDataA: this.data.computedDataA})

你好,使用npm安装报错

操作步骤重现:

按照示例npm install --save miniprogram-computed安装:

$ npm install --save miniprogram-computed
npm WARN saveError ENOENT: no such file or directory, open 'D:\work-code\codewx\xxx\package.json'
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN enoent ENOENT: no such file or directory, open 'D:\work-code\codewx\xxx\package.json'
npm WARN xxx No description
npm WARN xxx No repository field.
npm WARN xxx No README data
npm WARN xxx No license field.

+ [email protected]
added 1 package from 1 contributor and audited 1 package in 1.666s
found 0 vulnerabilities

微信小程序

构建npm,报错‘没有找到 node_modules 目录。’
不死心的用淘宝镜像源再安装一遍:cnpm install --save miniprogram-computed,这回可以正常构建了,
继续打开右侧详情【使用npm模块】也可以
最后写代码编译报错:

VM2638:1 thirdScriptError 
 sdk uncaught third Error 
 module "components/pullup/miniprogram-computed" is not defined 
 Error: module "components/pullup/miniprogram-computed" is not defined

能告诉我这是为什么吗?

关于纯数据字段的处理

开发过程种发现computed可以根据纯数据字段计算出值,而watch则不能监测纯数据字段的变化。

TypeScript环境,npm安装构建完毕后,报错“../rfdc" is not defined”。

无法和自定义 behavior 一起使用嘛?

index.js

const computedBehavior = require('miniprogram-computed');
const testBehavior = require('./test.behavior');


Component({
  behaviors: [testBehavior, computedBehavior],
  data: {

  },
  computed: {
    c(data) {
      return data.a + data.b;
    }
  },
  methods: {
  }
})

test.behavior.js

module.exports = Behavior({
  data: {
    a: 1,
    b: 2
  }
})

这个时候 c 获取不到 data 值。是有什么特别的引用方式吗?

单元测试期望值疑问

test('computed property changes', () => {
  let funcTriggeringCount = 0
  const innerComponentId = _.load({
    template: '<view>{{a}}+{{b}}={{c}}</view>',
    behaviors: [computedBehavior],
    properties: {
      a: {
        type: Number,
        value: -1,
      },
      b: String,
    },
    computed: {
      c(data) {
        funcTriggeringCount++
        return data.a + data.b
      }
    },
  })
  const outerComponentId = _.load({
    usingComponents: {
      inner: innerComponentId,
    },
    data: {
      a: 1,
      b: 2,
    },
    template: '<inner a="{{a}}" b="{{b}}"></inner>',
  })
  const component = _.render(outerComponentId)

  expect(_.match(component.dom, '<inner><wx-view>1+2=3</wx-view></inner>')).toBe(true)
  // 比较有疑问的是为什么这里是2 
  expect(funcTriggeringCount).toBe(2)

  component.setData({a: 100, b: 200})
  expect(_.match(component.dom, '<inner><wx-view>100+200=300</wx-view></inner>')).toBe(true)
  expect(funcTriggeringCount).toBe(3)
})

mobx store里的数组数据不能用于computed? 初始化也取不到mobx数据

我发错repo了, 在这里重发一遍
复现例子:
https://developers.weixin.qq.com/s/hgT6RCmL7Fkm

accounts是store里的一个数组

export const store = observable({

  // 数据字段
  numA: 4,
  numB: 5,
  accounts: [4, 5, 6],

  add: action(function() {
    this.accounts = [1, 2, 3]
  }),

  // actions
  update: action(function () {
    this.numA = this.numA + 1
    this.numB = this.numA + 1
  })

})

当启动的时候, 会报一个bug说

VM824:1 MiniProgramError
data.accounts.reduce is not a function
TypeError: data.accounts.reduce is not a function
    at sum (http://127.0.0.1:63254/appservice/index/components/computed-example.js:17:28)
    at http://127.0.0.1:63254/appservice/components/index.js:392:21
    at Array.forEach (<anonymous>)
    at Ge.created (http://127.0.0.1:63254/appservice/components/index.js:385:34)
    at r.safeCallback (http://127.0.0.1:63254/appservice/__dev__/WAService.js:2:1775504)
    at r.call (http://127.0.0.1:63254/appservice/__dev__/WAService.js:2:1775397)
    at Function.M._advancedCreate (http://127.0.0.1:63254/appservice/__dev__/WAService.js:2:1823182)
    at r.createComponent (http://127.0.0.1:63254/appservice/__dev__/WAService.js:2:1834383)
    at e (http://127.0.0.1:63254/appservice/__dev__/WAService.js:2:1919566)
    at e (http://127.0.0.1:63254/appservice/__dev__/WAService.js:2:1920093)
Component({
  behaviors: [behaviorTest, storeBindingsBehavior, computedBehavior],
  computed: {
    sum(data) {
      console.log(data.accounts)
      return data.accounts.reduce((s, o) => s + o, 0)
    },
  },
  data: {
    a: 1,
    b: 1,
  },
  storeBindings: {
    store,
    fields: ['numA', 'numB','accounts'],
    actions: {
      buttonTap: 'add'
    },
  },

  methods: {
    onTap() {
      console.log(this.data.accounts[0], this.data.accounts.reduce((s, o) => s + o, 0))
      this.buttonTap()
    }
  }
})

computedCache导致的bug

由于computedCache在同一component类型间共享,当同一页面使用多个同一类型的component,且component的某个computed出现相同值时,会出现bug

解决方案如下:
因为eslint的原因 pr就不提了,贴出完整重构过的代码

// 计算 computed
const calcComputed = function () {
    const data = this.data = this.data || {}
    const computed = data._computed || {}
    const computedKeys = Object.keys(computed)
    const needUpdate = {}

    for (let i = 0, len = computedKeys.length; i < len; i++) {
        const key = computedKeys[i]
        const getter = computed[key]

        if (typeof getter === 'function') {
            const value = getter.call(this)

            this._computedCache = this._computedCache || {}
            if (this._computedCache[key] !== value) {
                needUpdate[key] = value
                this._computedCache[key] = value
            }
        }
    }

    return needUpdate
}

module.exports = Behavior({
    lifetimes: {
        attached() {
            this._originalSetData = this.setData
            this.setData = this._setData
            this.setData({})
        }
    },
    definitionFilter(defFields) {
        const computed = defFields.computed || {}

        defFields.data = defFields.data || {}
        defFields.data._computed = computed

        defFields.methods = defFields.methods || {}
        defFields.methods._setData = function (data, callback) {
            const originalSetData = this._originalSetData

            if (this._doingSetData) {
                // eslint-disable-next-line no-console
                console.warn('can\'t call setData in computed getter function!')
                return
            }

            this._doingSetData = true

            // TODO 过滤掉 data 中的 computed 字段
            const dataKeys = Object.keys(data)
            for (let i = 0, len = dataKeys.length; i < len; i++) {
                const key = dataKeys[i]

                if (computed[key]) delete data[key]
            }

            // 做 data 属性的 setData
            originalSetData.call(this, data, callback)

            // 计算 computed
            const needUpdate = calcComputed.call(this)

            // 做 computed 属性的 setData
            originalSetData.call(this, needUpdate)

            this._doingSetData = false
        }
    }
})

XX is not found

demo 导入项目,根本打不开!!!!!!!!!!

新版本无法使用westore了

1.0.0版以下同一个自定义组件可以使用store和computed,computed可以监听store注入的data。2.0.x版本莫名其妙地不会监听store注入的data,也会让westore的this.update函数报错。希望可以兼容更多的主流开发环境

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.