v-if跟v-show

v-if跟v-show

写这个区域的时候,因为没有商品就自动隐藏,需要做一个边界的判断

https://img1.sycdn.imooc.com//climg/63df520509a0480604210270.jpg


我想的是这里回频繁切换,我就使用了v-show 但是 会波浪线提示

https://img1.sycdn.imooc.com//climg/63df5232095b7de008620072.jpg


换成v-if就没事

https://img1.sycdn.imooc.com//climg/63df524209ac56ef08680065.jpg


请问这个是什么现象

按理说这两个都是一样的把?只是如果频繁切换的话才需要使用 v-show

(v-if 会操作dom,v-show会使用display)

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
<template>
  <div class="cart">
    <div class="product">
      <div class="product__item" v-for="item in productList" :key="item._id">
        <template v-if="item.count > 0">
          <img class="product__item__img" :src="item.imgUrl" />
          <div class="product__item__detail">
            <h4 class="product__item__title">{{ item.name }}</h4>
            <p class="product__item__price">
              <span class="product__item__yen">¥{{ item.price }}</span>
              <span class="product__item__origin">¥{{ item.oldPrice }}</span>
            </p>
          </div>
          <div class="product__number">
            <span
              class="product__number__minus iconfont"
              @click="
                () => {
                  changeCartItemInfo(shopId, item._id, item, -1);
                }
              "
              >&#xe7fd;</span
            >
            {{ item.count || 0 }}
            <span
              class="product__number__plus iconfont"
              @click="
                () => {
                  changeCartItemInfo(shopId, item._id, item, 1);
                }
              "
              >&#xe614;</span
            >
          </div>
        </template>
      </div>
    </div>
    <div class="check">
      <div class="check__icon">
        <img
          class="check__icon__img"
          src="http://www.dell-lee.com/imgs/vue3/basket.png"
        />
        <div class="check__icon__tag">{{ total }}</div>
      </div>
      <div class="check__info">
        总计:<span class="check__info__price">¥{{ price }}</span>
      </div>
      <div class="check__btn">去结算</div>
    </div>
  </div>
</template>
 
<script>
import { computed } from "vue";
import { useStore } from "vuex";
import { useRoute } from "vue-router";
import { useCommonCartEffect } from "./commonCartEffect";
 
//获取购物车信息逻辑
const useCartEffect = (shopId) => {
  const store = useStore();
  const cartList = store.state.cartList;
 
  //计算 Tab 栏数量
  const total = computed(() => {
    const productList = cartList[shopId];
    let count = 0;
    if (productList) {
      for (let i in productList) {
        const product = productList[i];
        count += product.count;
      }
    }
    return count;
  });
 
  //计算 Tab 栏 价格
  const price = computed(() => {
    const productList = cartList[shopId];
    let count = 0;
    if (productList) {
      for (let i in productList) {
        const product = productList[i];
        count += product.count * product.price;
      }
    }
    return count.toFixed(2);
  });
 
  const productList = computed(() => {
    const productList = cartList[shopId] || [];
    return productList;
  });
 
  return { total, price, productList, cartList };
};
 
export default {
  name: "Cart",
  setup() {
    const route = useRoute();
    const shopId = route.params.id;
    const { changeCartItemInfo } = useCommonCartEffect();
    const { total, price, productList, cartList } = useCartEffect(shopId);
    return { total, price, productList, shopId, cartList, changeCartItemInfo };
  },
};
</script>
 
<style lang="scss" scoped>
@import "../../style/variables.scss";
@import "../../style/mixins.scss";
 
.cart {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
}
 
.product {
  overflow-y: scroll;
  flex: 1;
  background: #fff;
  &__item {
    position: relative;
    display: flex;
    padding: 0.12rem 0;
    margin: 0 0.16rem;
    border-bottom: 0.01rem solid $content-bgColor;
    &__img {
      width: 0.46rem;
      height: 0.46rem;
      margin-right: 0.16rem;
    }
    &__title {
      margin: 0;
      line-height: 0.2rem;
      font-size: 0.14rem;
      color: $content-fontColor;
      @include ellipsis;
    }
    &__price {
      margin-top: 0.06rem;
      line-height: 0.2rem;
      font-size: 0.14rem;
      color: $hightLight-fontColor;
    }
    &__yen {
      font-size: 0.12rem;
      font-weight: bold;
    }
    &__origin {
      margin-left: 0.08rem;
      line-height: 0.2rem;
      font-size: 0.12rem;
      color: $light-fontColor;
      text-decoration: line-through;
    }
    .product__number {
      position: absolute;
      right: 0;
      bottom: 0.12rem;
      &__minus,
      &__plus {
        display: inline-block;
        width: 0.2rem;
        line-height: 0.2rem;
        border-radius: 50%;
        font-size: 0.18rem;
        text-align: center;
      }
      &__minus {
        border: 0.01rem solid $medium-fontColor;
        color: $medium-fontColor;
        margin-right: 0.05rem;
      }
      &__plus {
        background: $btn-bgColor;
        color: $bgColor;
        margin-left: 0.05rem;
      }
    }
  }
}
 
.check {
  display: flex;
  line-height: 0.5rem;
  box-sizing: border-box;
  border-top: 0.01rem solid $content-bgColor;
  &__icon {
    position: relative;
    width: 0.84rem;
    &__img {
      display: block;
      margin: 0.12rem auto;
      width: 0.28rem;
      height: 0.26rem;
    }
    &__tag {
      position: absolute;
      left: 0.49rem;
      top: 0.04rem;
      padding: 0 0.04rem;
      min-width: 0.15rem;
      height: 0.15rem;
      line-height: 0.15rem;
      background-color: $hightLight-fontColor;
      color: #fff;
      border-radius: 0.1rem;
      text-align: center;
    }
  }
  &__info {
    flex: 1;
    color: $content-fontColor;
    font-size: 0.12rem;
    &__price {
      color: $hightLight-fontColor;
      font-size: 0.18rem;
    }
  }
  &__btn {
    width: 0.98rem;
    text-align: center;
    background-color: #4fb0f9;
    color: #fff;
    font-size: 0.14rem;
  }
}
</style>


正在回答 回答被采纳积分+1

登陆购买课程后可参与讨论,去登陆

1回答
imooc_慕慕 2023-02-05 15:19:35

同学你好,分析如下:

同学可以试着开拓思维这种想法很好,但是由于如下原因无法使用v-show ,参考如下:

v-show 是通过 display 来控制标签进行渲染的,但是 template 标签在 vue 解析后是不会显示在页面上的,是虚拟 Dom,所以无法使用 v-show。

反之 v-if 是可以使用在 template 标签上,因为 v-if 是条件渲染,只要满足 v-if 后的条件就可以完成渲染。

简单理解为不支持这种写法,因此这里只能使用v-if。

祝学习愉快~

问题已解决,确定采纳
还有疑问,暂不采纳

恭喜解决一个难题,获得1积分~

来为老师/同学的回答评分吧

0 星
请稍等 ...
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号

在线咨询

领取优惠

免费试听

领取大纲

扫描二维码,添加
你的专属老师
插入代码