vue computed 无法触发 set

vuex 是不允许被直接修改的,所以我使用computed get set 来完成这部分功能.如下图代码: console.log('set') 无法触发.
但是可以从vue-dev-tool看到c已经改变, 问题是: computed没有触发set,为什么c变量可以被改变

<script>
import Vue from 'vue'

export default Vue.component('AttributesContainer', {
  data () {
    return {
      html: ''
    }
  },
  render (h) {
    return h(Vue.extend({
      template: `
        <div class="AttributesContainer">
          ${this.html}
        </div>
      `,
      computed: {
        c: {
          get () {
            return this.$store.state.attrs[this.$store.state.activeAttrs]
          },
          set (val) {
            console.log('set')
            let attrs = this.$store.state.attrs
            let j = {}
            j[this.$store.state.activeAttrs] = val
            this.$store.commit('changeAttrs', window.Object.assign({}, attrs, j))
          }
        }
      }
    }))
  },
  computed: {
    content () {
      return this.$store.state.attrs[this.$store.state.activeAttrs]
    }
  },
  watch: {
    content: {
      handler () {
        let html = ''
        let c = this.content
        for (let i in c) {
          let item = c[i]
          if (i === 'name') continue
          if (i === 'id') continue
          html += '<div class="item">'
          html += `<div v-text="c['${i}'].desc"></div>`
          html += '<div class="content">'
          if (item.type === 'bool') {
            html += `<el-radio v-model="c['${i}'].default" label="">默认</el-radio>`
            html += `<el-radio v-model="c['${i}'].default" label="true">true</el-radio>`
            html += `<el-radio v-model="c['${i}'].default" label="false">false</el-radio>`
          } else if (item.type === 'number') {
            html += `<el-input-number v-model="c['${i}'].default"></el-input-number>`
          } else {
            html += `<el-input v-model="c['${i}'].default"></el-input>`
          }
          html += '</div>'
          html += '</div>'
        }
        this.html = html
      },
      deep: true
    }
  }
})
</script>

<style scoped>
  .AttributesContainer {
    width: 300px;
  }

  >>>.item {
    display: flex;
    flex-direction: column;
  }

  >>>.item>div {
    padding: 5px;
  }
</style>

clipboard.png

computed在vue-tool中确实被改变了, vuex数据却是没变。 computed中的依赖项是vuex数据啊, vuex数据没变的话,computed又为什么发生变化? 绝望中....

阅读 8.7k
1 个回答
export function defineComputed (
  target: any,
  key: string,
  userDef: Object | Function
) {
  const shouldCache = !isServerRendering()
  if (typeof userDef === 'function') {
    sharedPropertyDefinition.get = shouldCache
      ? createComputedGetter(key)
      : userDef
    sharedPropertyDefinition.set = noop
  } else {
    sharedPropertyDefinition.get = userDef.get
      ? shouldCache && userDef.cache !== false
        ? createComputedGetter(key)
        : userDef.get
      : noop
    sharedPropertyDefinition.set = userDef.set
      ? userDef.set
      : noop
  }
  if (process.env.NODE_ENV !== 'production' &&
      sharedPropertyDefinition.set === noop) {
    sharedPropertyDefinition.set = function () {
      warn(
        `Computed property "${key}" was assigned to but it has no setter.`,
        this
      )
    }
  }
  Object.defineProperty(target, key, sharedPropertyDefinition)
}

target 为vm
key 为'c'
所以userDef中的setter只有在给vm的c属性赋值的情况下才会触发

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题