小程序

微信小程序 【开发】 自学总结

2020-11-21  本文已影响0人  squidbrother
抖音小程序与微信小程序差异
  1. API方法使用 tt -> wx

  2. 获取用户信息的方式

<view wx:if="{{showLoginBtn}}">
  <button 
    class="skillbtn" 
    bindgetuserinfo="loginFn" 
    open-type="getUserInfo"
  >手动授权登录</button>
</view>
<view wx:else>
  <text>请升级微信版本</text>
</view>
...
//查看授权按钮是否可以使用
if(wx.canIUse('button.open-type.getUserInfo')){
  _that.setData({
    'showLoginBtn': true
  });
};
...
//获取用户信息与请求服务器获取userid
loginFn(ev){
  var _that = this;
  //获取用户的当前授权设置
  wx.getSetting({
    success(res){
      //查看【获取用户信息】授权
      if(res.authSetting['scope.userInfo']){
        wx.getUserInfo({
          success(res){
            var _userInfo = res.userInfo;
            
            //获得code,再进行注册
            _that.registerFn(function(_code){

              //请求后台接口,获取userid

            });
          },
          fail(err){
            console.log(err);
          }
        });
      }else{
        app.showPopFn({
          'title':'授权失败',
          'icon': 'none',
          'duration': 1000
        });
      }
    }
  })
}

2-2. 如果wx:if挂载的标签上条件,与通过此条件来增加标签上的class类名时候,不会产生动画效果
解决: 需要增加额外条件,来改变class类名,可能的话,还要增加延时定时器来进行这个类名条件的设置

  1. rpx(responsive pixel): 可以根据屏幕宽度进行自适应。
    规定屏幕宽为750rpx。
    如在 iPhone6 上,屏幕宽度为375px,共有750个物理像素,则750rpx = 375px = 750物理像素,1rpx = 0.5px = 1物理像素。

  2. 获取用户坐标
    在app.json中,添加获取目标位置的权限:

"permission": {
    "scope.userLocation": {
      "desc": "你的位置信息将用于小程序位置接口的效果展示"
    }
}

获取用户坐标 wx.getLocation

getUserLocalFn(){
    var that = this;
    //获取用户坐标
    wx.getLocation({
      type: 'wgs84',
      success(res){
        var _userLocal = that.data.userLocal;
        _userLocal.latitude = res.latitude;
        _userLocal.longitude = res.longitude;
        that.setData({
          "userLocal": _userLocal
        });
      },
      fail(err){
        console.log(err);
      }
     });
}
  1. 图片预加载
    app.js
//图片预加载
loadImg(_link,sucFn,errFn,cmpFn){
  wx.getImageInfo({
    src: _link,
    success(res){
      sucFn && sucFn(res);
    },
    fail(err){
      errFn && errFn(err);
    },
    complete(res){
      cmpFn && cmpFn(res);
    }
  });
},
//加载所有图片
loadAllImgs(imgListArr,compFn){
  //图片预加载 相关
  var _that = this;
  var num = 0;
  
  for(var i=0; i<imgListArr.length; i++){
    ;(function(i){
      var _tempImg = imgListArr[i];
      //加载图片
      _that.loadImg(_tempImg,function(res){
        num+=1;
        if(num==imgListArr.length){
          compFn && compFn();
        }
      },function(err){
        num+=1;
        if(num==imgListArr.length){
          compFn && compFn();
        }
      },null);  
    })(i);
  }
}

使用,pages下某个页面:

//加载所有图片
app.loadAllImgs([
  'https://www.xxx.net/minisoft/zhenze/everyDayPic_1.jpg',
  'https://www.xxx.net/minisoft/zhenze/everyDayPic_2.jpg',
  'https://www.xxx.net/minisoft/zhenze/everyDayPic_3.jpg'
],function(){
  _that.setData({
    allimgLoaded: true
  });
});

通过allimgLoaded这个数据变量来切换loading条和图片
wxml结构:

<!-- 背景图 -->
<view class="imgBox">
    <!--loadingGear 加载条 -->
    <view class="loadingGear {{allimgLoaded? '':'loadingGearAc'}}">
        <view class="inset">
            <view class="blocks"></view>
            <view class="blocks"></view>
            <view class="blocks"></view>
            <view class="blocks"></view>
            <view class="blocks"></view>
            <view class="blocks"></view>
            <view class="blocks"></view>
            <view class="blocks"></view>
        </view>
    </view>  
    <image wx:if="{{allimgLoaded}}" src="{{itemEle.picSrc}}" mode="aspectFill" />
