呀呼!呀呼! 2023-04-02 13:59 采纳率: 77.3%
浏览 32

关于v-if和v-show页面渲染的问题

关于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"

img


初始没有问题,但是当我点击了change按钮,往arr添加元素之后,应该展示show1。

img


可以从控制台看到,arr数组的长度已经为1,元素添加成功了,但是依然展示show2,不是show1.
当我不清缓存重新编译,即相当于重新渲染页面,才显示show1.

img


这是为什么呢?数组的长度明明是发送了变化。对于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是计算属性的缘故?

  • 写回答

2条回答 默认 最新

  • Stu.Zhang 2023-04-02 14:47
    关注

    在Vue中,当使用v-show时,元素始终存在于DOM中,只是通过CSS的display属性来控制元素是否显示。因此,当改变v-show表达式的值时,只会更新CSS属性而不会重新编译整个模板。这也就是为什么需要重新编译页面才能看到v-show的变化。

    相比之下,当使用v-if时,每次表达式的值发生变化时,Vue会根据新值重新编译对应的模板,并且销毁或创建元素(取决于表达式的值)。因此,v-if更适合用于频繁切换的场景,但需要注意性能问题。

    至于你遇到的问题,可能与Vuex相关。如果store中的数据被修改,Vue不能自动检测到这些变化并更新视图。你需要手动触发一个state的变化来通知Vue进行重新渲染。可以尝试在mutations中添加一行代码:

    state.arr = state.arr.slice();

    这将使数组重新分配内存,从而通知Vue重新渲染视图。

    评论

报告相同问题?

问题事件

  • 修改了问题 4月3日
  • 修改了问题 4月2日
  • 创建了问题 4月2日

悬赏问题

  • ¥15 已知许多点位,想通过高斯分布来随机选择固定数量的点位怎么改
  • ¥15 怎么生成确定数目的泊松点过程
  • ¥15 layui数据表格多次重载的数据覆盖问题
  • ¥15 python点云生成mesh精度不够怎么办
  • ¥15 QT C++ 鼠标键盘通信
  • ¥15 改进Yolov8时添加的注意力模块在task.py里检测不到
  • ¥50 高维数据处理方法求指导
  • ¥100 数字取证课程 关于FAT文件系统的操作
  • ¥15 如何使用js实现打印时每页设置统一的标题
  • ¥15 安装TIA PortalV15.1报错