关于v-if和v-show页面渲染的问题。
在使用v-if时,v-if里面的表达式变化的时候,页面会进行自动同步渲染显示元素或者删除元素。
但是使用v-show的时候,需要重新编译一次页面,他才反应得过来,把元素隐藏/显示。
vue文件代码:
<view>
<view class="" v-show="arr.length !== 0">
show1
</view>
<view v-show="arr.length === 0">
show2
</view>
<button @click="add">change</button>
</view>
<script>
import {
mapState,
mapActions,
} from 'vuex'
export default {
data() {
return {
};
},
methods: {
...mapActions('m_cart1', ['change','add']),
},
computed: {
...mapState('m_cart1', ['BooleanText']),
...mapState('m_cart1', ['arr']),
}
}
</script>
store文件夹的js文件代码:
export default {
// 为当前模块开启命名空间
namespaced: true,
state: () => ({
BooleanText:JSON.parse(uni.getStorageSync('text') || true),
arr:JSON.parse(uni.getStorageSync('arr') || "[]"),
}),
actions: {
change(context, value){
context.commit("CHANGE", value);
},
add(context, value){
context.commit("ADD", value);
},
saveToStorage(context, value) {
context.commit("SAVETOSTORAGE", value);
}
},
// 模块的 mutations 方法
mutations: {
CHANGE(state){
state.BooleanText=!state.BooleanText;
},
ADD(state){
state.arr.push(1);
this.commit('m_cart1/SAVETOSTORAGE')
},
SAVETOSTORAGE(state) {
uni.setStorageSync('text', JSON.stringify(state.BooleanText))
uni.setStorageSync('arr', JSON.stringify(state.arr))
}
},
}
// 1. 导入 Vue 和 Vuex
import Vue from 'vue';
import Vuex from 'vuex';
import moduleCart1 from './cart1.js'
Vue.use(Vuex)
// 3. 创建 Store 的实例对象
const store = new Vuex.Store({
// TODO:挂载 store 模块
modules: {
m_cart1: moduleCart1
},
})
// 4. 向外共享 Store 的实例对象
export default store
代码概况:
点击change按钮就会往arr数组里利用push方法去添加一个元素,当arr的长度不等于0的时候,就展示show1,
等于0则展示show2。
结果:使用v-show去写隐藏条件v-show="arr.length !== 0"
初始没有问题,但是当我点击了change按钮,往arr添加元素之后,应该展示show1。
可以从控制台看到,arr数组的长度已经为1,元素添加成功了,但是依然展示show2,不是show1.
当我不清缓存重新编译,即相当于重新渲染页面,才显示show1.
这是为什么呢?数组的长度明明是发送了变化。对于vue不能感知到这个数组的变化,我是不怎么认同的,因为我在updated函数里面,打印这个arr数组的长度,他是可以正确打印出来的,确实发送了变化,而且我直接在页面上使用插值语法去显示这个arr数组的长度也是正确的。这里的尝试的代码和图片就不展示出来了。我觉得这就说明了vue是感知到了arr数组的变化的,但是就是不知道为什么v-show的判断条件没有进行重新判断?而是等页面重新渲染之后才判断。我也觉得这个说法说不通,因为我直接使用一个布尔类型变量去判断是可以的,使用数组.length!==0就不行。
当我使用v-if去判断v-if="arr.length !== 0"的时候,就没有这个问题,一点chang,数组长度变化,页面也跟着变化为show1,不需要重新编译。
这是为什么?v-if和v-show在这里有什么差异?
题外话:在以前,我们把数据放到自己的data里面是没有这个问题的,v-show和v-if都是直接自动刷新的,难道是因为这个arr是从store里读出来的缘故,亦或者是这个arr是计算属性的缘故?