</view>

css3 loading图标,激活状态运动,否则不运动
wxss

/*loadingGear - 加载条2*/
.loadingGear { position:absolute; left:50%; top:50%; width:4rpx; height:4rpx; margin:-2rpx 0 0 -2rpx; 
z-index:-1;
}
.loadingGear .inset  { position:relative; z-index:2; width:100%; height:100%; visibility:hidden; }
  /*激活*/
.loadingGearAc { z-index:9999;}
.loadingGearAc .inset { visibility:visible;
-webkit-animation:gearAni linear 2s infinite;
-moz-animation:gearAni linear 2s infinite;
-ms-animation:gearAni linear 2s infinite;
-o-animation:gearAni linear 2s infinite;
animation:gearAni linear 2s infinite;
}
.loadingGear .inset .blocks { position:absolute; left:0; bottom:0; z-index:2; width:100%; height:300%; overflow:hidden; background:#006d78; font-size:0; line-height:0;
-webkit-transform-origin:center bottom; -moz-transform-origin:center bottom; transform-origin:center bottom;
}
.loadingGear .inset .blocks:nth-child(1){ -webkit-transform:rotate(0deg) translateY(-10rpx); -moz-transform:rotate(0deg) translateY(-10rpx); transform:rotate(0deg) translateY(-10rpx); }
.loadingGear .inset .blocks:nth-child(2){ -webkit-transform:rotate(45deg) translateY(-10rpx); -moz-transform:rotate(45deg) translateY(-10rpx); transform:rotate(45deg) translateY(-10rpx); }
.loadingGear .inset .blocks:nth-child(3){ -webkit-transform:rotate(90deg) translateY(-10rpx); -moz-transform:rotate(90deg) translateY(-10rpx); transform:rotate(90deg) translateY(-10rpx);  }
.loadingGear .inset .blocks:nth-child(4){ -webkit-transform:rotate(135deg) translateY(-10rpx); -moz-transform:rotate(135deg) translateY(-10rpx); transform:rotate(135deg) translateY(-10rpx);  }
.loadingGear .inset .blocks:nth-child(5){ -webkit-transform:rotate(180deg) translateY(-10rpx); -moz-transform:rotate(180deg) translateY(-10rpx); transform:rotate(180deg) translateY(-10rpx); }
.loadingGear .inset .blocks:nth-child(6){ -webkit-transform:rotate(225deg) translateY(-10rpx); -moz-transform:rotate(225deg) translateY(-10rpx); transform:rotate(225deg) translateY(-10rpx); }
.loadingGear .inset .blocks:nth-child(7){ -webkit-transform:rotate(270deg) translateY(-10rpx); -moz-transform:rotate(270deg) translateY(-10rpx); transform:rotate(270deg) translateY(-10rpx); }
.loadingGear .inset .blocks:nth-child(8){ -webkit-transform:rotate(315deg) translateY(-10rpx); -moz-transform:rotate(315deg) translateY(-10rpx); transform:rotate(315deg) translateY(-10rpx); }
/*gearAni*/
@-webkit-keyframes gearAni { 
  0% { -webkit-transform:rotate(0deg);  -moz-transform:rotate(0deg);  transform:rotate(0deg);}  
  100% { -webkit-transform:rotate(360deg);  -moz-transform:rotate(360deg);  transform:rotate(360deg);}  
}
@keyframes gearAni { 
  0% { -webkit-transform:rotate(0deg);  -moz-transform:rotate(0deg);  transform:rotate(0deg);}  
  100% { -webkit-transform:rotate(360deg);  -moz-transform:rotate(360deg);  transform:rotate(360deg);}  
}
  1. 使用微信小程序API时候,需要先要测试下兼容
compareVersion(v1, v2){
  v1 = v1.split('.')
  v2 = v2.split('.')
  const len = Math.max(v1.length, v2.length)
  while(v1.length < len){
    v1.push('0')
  }
  while(v2.length < len){
    v2.push('0')
  }
  for(let i = 0; i < len; i++){
    const num1 = parseInt(v1[i])
    const num2 = parseInt(v2[i])
    if (num1 > num2){
      return true;
    }else if(num1 < num2){
      return false;
    }
  }
}

