我数据已经存到本地了 但是这个代码拿不到数据<template> <div> <van-card :thumb="shop_list.img" /> </div> </template> <script lang="ts" setup> interface TypeList { name: string; age: number; id: string | number; title: number; } const shop_list = window.localStorage.getItem("shop_list") || []; </script> <style></style>
时间: 2023-12-09 22:06:02 浏览: 24
根据您提供的代码,问题可能出在 `shop_list` 的类型推断上。由于您在初始化 `shop_list` 时使用了逻辑或运算符 `||`,当 `window.localStorage.getItem("shop_list")` 返回 `null` 或 `undefined` 时,将会赋值空数组给 `shop_list`。这将导致 `shop_list` 的类型被推断为一个空数组 `never[]`,而不是您期望的类型。
解决这个问题的方法是通过显式指定 `shop_list` 的类型来避免类型推断错误。根据您的代码,您可以将 `shop_list` 的类型指定为 `TypeList[]`,即购物车数据的数组类型:
```typescript
const shop_list: TypeList[] = JSON.parse(window.localStorage.getItem("shop_list") || "[]");
```
或者,在获取 `shop_list` 之后进行类型转换,确保它是一个数组类型:
```typescript
const shop_list = JSON.parse(window.localStorage.getItem("shop_list") || "[]") as TypeList[];
```
请注意,在解决问题时,还需要确保购物车数据的存储和获取逻辑正确无误。如果问题仍然存在,请提供更多详细信息,以便我能够更好地帮助您解决问题。
相关问题
<template #thumb> <img :src="item.img" alt="Custom Image"> </template>这算不算插槽
是的,你提到的`<template>`标签内的内容是Vue 2中的具名插槽的语法。具名插槽可以使用`v-slot`指令或者`#`符号来定义。
在你的代码中,`thumb`就是一个具名插槽的名称。通过使用`v-slot:thumb`或者`#thumb`来指定插槽的名称。
```html
<template>
<div>
<slot name="thumb">
<img :src="item.img" alt="Custom Image">
</slot>
</div>
</template>
```
在父组件中,可以通过具名插槽名称来传递内容给该插槽:
```html
<template>
<div>
<my-component>
<template v-slot:thumb>
<img :src="customImg" alt="Custom Image">
</template>
</my-component>
</div>
</template>
```
在这个例子中,`<template v-slot:thumb>`或者`<template #thumb>`中的内容将会被传递给子组件的名为`thumb`的插槽。这样,你可以在父组件中动态地渲染不同的图片或其他内容到子组件中的具名插槽中。
<template> <div> <router-view /> <div class="title">购物车</div> <div class="shop_goods" v-for="(item, index) in shopcarList" :key="index"> <van-checkbox v-model="item.isChecked"></van-checkbox> <van-card :title="item.name" :thumb="item.img"> <template #price> <span>¥{{ item.price }}</span> </template> <template #num> <p class="count"> <span @click="del(index)">-</span> <span>{{ item.num }}</span> <span @click="add(index)">+</span> </p> </template> </van-card> </div> <div class="shopcar_total"> <van-submit-bar :price="priceTotal" @submit="onSubmit"> <template #button> <span class="total"> 去结算 </span> </template> <van-checkbox v-model="isAllChecked">全选</van-checkbox> </van-submit-bar> </div> </div> </template> <script> export default { data() { return { stepper: 1, shopcarList: [], }; }, methods: { onSubmit() { console.log(111); }, add(index) { // console.log(index); this.$set( this.shopcarList[index], this.shopcarList[index].num, this.shopcarList[index].num++ ); }, del(index) { if (this.shopcarList[index].num == 1) { this.$toast("不能再减了"); } else { this.$set( this.shopcarList[index], this.shopcarList[index].num, this.shopcarList[index].num-- ); } }, }, created() { this.shopcarList = JSON.parse(localStorage.getItem("shopcar")) || []; console.log(this.shopcarList); }, computed: { isAllChecked: { set(val) { this.shopcarList.forEach((ele) => { ele.isChecked = val; }); }, get() { return this.shopcarList.every((ele) => { return ele.isChecked == true; }); }, }, priceTotal() { let sum = 0; let newPrice = this.shopcarList.filter((ele) => { return ele.isChecked == true; }); sum = newPrice.reduce((pre, current) => { return (pre += current.price * current.num); }, 0); return sum * 100; }, }, }; </script>这个页面怎么优化
这个页面可以优化的地方有:
1. 使用vue的keep-alive标签,对于需要频繁切换的组件进行缓存,减少重复渲染。
2. 使用v-show代替v-if,因为v-if每次都会销毁和重新创建DOM元素,而v-show只是控制元素的显示和隐藏。
3. 对于频繁使用的方法,可以将其提取为公共方法,避免重复代码。
4. 对于localStorage的操作,可以将其封装为一个单独的模块,并进行数据的有效性验证,避免出现数据异常。
5. 对于复杂的计算属性,可以使用缓存机制,避免重复计算。
6. 对于数组的修改,可以使用Vue提供的set方法,确保数据的响应式更新。
7. 可以考虑使用分页或懒加载等技术,对于大量数据进行分批加载,减轻页面的渲染压力。
8. 对于一些不必要的DOM元素,可以使用v-if或v-show进行控制,避免无意义的渲染。
9. 对于一些常用的组件,可以考虑进行全局注册或按需加载,避免重复引入和渲染。