v-show没有按预期工作

时间:2018-04-23 14:30:15

标签: javascript vue.js

当我点击按钮后数组显示[]更改时(我可以看到Vue的chrome插件中的节目[]更改),字符' a'还在页面上。' b'和' c'从不出现。
    



<script type="text/javascript" src="https://unpkg.com/vue@2.5.16/dist/vue.js"></script>
<script>
    let vm = new Vue({
        el: '#app',
        data: {
        currentShow:0,
        shows:[true, false, false],
        },
        watch:{
            currentShow: function (val, old) {
                this.shows[old] = false;
                this.shows[val] = true
            }
        }
    });
</script>
&#13;
<!-- Letter 'a', 'b', 'c' shows only when its corresponding shows[] is true-->
<div id="app">
    <p v-show="shows[0]">a</p>
    <p v-show="shows[1]">b</p>
    <p v-show="shows[2]">c</p>
    <button @click="currentShow=(currentShow+1)%3">next</button>
</div>
&#13;
&#13;
&#13;

2 个答案:

答案 0 :(得分:1)

这是一个反应性警告。您可以使用Vue.set()

&#13;
&#13;
<script type="text/javascript" src="https://unpkg.com/vue@2.5.16/dist/vue.js"></script>

<!-- Letter 'a', 'b', 'c' shows only when its corresponding shows[] is true-->
<div id="app">
    <p v-show="shows[0]">a</p>
    <p v-show="shows[1]">b</p>
    <p v-show="shows[2]">c</p>
    <button @click="currentShow=(currentShow+1)%3">next</button>
</div>

<script>
    let vm = new Vue({
        el: '#app',
        data: {
        	currentShow: 0,
        	shows:[true, false, false],
        },
        watch:{
            currentShow: function (val, old) {
                Vue.set(this.shows, old, false);
                Vue.set(this.shows, val, true);
            }
        }
    });
</script>
&#13;
&#13;
&#13;

文档:

如果按索引添加或编辑元素,则have to call Vue.set()

Vue.set(this.shows, old, false);
Vue.set(this.shows, val, true);

或者:

this.shows.splice(old, 1, false);
this.shows.splice(val, 1, true);

这使Vue能够调整对该元素的反应性。

为什么?

除了常见的警告问题外,文档还有a specific guidance on arrays

  

注意事项

     

由于JavaScript的限制,Vue 无法检测到以下内容   更改为数组:

     
      
  1. 直接设置带索引的项目时,例如vm.items[indexOfItem] = newValue
  2.   
  3. 修改数组的长度时,例如: vm.items.length = newLength
  4.         

    例如:

    var vm = new Vue({
      data: {
        items: ['a', 'b', 'c']
      }
    })
    vm.items[1] = 'x' // is NOT reactive
    vm.items.length = 2 // is NOT reactive
    
         

    为了克服警告1,以下两者都将完成相同的操作   如vm.items[indexOfItem] = newValue,但也会触发状态   反应系统的更新:

    // Vue.set
    Vue.set(vm.items, indexOfItem, newValue)
    
    // Array.prototype.splice
    vm.items.splice(indexOfItem, 1, newValue)
    
         

    您还可以使用vm.$set   实例方法,它是全局Vue.set

    的别名
    vm.$set(vm.items, indexOfItem, newValue)
    
         

    要处理警告2,您可以使用splice

    vm.items.splice(newLength)
    

答案 1 :(得分:0)

如果数组元素是基元(通常不是对象),则Vue无法监视数组元素。 Vue已更新由push()pop()和其他方法触发,但无法知道何时更新内部值。请参阅docs

我为您的示例找到了一个特定的解决方案,它只能是一个选定的项目,随时可以适应它。

let vm = new Vue({
    el: '#app',
    data: {
      currentShow: 0
    },
    methods: {
    
      showNext(){
        this.currentShow = (this.currentShow+1) % 3
      }
      
    }
});
<script type="text/javascript" src="https://unpkg.com/vue@2.5.16/dist/vue.js"></script>

<!-- Letter 'a', 'b', 'c' shows only when its corresponding shows[] is true-->
<div id="app">
    <p v-show="currentShow==0">a</p>
    <p v-show="currentShow==1">b</p>
    <p v-show="currentShow==2">c</p>
    <button @click="showNext()">next</button>
</div>