放在app.js内,pages使用js调用
如:音频API的兼容

var _btn = app.compareVersion(version,'1.6.0');
if(_btn){
  //基础库 1.6.0 开始支持,低版本需做兼容处理。
  InnerAudioContext = wx.createInnerAudioContext();
}else{
  wx.showModal({
    title: '提示',
    content: '当前微信版本过低,无法使用音频功能,请升级到最新微信版本后重试。'
  });
};
  1. 跳转到第三方小程序,需要获知对方的小程序APPID
    也可以放在app.js内方便,统一调用
jumpOtherMinisoft(_appid,sucFn,errFn){
  var _that = this;

  //兼容
  var version = wx.getSystemInfoSync().SDKVersion;
  var _btn = _that.compareVersion(version,'1.3.0');
  
  if(_btn){
    //基础库 1.3.0 开始支持
    wx.navigateToMiniProgram({
      'appId':_appid,
      success(res){
        sucFn && sucFn(res);
      },
      fail(err){
        errFn && errFn(err);
      }
    });
  }else{
    wx.showModal({
      title: '提示',
      content: '当前微信版本过低,无法使用该功能,请升级到最新微信版本后重试。'
    });
  };
}

pages页面内js直接使用

app.jumpOtherMinisoft('wx2c348cf579062e56',null,function(err){
  console.log(err);
  app.showPopFn({
    'title':'跳转小程序失败'
  });
});

补充,如何查看小程序的appid,
打开微信 - 搜索小程序 - 进入 - 点击右上角三个点 - 点击 弹出层小程序的名称 - 更多资料 - 即可查看 APPID

  1. 转发以及分享到朋友圈
    转发的触发方式为,wxml内放入一个button,open-type,此外在页面的js内要定义onShareAppMessage与onShareTimeline,分别用来定义转发和分享到朋友圈
//用户点击右上角转发  图片长宽比是 5:4
//基础库 1.2.0 开始支持,低版本需做兼容处理
onShareAppMessage(res){
  //兼容
  var version = wx.getSystemInfoSync().SDKVersion;
  var _btn = app.compareVersion(version,'1.2.0');
  if(_btn){
    // 来自页面内转发按钮
    if(res.from === 'button'){};
    return {
      'title': res.target.dataset.tit  || app.globalData.shareObj.sharemes,
      'path':  res.target.dataset.path || app.globalData.shareObj.sharePath,
      'imageUrl': app.globalData.shareObj.shareSendPic
    }
  }else{
    wx.showModal({
      title: '提示',
      content: '当前微信版本过低,无法使用该功能,请升级到最新微信版本后重试。'
    });
  };
},
//用户点击右上角转发到朋友圈  query-当前页面路径携带的参数  图片长宽比是 1:1
//从基础库 2.11.3 开始支持 
onShareTimeline(){
  //兼容
  var version = wx.getSystemInfoSync().SDKVersion;
  var _btn = app.compareVersion(version,'2.11.3');
  if(_btn){
    return {
      'title': app.globalData.shareObj.sharemes,
      'query': null,
      'imageUrl': app.globalData.shareObj.shareFriendPic
    }
  }else{
    wx.showModal({
      title: '提示',
      content: '当前微信版本过低,无法使用该功能,请升级到最新微信版本后重试。'
    });
  };
},

注: 分享的图片比例分别为 5:4、1:1
在wxml内调用,添加自定义属性,可能会方便些

<button 
    class="insetBtn" 
    open-type="share"
    data-tit="{{listsData[nowIndex].tit}}"
    data-path="/pages/find_food_detail/index?sendindex={{nowIndex}}"
></button>
  1. 通过坐标,打开微信小程序内置地图,进行导航
//使用微信内置地图查看位置
openLocationFn(_lat,_lon,sucFn,errFn){
  if(_lat=='' || _lon==''){
    this.showPopFn({
      'title': '坐标错误'
    });
    return false;
  }else{
    wx.openLocation({
      'latitude': _lat,
      'longitude': _lon,
      'scale': 17,
      success(res){
        sucFn && sucFn(res);
      },
      fail(err){
        errFn && errFn(err);
      }
    });
  };
}

调用

