vue3手写电商微信小程序( 微信开发者工具)【问题总结】
-
- 该项目技术栈:vite3 + vue3.2 + pinia + typeScript
- 1、样式穿透在微信开发者工具不适用:
- 2、`v-html`在微信开发者工具显示的是`rich-text`组件,导致样式不适用:`图片大小不自适应`,比如图片太大,只展示了一半
- 3、uni-app组件里的`checkbox-group`和`checkbox`写的样式在微信开发者工具里不匹配
- 4、蓝湖UI上的图片链接在微信开发者工具上不可用
- 5、问题: 元素隐式具有 “any“ 类型,因为类型为 “string“ 的表达式不能用于索引类型 “Object“。 在类型 “Object“ 上找不到具有类型为 “string“ 的参数的索引签名
- 6、ts对于类型定义这块比较严谨,所以在传prop要传一个对象时,要使用泛类型进行定义:
- 7、在calc时,在符号前面要增加空格,没有空格不会生效
- 8、小程序系列无法拦截原生tabbar及原生导航返回,如需拦截就需要自定义tabbar、header,在这里我们可以利用其他解决方案:
- 总结:
该项目技术栈:vite3 + vue3.2 + pinia + typeScript
1、样式穿透在微信开发者工具不适用:
解决方案: 全局引入一个
scss
文件,在其内根据微信小程序开发者工具上的标签层级单独写样式
2、v-html
在微信开发者工具显示的是rich-text
组件,导致样式不适用:图片大小不自适应
,比如图片太大,只展示了一半
解决方案:
- html代码:
<rich-text class="content" :nodes="formatImg(state.info.detailMobileDesc)"</rich-text>
- JavaScript代码:
const formatImg = (html: string) => {
var newContent = html.replace(/<img[^>]*>/gi, match => {
let processed = null;
if (!match.match(/style=\"(.*)\"/gi)) {
processed = match.replace(
/\<img/g,
'<img style="width:100%;height:auto;display:block"',
);
} else {
processed = match.replace(
/style=\"(.*)\"/gi,
'style="width:100%;height:auto;display:block"',
);
}
return processed;
});
return newContent;
};
3、uni-app组件里的checkbox-group
和checkbox
写的样式在微信开发者工具里不匹配
审核元素发现在小程序开发者工具中,checkbox组件是被黑盒封装的,根本无法查看组件内部的类名
,也就是说无法知晓修改的类名具体情况了。于是查阅资料发现,小程序平台checkbox组件实际内部类名和h5端不一致(类名及代码如下):
<checkbox-group @change="checkboxChange">
<uni-swipe-action>
<uni-swipe-action-item
class="uni-list-cell"
v-for="(item, index) in state.cartList"
:key="item.sku"
>
<view class="content-box">
<view class="ceshi">
<checkbox
:class="{ checked: item.checked }"
:value="item.value"
:checked="item.checked"
@click="checkOne(item, index)"
/>
</view>
<view class="box">
<img
class="cellImage"
:src="JSON.parse(item.goodsImg)[0]"
alt=""
/>
<view class="right">
<p class="nameTitle">
{
{ item.goodsName }}
</p>
<p class="modelSec">
{
{ item.model }}
</p>
<view class="priceSele">
¥{
{ item.price }}
<view class="numBox"
><uni-number-box
:min="1"
:max="9999999999"
:isMax="item.count >= 9999999999 ? true : false"
:isMin="item.count === 1"
v-model="item.count"
@change="changeValue"
/></view>
</view>
</view>
</view>
</view>
<template v-slot:right>
<view class="slot-button" @click="deleteCartItem(index)">
<image
class="thumbnail_4"
referrerpolicy="no-referrer"
src="http://p0.qhimg.com/t01fd5d8f0e8cfe01c4.png"
/>
<p> 删除 </p>
</view>
</template>
</uni-swipe-action-item>
</uni-swipe-action>
</checkbox-group>
所以,若要兼容多平台需要写两套不同类名的样式,同时配合uni-app中的条件注释
实现跨端兼容,通过在代码外层包裹条件注释,当ifdef
后面的平台类型是MP-WEIXIN
,代表下列代码只会在微信小程序端生效,其它平台不会执行:
/* #ifdef MP-WEIXIN */
uni-checkbox .uni-checkbox-input,
checkbox .wx-checkbox-input {
width: 35rpx;
height: 35rpx;
border-radius: 50% !important;
}
uni-checkbox .uni-checkbox-input,
checkbox .wx-checkbox-input.wx-checkbox-input-checked {
color: #fff !important;
background-color: #3873fa !important;
}
/* #endif */
关于条件注释,如果还不是很明白,可以查看:条件编译 解决各端差异 - uni-app官网 (dcloud.io)
4、蓝湖UI上的图片链接在微信开发者工具上不可用
需要将图片下载下来放在图床上生成链接,最后统计再上传至白名单更改域名
5、问题: 元素隐式具有 “any“ 类型,因为类型为 “string“ 的表达式不能用于索引类型 “Object“。 在类型 “Object“ 上找不到具有类型为 “string“ 的参数的索引签名
描述: 在写代码的时候,取一个对象某一个key对应的value值,但是写完之后发现
Typescript
报错了,错误内容就是如题,有点奇怪,特此去了解一下:
for (const key in obejct) {
// 处理...
obejct[key]
....
}
解决方案:
方案一:忽略
在tsconfig.json
中compilerOptions
里面新增忽略的代码,如下所示,添加后则不会报错:
"suppressImplicitAnyIndexErrors": true
方案二:声明
在定义的Interface里对其进行声明,如下所示,声明过后,也不会再报错:
interface DAMNU_ENABLE {
....
[key: string]: boolean, // 字段扩展声明
};
[key: string]: boolean, // 字段扩展声明 声明之后可以用方括号的方式去对象里边的值
方案三:对其使用keyof进行判断
TypeScript 允许我们遍历某种类型的属性,并通过
keyof
操作符提取其属性的名称。keyof 操作符是在 TypeScript 2.1 版本引入的,该操作符可以用于获取某种类型的所有键,其返回类型是联合类型
。扫描二维码关注公众号,回复: 14613270 查看本文章
export function isValidKey(
key: string | number | symbol,
object: object
): key is keyof typeof object {
return key in object;
}
定义一个函数:isValidKey()
,然后对需要使用到的地方进行一次判断:
for (const key in obejct) {
if(isValidKey(key,obejct)){
// 处理...
obejct[key]
....
}
}
这三种方式都可以解决如题的报错信息,但是个人比较倾向于第三种,并不是其他两种不好,只是说,写第一种有一点点写any的感觉,不到万不得已不这么弄;第二种得把用到的属性字段类型都写出来,有点费事
6、ts对于类型定义这块比较严谨,所以在传prop要传一个对象时,要使用泛类型进行定义:
// 接收外部传参
interface propData {
goodsItem: {
goodsImg: string;
itemName: string;
model: string;
price: string;
count: string;
};
}
const props = defineProps<propData>();
7、在calc时,在符号前面要增加空格,没有空格不会生效
height: calc(100vh - 80rpx);
8、小程序系列无法拦截原生tabbar及原生导航返回,如需拦截就需要自定义tabbar、header,在这里我们可以利用其他解决方案:
业务场景: 在首页
home.vue
中点击底部tabbar
跳转至二级页面page.vue
,跳转时需要进行角色验证,判断是否有该模块权限,在这里没有办法监测tabbar
跳转,只能利用两个页面传值的方式进行监测:
page.vue
文件(uni.$emit('open');
)
onShow(() => {
// 判断是否是游客
const userStore = userInfoStoreStore();
const userInfo = userStore.getUserInfo;
if (!userInfo.userRole) {
uni.switchTab({
url: '/pages/home/index',
});
uni.$emit('open');
} else {
// 该页面其他操作
......
}
});
home.vue
文件:
onShow(() => {
// 游客角色点击产品
uni.$on('open',function(){
// 若是游客,首页做提示操作
.......
})
})
总结:
后续还发现有什么问题我会继续更新博客,大家也可以在评论区沟通交流,拜拜!!!