今天写项目时遇到的问题,瞬间就卡在那了
来还原一下:
parent.vue:
<template> <div> <button @click="change">change</button> <input type="text" v-model="list" name=""> <child v-for="item in list" :key="item.id" :list="item.list"></child> </div> </template> <script> import child from './child.vue' export default { name: 'parent', data () { return { list:[{id:1,type:1},{id:2,type:2},{id:3,type:3}] } },methods:{ change(){ console.log(this) console.log(this.$set) setTimeout(()=>{ this.list[1]['list'] = {a:1,b:2,c:3} },1000) } }, components:{ child }, watch:{ // list:{ // handler: function (val, oldVal) { console.log(val,oldVal) }, // deep: true // } },computed:{ // test:function(){ // console.log(this.list) // return this.list // } } } </script> <style scoped> </style>
child.vue
<template> <div class="border"> {{list.a}}<br /> {{list.b}}<br /> {{list.c}} </div> </template> <script> export default{ props:{ list:{ default:()=>{return{a:0,b:0,c:0}} } }, data(){ return{ // newList:this.list } }, computed:{ // newList:()=>{ // console.log(this.list) // return this.list // } } } </script> <style> .border{ border:1px solid #ddd; } </style>
我预想中的正常情况应该是点击按钮,,然后 页面上的 000 000 000 变成 000 123 000 ,
但是就是没有变化看了下 vue 文档先试试是不是子组件检测的值出了问题,
然后我在子组件中添加了 watch和 computed 结果都是无效的;
后来我搜索了页面,发了了一个全局函数 :
Vue.set();
他的效果:
Vue.set( target, key, value )
-
参数:
{Object | Array} target
{string | number} key
{any} value
-
返回值:设置的值。
-
用法:
设置对象的属性。如果对象是响应式的,确保属性被创建后也是响应式的,同时触发视图更新。这个方法主要用于避开 Vue 不能检测属性被添加的限制。
终于被我找到了关键的地方了,但是在组件中怎么使用全局指令呢?
我后面又发现了 this.$set这个函数是完全一样的;
所以高兴的用上了:
正确用法:
methods:{ change(){ setTimeout(()=>{
this.list[1]['list'] = {a:1,b:2,c:3}//这样写 data 并不会检测
this.$set(this.list[1],'list',{a:1,b:2,c:3})//正确的写法
},1000) }
这个坑,浪费了我几个小时,虽然我用 v-if 也解决了,但是总是不甘心,晚上继续研究终于让我解决了;
引以为戒;