goOpenLocationFn(){
  app.openLocationFn(30.91185865822398,120.50376582713723,null,function(err){
    console.log(err);
    app.showPopFn({
      'title': '调用失败',
      'icon': 'success',
      'duration': 500
    })
  })
}
  1. 小程序音频使用
    声明音频对象
var version = wx.getSystemInfoSync().SDKVersion;
var _btn = app.compareVersion(version,'1.6.0');
if(_btn){
  InnerAudioContext = wx.createInnerAudioContext();
}else{
  wx.showModal({
    title: '提示',
    content: '当前微信版本过低,无法使用音频功能,请升级到最新微信版本后重试。'
  });
};

配置音频属性,以及调用方法

//监听播放结束后,关闭对播放结束的监听
InnerAudioContext.src = _nowAudioSrc;
InnerAudioContext.play()
InnerAudioContext.onEnded(function(){
  InnerAudioContext.offEnded();
  InnerAudioContext.stop(); 
  ...业务样式等操作...
  console.log('播放完毕');
});

注: 上述监听结束的方法,最好结束后调用stop,重置音频

10-1. 播放进度与获取音频时长

//2. 监听播放、并获取音频的时长、播放位置与 进度百分比
nowAudioObj.offPlay();
nowAudioObj.onPlay(() => {
  
  //获取总时长与当前播放位置
  nowAudioObj.offTimeUpdate();
  nowAudioObj.onTimeUpdate(()=>{ 
    //初始化 -- 获取音频总时长
    _listsData[_index].audio.duration = nowAudioObj.duration; 
    //实时更新 -- 获取当前播放的位置
    _listsData[_index].audio.startTime = nowAudioObj.currentTime;
    //实时更新 -- 进度条百分比
    _listsData[_index].audio.nowTimePercent = Math.floor(nowAudioObj.currentTime/nowAudioObj.duration*100);

    _that.setData({
      'listsData': _listsData
    });
  });
});

//3. 播放结束监听
nowAudioObj.offEnded();
nowAudioObj.onEnded(() => {
  //重置播放位置、重置样式
  _listsData[_index].audio.startTime = 0;
  _listsData[_index].audio.nowTimePercent = Math.floor(0/nowAudioObj.duration*100);
  _listsData[_index].audio.playStatue = false;

  app.showPopFn({
    'title': '播放完毕'
  });

  //停止监听
  nowAudioObj.stop();
  nowAudioObj.offPlay();
  nowAudioObj.offEnded();
  nowAudioObj.offTimeUpdate();
  _that.setData({
    'listsData': _listsData
  });
});

//4. 捕获错误
nowAudioObj.offError();
nowAudioObj.onError(function(errMsg,errCode){
  console.log(errMsg);
  var _errMes = '';
  switch(errCode){
    case 10001:
      _errMes = '系统错误';
      break;
    case 10002:
      _errMes = '网络错误';
      break; 
    case 10003:
      _errMes = '文件错误';
      break;
    case 10004:
      _errMes = '格式错误';
      break;
    case -1:
      _errMes = '未知错误';
      break;          
  };
  app.showPopFn({
    title:_errMes,
    duration:600
  });
});  

注:

  1. 输入框表单,通过键盘进行搜索,而非一个自定义按钮
    通过bindconfirm事件,可以在键盘敲击回车、在手机键盘输入法触摸完成后,即可进行搜索
<input 
    type="text" 
    bindinput="txtFn" 
    bindconfirm="inputConfirmFn"
    value="{{txtval}}" 
    placeholder="搜索内容..." 
/>

通过事件对象 ev.detail.value 可以完成内容获取

inputConfirmFn(ev){
  var _val = ev.detail.value;
  _val = _val.replace(/\s+/g,""); 
  if(_val != ''){
    console.log('提交的内容为',_val);
  }else{
    app.showPopFn({
      'title': '内容不能为空',
      'icon': 'none',
      'duration': 600
    });
  };
}
  1. 小程序自带的顶部工具栏,可以通过在app.json的window内,通过"navigationStyle":"custom"关闭默认导航
    只保留右上角三个点
"navigationStyle":"custom"

定义一个自定义状态栏组件,可以使用的属性与插槽,官方手册
问题:
不同设备的状态栏的高度不一样,因此自定义导航图标,可能会因设备不一样而跑偏,
所以,为了统一这个比例,可以通过wx.getSystemInfo获取系统信息,通过系统信息返回statusBarHeight获得状态栏高度( 单位px )
再通过 wx.getMenuButtonBoundingClientRect()方式是获得胶囊按钮的空间信息,以及系统状态栏的高度,之后进行对应的计算
具体的方法是:
app.js onLaunch声明周期中

