vue3手写电商微信小程序( 微信开发者工具)【问题总结】

该项目技术栈: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-groupcheckbox写的样式在微信开发者工具里不匹配

审核元素发现在小程序开发者工具中,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.jsoncompilerOptions里面新增忽略的代码,如下所示,添加后则不会报错:

"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(){
    
    
     // 若是游客,首页做提示操作
     .......
  })
})

总结:

后续还发现有什么问题我会继续更新博客,大家也可以在评论区沟通交流,拜拜!!!

猜你喜欢

转载自blog.csdn.net/weixin_55846296/article/details/129923611