vue computed计算属性显示undefined的解决
作者:小小菜鸟在加油
这篇文章主要介绍了vue computed计算属性显示undefined的解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
vue computed计算属性显示undefined
在做三级联动菜单页面的时候,之前的几个报错都解决了,终于没有报错了,控制台干干净净,最后菜单却没显示出来,用vue开发者工具一看,三级联动的模块里,计算属性显示undefined。
在计算属性里console了一下,数组什么的都能在控制台输出,发现数据明明是传过来了的,
尴尬,原来是搞各种bug,console来console去的把计算属性的return整没了。
computed:{ ...mapState({ categoryList:(state)=>{ // console.log(state.home.categoryList) state.home.categoryList } }) }
加上return就恢复了。
computed:{ ...mapState({ //state的括号可以去掉,函数的大括号可以去掉 categoryList:(state)=>{ // console.log(state.home.categoryList); return state.home.categoryList; } }) }
nice,我是伞兵。
vue computed 使用避坑
其实不是 computed 的坑,是我自己没弄清原理瞎用,导致出现各种问题。。
<template> <section> <input type="button" value="查看三个list的值" @click="lookOneLook" /> <div> list1: <span v-for="(o, index) in list1" :key="'list1' + index"> {{ o }} </span> </div> <div> list2: <span v-for="(o, index) in list2" :key="'list2' + index"> {{ o }} </span> <input type="button" value="向list2中push" @click="list2.push(5)" /> </div> <div> list3: <span v-for="(o, index) in list3" :key="'list3' + index"> {{ o }} </span> <input type="button" value="向list3中push" @click="list3.push(6)" /> </div> </section> </template>
<script> export default { computed: { list2: { get() { return this.list1; }, set(val) { alert("触发list2的setter"); this.list1 = val; }, }, list3: { get() { return this.list1.map((o) => o); }, set(val) { alert("触发list3的setter"); this.list1 = val; }, }, }, data() { return { list1: [1, 2, 3, 4], }; }, methods: { lookOneLook() { alert(` list1 : ${this.list1} list2 : ${this.list2} list3 : ${this.list3}`); }, }, }; </script>
list2.push 和 list3.push 都没有触发的 computed setter。对于引用类型的计算属性,只有 list2=...
这样修改引用地址,才会触发 setter
list2.push()
:能成功修改三个list的值。因为 list2 和 list1 是相同的引用地址,list2.push 此时等价于 list1.push。list1变化后触发list3变化list3.push()
:能成功修改自己,但是数据变化没有触发视图的自动更新。是因为 computed 只是个 Watcher,自身没有绑定依赖,值变化不会触发视图的更新。所以在页面中看不到 list3 变化,只能在弹窗中看到 list3 的变化(因为弹窗是每次点击后当场取值的)- 又
list2.push
:此时list3 又变回去了
反思
对于引用类型的计算属性,只有 list2=… 这样修改引用地址,才会触发 setter
计算属性自己只是个 Watcher,不是像 props 和 data 那样的数据。所以绝对不要在计算属性上加自定义的属性,因为没有意义:
1. 它不是对象,没有依赖关系。数据变化,"依赖"不会更新
2. computed 内部关联的变量一旦变化,computed 的值就会重新计算,你自己添加的属性的修改就都没了。
下面的写法一有效,是因为引用相同,相当于什么都没干就是单纯起了个别名。这种起别名的操作以后少干,因为逻辑上很不清晰,复杂的工程中出了 bug 不好调。
computed:{ options:{ // 写法一:test() 有效,是因为 this.options 和 this.userObj.options 是相同引用 return this.userObj.options; /** 写法二:test() 无效 return { name :this.userObj.options.name };*/ } } methods:{ test(){ this.options.name='1'; } }```
computed 本质就是一个有 value 的 Watcher,别把它当数据用!!!
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。