//获取状态栏高度
wx.getSystemInfo({
  success(res){
    _that.globalData.sysBarHeight = res.statusBarHeight;
    console.log(res.statusBarHeight);
  },
  fail(err){
    console.log('系统信息错误',err);
  }
});

//获取胶囊按钮的空间信息
//基础库 2.1.0 开始支持
if(_that.compareVersion(version,'2.1.0')){
  var ButtonBoundingRes = wx.getMenuButtonBoundingClientRect();
  if(ButtonBoundingRes){
    _that.globalData.ButtonBoundingHright = (ButtonBoundingRes.top - _statusBarHeight)*2 + ButtonBoundingRes.height
  };
}else{
  wx.showModal({
    title: '提示',
    content: '当前微信版本过低,无法获取胶囊按钮尺寸功能,请升级到最新微信版本后重试。'
  });
};
一图胜千言

通过上面方式计算结果 自定义导航栏的高度应该为
statusBarHeight 下面的胶囊实际占位 最终自定义导航高度
20 + (24-20)*2+32 = 60

  1. 小程序组件lifetimes 可以补充onload、onshow的生命周期
    js
lifetimes: {
  attached: function() {
    // 在组件实例进入页面节点树时执行
    ...
  },
  detached: function() {
    // 在组件实例被从页面节点树移除时执行
    ...
  },
},
  1. 通过分享进来,没有返回主页入口的困局
    问题:
    如果分享页面是详细页面,通过分享点击进来,无法通过常规后退按钮返回,因此需要一个返回首页的按钮
    但是需要一个判断的条件,即 如何判断此时页面是否为分享点击进来的。
    方案:
    在app.js内,可以在App的onLaunch和onShow,或wx.getLaunchOptionsSync中获取上述场景值,
    来获取 scene (小程序的场景值)
    官方的场景值对应表
    通过将获取的scene来判断是否显示一个返回主页的入口,与表格对比可知,
1007  --  是分享给朋友,朋友通过链接点击过来的
1008  --  群聊会话中的小程序消息卡片

app.js

App({
  onLaunch(option){
    //可以查看scene值
    if(option.scene==1007 || option.scene==1008){
      _that.globalData.formShare = true;
    };
    ...
  1. wx.navigateTo 与 wx.redirectTo 的使用差异
    不同点:
    wx.navigateTo 用于页面流程为串行的操作,最多纪录10层历史路径,可以通过wx.navigateBack进行后退,
    如果超过10层,会进行报错。
navigateTo webview cont limit exceed

wx.redirectTo 可以用来代替上页面跳转的问题,但是无法使用历史路径。
相同点:
都不能跳到 tabbar 页面

  1. 复杂数据的修改,通过字符串拼接好数据,包裹上[ ]来进行解析
    推荐的方式:
var _nowIndex = this.data.nowIndex;
this.setData({
    ['listsData['+_nowIndex+'].sonIndex']: 新的数据
});

var _dataStr = "mapDatas.tabLists["+_mapDatas.tabIndex+"].sonLists";
 _that.setData({
    [_dataStr]: _tempArr
});

引起问题的方式:

var _sonIndex = ev.detail.current;
var _listsData = this.data.listsData;
var _nowIndex = this.data.nowIndex;

_listsData[_nowIndex].sonIndex = _sonIndex;
this.setData({
  'listsData': _listsData
});

出现的具体问题是:

由于小程序运行逻辑线程与渲染线程之上,setData的调用会把数据从逻辑层传到渲染层,数据太大会增加通信时间。
**得分条件:`setData`的数据在`JSON.stringify`后不超过 256KB**
  1. scroll-view组件内,存在子元素,包裹一个swiper组件和同级增加一个浮层,滚动scroll-view时候,浮层会消失
    解决方法:
    将浮层从swiper同级提取到更高一层,可以解决问题。

  2. wx.navigateTo跳转,会出现重复跳转
    原因:如 wx.navigateTo、wx.redirectTo跳转官方没有做节流
    具体操作:

//修复BUG、节流timer
var navigaterTimer = null;
var redirectTimer = null;

App({
onLaunch(option){
var _that = this;
  ...
//跳转 wx.navigateTo 小程序中页面栈最多十层
jumpLink(_link,sucFn,errFn){
clearTimeout(navigaterTimer);
navigaterTimer = setTimeout(function(){
  wx.navigateTo({
    url: _link,
    success(res){
      sucFn && sucFn(res);
    },
    fail(err){
      errFn && errFn(err);
    }
  })
},600);
},
//跳转
jumpLink2(_link,sucFn,errFn){
clearTimeout(redirectTimer);
redirectTimer = setTimeout(function(){
  wx.redirectTo({
    url: _link,
    success(res){
      sucFn && sucFn(res);
    },
    fail(err){
      errFn && errFn(err);
    }
  });
},500);
},

注:延迟时间越久,修复效果越好,如果延迟时间设置300ms,在模拟器上仍可能出现重复跳转的情况,理解可能是设备性能来不及反应?

  1. text标签内如果要添加长文本,为了方便用户浏览时copy可以,为text添加user-select属性,
    此外,首行缩进(text-indent:2em;)不能添加到父级标签,否则会溢出屏幕

  2. 针对富文本,处理带有HTML标签的文案

<rich-text nodes="{{itemEle.backMes.detmes}}" user-select></rich-text>
  1. 获取rpx与px的转化比例值
    已知:小程序规定屏幕宽为750rpx,这个无关机型(rpx(responsive pixel): 可以根据屏幕宽度进行自适应)
    未知:当前设备的宽度
let windowWidth = wx.getSystemInfoSync().windowWidth
let rate = 750 / windowWidth
  1. 小程序加载分页的格式


    小程序分页

22-2. 分页代码格式
js:

'commentLists':{
  'list':[],
  'loaded': false,
  'isLoading': false, 
  'noMore': false,
  'totalcount':0,
  'pageindex': 0
}

wxml:

<!--加载完毕-->
<view 
    class="commentLists"
    wx:if="{{isLoaded}}"
>
    <!-- 有数据 -->
    <view
        wx:if="{{commentLists.list.length>0}}"
    >
        <!--数据列表-->
        <view class="listBox">
            <!-- ele -->
            <view 
                class="ele"
                wx:for="{{commentLists.list}}" 
                wx:for-index="idx" 
                wx:for-item="itemEle"
                wx:key="idx"
            >
                <view class="phootBox borderR">
                    <image src="{{itemEle.userPhoto}}" mode="aspectFill" />
                </view>
                <view class="say">
                    <text>{{itemEle.mes}}</text>
                </view>
            </view>
        </view>
        <!-- 暂无更多数据 -->
        <view wx:if="{{noMore}}" class="noDataTxt">
            <text>暂无更多评论</text>
        </view> 
    </view>
    <!-- 无数据 -->
    <view wx:if="{{commentLists.noMore}}">
        <view class="noDataTxt">
            <text>暂无任何数据</text>
        </view> 
    </view>
</view>
<!--加载中-->
<view wx:else>
    <view class="noDataTxt">
        <text>加载中...</text>
    </view> 
</view>
  1. 小程序跳转第三方小程序中某个页面
    具体流程:
"navigateToMiniProgramAppIdList": [
    "wx91d27dbf599dff74",
    "wx0e6ed4f51db9d078"
]
pages/gs/sight/newDetail.html?sightId=25603&mktshare=eyJhbGxpYW2IjNyojIklWZj5ODQsInNpZCI6NzExNDY1LCJvdWlkIjoiIiwic291cmNlaWQiOjU1NTUyNjg5LCJmcm9tYWxsaWFuY2VpZCI6MCwiZnJvbXNpZCI6MCwiZnJvbW91aWQiOiIiLCJmcm9tc291cmNlaWQiOjAsImZyb21vcGVuaWQiOiIyMTVhZGVhZi1lMmRiLTQ3YWUtODRiZC1hMWU2ZWViMWNlMTAifQ()()KY&allianceid=262684&sid=711465&ouid=&sourceid=55552689

处理链接为:

pages/gs/sight/newDetail?sightId=25603

wxml标签内使用,方式为:

<navigator 
    target="miniProgram" 
    open-type="navigate" 
    app-id="{{pageDetail.appid}}" 
    path="{{pageDetail.path}}" 
    extra-data="" 
    version="release"
>查看详情</navigator>

占坑....

上一篇下一篇

猜你喜欢

热点阅读