Life m|

丶乔

园龄:1年7个月粉丝:1关注:1

小程序部分记录

1.uniapp

https://ask.dcloud.net.cn/article/36286

1.1request

********url文件**************

// 开发环境
const dev = "wxapp.chuntaoyisheng.com/";
// 测试环境
const test = "miapp.chuntaoyisheng.com/";

const ENV_HOST = process.env.NODE_ENV === "development" ? dev : test;

export const host = `https://${ENV_HOST}`;


*************request文件************

import { host } from "@/url";
export default function(
  url: String,
  data: any,
  method: any,
  form = "json",
  params: any
) {
  let token = uni.getStorageSync("token");
  if (token) {
    if (method === "POST") {
      url = `${url}?token=${token}`;
      if (form == "form") {
        for (let k in data) {
          let value = data[k] !== undefined ? data[k] : "";
          url += `&${k}=${encodeURIComponent(value)}`;
        }
      }
      if (params) {
        for (let s in params) {
          let values = params[s] !== undefined ? params[s] : "";
          url += `&${s}=${encodeURIComponent(values)}`;
        }
      }
    } else {
      data = Object.assign({ token }, data);
    }
  }
  return new Promise((resolve, reject) => {
    uni.request({
      url: host + url,
      data: form == "form" ? "" : data,
      method,
      header: {
        "content-type": "application/json;charset=UTF-8", // 默认转为json格式
          Authorization: token,
      },
      success(res: any) {
        if (res.data.state) {
          const body = res.data.body;
          resolve(
            (!body && typeof body == "object") || typeof body == "undefined"
              ? true
              : body
          );
        } else {
          new Error(res.data);
          reject(res.data);
        }
      },
      fail(err) {
        reject(err);
      },
    });
  });
}


**************使用***********
import request from "@/util/request";
export function xxx(data: any) {
  return request("/api/v1/account/userArchiveCheck", data, "POST");
}

2.动态修改title

uni.setNavigationBarTitle({
  title:res.data.storeName
})

3.分包优化

"mp-weixin": {
  "optimization": {
    "subPackages": true
  },
  "runmode" : "liberate" // 开启分包优化后,必须配置资源释放模式
}

4.微信电子健康卡文档

https://mp.weixin.qq.com/wxopen/plugindevdoc?appid=wxee969de81bba9a45&token=&lang=zh_CN

{
  "path": "patientManagement/add",
    "style": {
      "navigationBarTitleText": "新增健康卡",
        "mp-weixin": {
          "usingComponents": {
            "health-card-login": "plugin://healthCardPlugins/healthCardLogin"
          }
        }
    }
},

5.用户自定义信息绘制二维码

https://developers.weixin.qq.com/community/develop/article/doc/00002064e6c920917be96c1ed56013

6.上拉加载

onReachBottom

7.预览图片

// 预览图片
uni.previewImage({
  urls: res.tempFilePaths,
  longPressActions: {
    itemList: ['发送给朋友', '保存图片', '收藏'],
    success: function(data) {
      console.log('选中了第' + (data.tapIndex + 1) + '个按钮,第' + (data.index + 1) + '张图片');
    },
    fail: function(err) {
      console.log(err.errMsg);
    }
  }
});

wx.previewImage({
  urls: ["/static/logo.png"], //需要预览的图片http链接列表,多张的时候,url直接写在后面就行了
  current: '', // 当前显示图片的http链接,默认是第一个
  success: function(res) {},
  fail: function(res) {},
  complete: function(res) {},
})

8.全局变量

app.vue中

 onShow: function(options) {
    console.log('App Show')
    // this.webSocket.connectSocket()
    this.globalData.pageQuery = options.query
  },
      globalData: {
    test: '',
    pageQuery: {},
  },

其他页面

onLoad() {
    /* ***公众号入口跳转核酸预约挂号缴费 */
    const pageQuery = getApp().globalData.pageQuery
    console.log(pageQuery, '---公众号跳转得到的参数----')
    if (pageQuery.type === 'nucleatePay') {
      uni.navigateTo({
        url: `/pages-user/nucleicAcidAppointment/flowform/success?id=${pageQuery.id}`,
      })
    }
    /* **** */
  },

9.隐藏top栏

pages.json中

  "globalStyle": {
    "navigationBarTextStyle": "black",
    "navigationBarTitleText": "uni-app",
    "navigationBarBackgroundColor": "#F8F8F8",
    "backgroundColor": "#F8F8F8",
    "navigationStyle": "custom"
  }

10.上传图片

    uni.chooseImage({
        count: 5 - this.uploadImags.length, //默认9 6 - _self.uploadImags.length
        sizeType: ["original", "compressed"], //可以指定是原图还是压缩图,默认二者都有
        sourceType: ["album"], //从相册选择
        success: (res: any) => {
          console.log(res);
          res.tempFiles.forEach((item: any) => {
            //上传图片
            if (item.size < 5000000) {
              //   upload(item.path).then(data => {
              //     console.log(data)
              //     if (data.body) {
              //       this.uploadImags.push(data.body)
              //     }
              //   })
            } else {
              uni.showToast({
                title: "图片大小不能超过5M",
                icon: "none",
              });
            }
          });
        },
      });

11.移动端h5 打开vconsole

html文件中

<script src="https://unpkg.com/vconsole/dist/vconsole.min.js"></script>
    <script>
      // VConsole will be exported to `window.VConsole` by default.
      var vConsole = new window.VConsole();
    </script>

12.监听小程序版本更新

const updateManager = uni.getUpdateManager();

updateManager.onCheckForUpdate(function (res) {
  // 请求完新版本信息的回调
  console.log(res.hasUpdate);
});

updateManager.onUpdateReady(function (res) {
  uni.showModal({
    title: '更新提示',
    content: '新版本已经准备好,是否重启应用?',
    success(res) {
      if (res.confirm) {
        // 新的版本已经下载好,调用 applyUpdate 应用新版本并重启
        updateManager.applyUpdate();
      }
    }
  });

});

updateManager.onUpdateFailed(function (res) {
   // 新的版本下载失败
        uni.showModal({
          title: '更新提示',
          content: '版本已更新,请删除当前小程序,重新搜索打开',
          showCancel: false,
        })
});

捕获报错 大多数时候不用

  await moneyBay({
        patientId: this.perId,
      })
        .then(res => {
          console.log(res, 'jieguo---------')
          if (res) {
            this.infoData = res
            this.isPay = false
          } else {
            this.isPay = true
          }
        })
        .catch(err => {
          uni.hideToast()
          uni.showModal({
            title: '系统提示',
            content: err.message.split(':')[1],
            confirmColor: '#0AB2C1',
            success: function(res) {
              if (res.confirm) {
                console.log('用户点击确定')
              } else if (res.cancel) {
                console.log('用户点击取消')
              }
            },
          })
          uni.hideToast()
        })

13.富文本解析支持显示空格

.replace(/&nbsp;/g, '\xa0')

14.启动命令更改

插件
cross-env

 "build:mp-weixin": "cross-env NODE_ENV=production UNI_PLATFORM=mp-weixin vue-cli-service uni-build",

15.跳转其他小程序

uni.navigateToMiniProgram({
	appId: '',// 其他小程序APPID
	path: '',//其他小程序地址
  	success: res => {
    	// 打开成功
        console.log("打开成功", res);
  	},
    fail: err => {
    	console.log(err);
   	}
});

16.聊天窗口消息滚动

//窗口元素#container
//1.支付宝小程序
data: windowHeight: uni.getSystemInfoSync().windowHeight //获取窗口可用高度
methods:
this.$nextTick(() => {
  my.createSelectorQuery()
    .select('#container')
    .boundingClientRect() //当前选择节点的位置信息
    .exec((ret) => { //exec将查询结果放入 callback 回调中
    if (ret[0].height >= this.windowHeight - 66) { //整体高度超出窗口可用高度时进行滚动
      uni.pageScrollTo({ //将页面滚动到目标位置
        scrollTop: ret[0].height,
      })
    }
  })
}

//2.微信小程序
data: windowHeight: uni.getSystemInfoSync().windowHeight //获取窗口可用高度
methods:
this.$nextTick(() => {
  const node = uni
  .createSelectorQuery()
  .in(this) //支付宝不支持in写法
  .select('#container')

  node
    .boundingClientRect(({ height }) => {
    if (height >= this.windowHeight - 66) {
      uni.pageScrollTo({
        scrollTop: height,
      })
    }
  })
    .exec()
}

17.wx.config is not a function

<script src="//res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
再使用jWeixin

18.微信浏览器h5调转微信小程序

如果使用uni 需要使用jWeixin代替wx
1.注入sdk

<script src="//res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>

2.app页
//后台获取签名数据
const res = await getTicket({
  url: encodeURIComponent(window.location.href),
});

//签名并获取开放组件wx-open-launch-weapp
jWeixin.config({
  // jsApiList 不能为空,为空部分机型会签名失败
  jsApiList: ["updateAppMessageShareData"],
  appId: res.appId,
  nonceStr: res.nonceStr,
  timestamp: res.timestamp,
  signature: res.signature,
  openTagList: ["wx-open-launch-weapp"],
  // debug: process.env.NODE_ENV === "development",
  debug: true,
});
//兼容ios ios由于路径加载原因第一次签名报错,需要刷新重新签名
jWeixin.error(function (res) {
  console.log(res, "失败-=-----");
  location.reload();
  // config信息验证失败会执行 error 函数,如签名过期导致验证失败,具体错误信息可以打开 config 的debug模式查看,也可以在返回的 res 参数中查看,对于 SPA 可以在这里更新签名
});

3.子页
  <view v-else class="operation">
      确认预约
      <wx-open-launch-weapp
        username="gh_aa3e606cd979" //必填微信唯一原始码
        :path="'pages/login/userLogin'" //路径
        id="launch-btn"
        style="
          display: block;
          position: absolute;
          top: 0;
          left: 0;
          width: 100%;
          height: 100%;
        "
      >
        <script type="text/wxtag-template">
          <style>
              .app-box{
                position:absolute;
                top:0;
                left:0;
                width:100%;
                height:100%;
              }
          </style>
          <div class="app-box"></div>
        </script>
      </wx-open-launch-weapp>
    </view>


注意:sdkjweixin-1.6.0.js 1.6.0版本才支持开放组件

19.日历组件

https://gitee.com/nullfeng/uniapp_date_and_time_selector

2.uni日历组件新增配置

<template>
  <view class="uni-calendar">
    <view
      v-if="!insert && show"
      class="uni-calendar__mask"
      :class="{ 'uni-calendar--mask-show': aniMaskShow }"
      @click="clean"
    ></view>
    <view
      v-if="insert || show"
      class="uni-calendar__content"
      :class="{
        'uni-calendar--fixed': !insert,
        'uni-calendar--ani-show': aniMaskShow,
      }"
    >
      <view v-if="!insert" class="uni-calendar__header uni-calendar--fixed-top">
        <view class="uni-calendar__header-btn-box" @click="close">
          <text class="uni-calendar__header-text uni-calendar--fixed-width"
            >取消</text
          >
        </view>
        <view class="uni-calendar__header-btn-box" @click="confirm">
          <text class="uni-calendar__header-text uni-calendar--fixed-width"
            >确定</text
          >
        </view>
      </view>
      <view class="uni-calendar__header">
        <view class="uni-calendar__header-btn-box" @click.stop="pre">
          <view class="uni-calendar__header-btn uni-calendar--left"></view>
        </view>
        <picker
          mode="date"
          :value="date"
          fields="month"
          @change="bindDateChange"
        >
          <text class="uni-calendar__header-text">{{
            (nowDate.year || '') + '年' + (nowDate.month || '') + '月'
          }}</text>
        </picker>
        <view class="uni-calendar__header-btn-box" @click.stop="next">
          <view class="uni-calendar__header-btn uni-calendar--right"></view>
        </view>
        <!-- <text class="uni-calendar__backtoday" @click="backtoday">回到今天</text> -->
      </view>
      <view class="uni-calendar__box">
        <view v-if="showMonth" class="uni-calendar__box-bg">
          <text class="uni-calendar__box-bg-text">{{ nowDate.month }}</text>
        </view>
        <view class="uni-calendar__weeks">
          <view class="uni-calendar__weeks-day">
            <text class="uni-calendar__weeks-day-text"></text>
          </view>
          <view class="uni-calendar__weeks-day">
            <text class="uni-calendar__weeks-day-text"></text>
          </view>
          <view class="uni-calendar__weeks-day">
            <text class="uni-calendar__weeks-day-text"></text>
          </view>
          <view class="uni-calendar__weeks-day">
            <text class="uni-calendar__weeks-day-text"></text>
          </view>
          <view class="uni-calendar__weeks-day">
            <text class="uni-calendar__weeks-day-text"></text>
          </view>
          <view class="uni-calendar__weeks-day">
            <text class="uni-calendar__weeks-day-text"></text>
          </view>
          <view class="uni-calendar__weeks-day">
            <text class="uni-calendar__weeks-day-text"></text>
          </view>
        </view>
        <view
          class="uni-calendar__weeks"
          v-for="(item, weekIndex) in weeks"
          :key="weekIndex"
        >
          <view
            class="uni-calendar__weeks-item"
            v-for="(weeks, weeksIndex) in item"
            :key="weeksIndex"
          >
            <calendar-item
              :weeks="weeks"
              :calendar="calendar"
              :selected="selected"
              :lunar="lunar"
              @change="choiceDate"
            ></calendar-item>
          </view>
        </view>
      </view>
    </view>
  </view>
</template>

<script>
import Calendar from './util.js'
import calendarItem from './uni-calendar-item.vue'
/**
 * Calendar 日历
 * @description 日历组件可以查看日期,选择任意范围内的日期,打点操作。常用场景如:酒店日期预订、火车机票选择购买日期、上下班打卡等
 * @tutorial https://ext.dcloud.net.cn/plugin?id=56
 * @property {String} date 自定义当前时间,默认为今天
 * @property {Boolean} lunar 显示农历
 * @property {Boolean} isDisableAll 是否禁用所有选项
 * @property {Array} optional 可选项
 * @property {String} startDate 日期选择范围-开始日期
 * @property {String} endDate 日期选择范围-结束日期
 * @property {Boolean} range 范围选择
 * @property {Boolean} insert = [true|false] 插入模式,默认为false
 * 	@value true 弹窗模式
 * 	@value false 插入模式
 * @property {Boolean} clearDate = [true|false] 弹窗模式是否清空上次选择内容
 * @property {Array} selected 打点,期待格式[{date: '2019-06-27', info: '签到', data: { custom: '自定义信息', name: '自定义消息头',xxx:xxx... }}]
 * @property {Boolean} showMonth 是否选择月份为背景
 * @event {Function} change 日期改变,`insert :ture` 时生效
 * @event {Function} confirm 确认选择`insert :false` 时生效
 * @event {Function} monthSwitch 切换月份时触发
 * @example <uni-calendar :insert="true":lunar="true" :start-date="'2019-3-2'":end-date="'2019-5-20'"@change="change" />
 */
export default {
  components: {
    calendarItem,
  },
  props: {
    isDisableAll: {
      type: Boolean,
      default: false,
    },
    optional: {
      type: Array,
      default() {
        return []
      },
    },
    date: {
      type: String,
      default: '',
    },
    selected: {
      type: Array,
      default() {
        return []
      },
    },
    lunar: {
      type: Boolean,
      default: false,
    },
    startDate: {
      type: String,
      default: '',
    },
    endDate: {
      type: String,
      default: '',
    },
    range: {
      type: Boolean,
      default: false,
    },
    insert: {
      type: Boolean,
      default: true,
    },
    showMonth: {
      type: Boolean,
      default: true,
    },
    clearDate: {
      type: Boolean,
      default: true,
    },
  },
  data() {
    return {
      show: false,
      weeks: [],
      calendar: {},
      nowDate: '',
      aniMaskShow: false,
    }
  },
  watch: {
    date(newVal) {
      this.cale.setDate(newVal)
      this.init(this.cale.selectDate.fullDate)
    },
    startDate(val) {
      this.cale.resetSatrtDate(val)
    },
    endDate(val) {
      this.cale.resetEndDate(val)
    },
    selected(newVal) {
      this.cale.setSelectInfo(this.nowDate.fullDate, newVal)
      this.weeks = this.cale.weeks
    },
  },
  created() {
    // 获取日历方法实例
    this.cale = new Calendar({
      // date: new Date(),
      selected: this.selected,
      startDate: this.startDate,
      endDate: this.endDate,
      range: this.range,
    })
    // 选中某一天
    this.cale.setDate(this.date)
    this.init(this.cale.selectDate.fullDate)
    // this.setDay
  },
  methods: {
    // 取消穿透
    clean() {},
    bindDateChange(e) {
      const value = e.detail.value + '-1'
      console.log(this.cale.getDate(value))
      this.cale.setDate(value)
      this.init(value)
    },
    /**
     * 初始化日期显示
     * @param {Object} date
     */
    init(date) {
      this.weeks = this.cale.weeks
      this.nowDate = this.calendar = this.cale.getInfo(date)
      this.disableAll()
    },
    disableAll() {
      //禁用全部日历,只可选配置项optional
      if (!this.isDisableAll) return
      for (let key in this.weeks) {
        this.weeks[key].forEach(v => {
          v.disable = true
          this.optional.includes(v?.fullDate) && (v.disable = false)
        })
      }
    },
    /**
     * 打开日历弹窗
     */
    open() {
      // 弹窗模式并且清理数据
      if (this.clearDate && !this.insert) {
        this.cale.cleanMultipleStatus()
        this.cale.setDate(this.date)
        this.init(this.cale.selectDate.fullDate)
      }
      this.show = true
      this.$nextTick(() => {
        setTimeout(() => {
          this.aniMaskShow = true
        }, 50)
      })
    },
    /**
     * 关闭日历弹窗
     */
    close() {
      this.aniMaskShow = false
      this.$nextTick(() => {
        setTimeout(() => {
          this.show = false
          this.$emit('close')
        }, 300)
      })
    },
    /**
     * 确认按钮
     */
    confirm() {
      this.setEmit('confirm')
      this.close()
    },
    /**
     * 变化触发
     */
    change() {
      if (!this.insert) return
      this.setEmit('change')
    },
    /**
     * 选择月份触发
     */
    monthSwitch() {
      let { year, month } = this.nowDate
      this.$emit('monthSwitch', {
        year,
        month: Number(month),
      })
    },
    /**
     * 派发事件
     * @param {Object} name
     */
    setEmit(name) {
      let { year, month, date, fullDate, lunar, extraInfo } = this.calendar
      this.$emit(name, {
        range: this.cale.multipleStatus,
        year,
        month,
        date,
        fulldate: fullDate,
        lunar,
        extraInfo: extraInfo || {},
      })
    },
    /**
     * 选择天触发
     * @param {Object} weeks
     */
    choiceDate(weeks) {
      if (weeks.disable) return
      this.calendar = weeks
      // 设置多选
      this.cale.setMultiple(this.calendar.fullDate)
      this.weeks = this.cale.weeks
      this.change()
    },
    /**
     * 回到今天
     */
    backtoday() {
      console.log(this.cale.getDate(new Date()).fullDate)
      let date = this.cale.getDate(new Date()).fullDate
      this.cale.setDate(date)
      this.init(date)
      this.change()
    },
    /**
     * 上个月
     */
    pre() {
      const preDate = this.cale.getDate(this.nowDate.fullDate, -1, 'month')
        .fullDate
      this.setDate(preDate)
      this.monthSwitch()
      this.disableAll()
    },
    /**
     * 下个月
     */
    next() {
      const nextDate = this.cale.getDate(this.nowDate.fullDate, +1, 'month')
        .fullDate
      this.setDate(nextDate)
      this.monthSwitch()
      this.disableAll()
    },
    /**
     * 设置日期
     * @param {Object} date
     */
    setDate(date) {
      this.cale.setDate(date)
      this.weeks = this.cale.weeks
      this.nowDate = this.cale.getInfo(date)
    },
  },
}
</script>

<style lang="scss" scoped>
.uni-calendar {
  /* #ifndef APP-NVUE */
  display: flex;
  /* #endif */
  flex-direction: column;
}

.uni-calendar__mask {
  position: fixed;
  bottom: 0;
  top: 0;
  left: 0;
  right: 0;
  background-color: $uni-bg-color-mask;
  transition-property: opacity;
  transition-duration: 0.3s;
  opacity: 0;
  /* #ifndef APP-NVUE */
  z-index: 99;
  /* #endif */
}

.uni-calendar--mask-show {
  opacity: 1;
}

.uni-calendar--fixed {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  transition-property: transform;
  transition-duration: 0.3s;
  transform: translateY(460px);
  /* #ifndef APP-NVUE */
  z-index: 99;
  /* #endif */
}

.uni-calendar--ani-show {
  transform: translateY(0);
}

.uni-calendar__content {
  background-color: #fff;
}

.uni-calendar__header {
  position: relative;
  /* #ifndef APP-NVUE */
  display: flex;
  /* #endif */
  flex-direction: row;
  justify-content: center;
  align-items: center;
  height: 50px;
  border-bottom-color: $uni-border-color;
  border-bottom-style: solid;
  border-bottom-width: 1px;
}

.uni-calendar--fixed-top {
  /* #ifndef APP-NVUE */
  display: flex;
  /* #endif */
  flex-direction: row;
  justify-content: space-between;
  border-top-color: $uni-border-color;
  border-top-style: solid;
  border-top-width: 1px;
}

.uni-calendar--fixed-width {
  width: 50px;
  // padding: 0 15px;
}

.uni-calendar__backtoday {
  position: absolute;
  right: 0;
  top: 25rpx;
  padding: 0 5px;
  padding-left: 10px;
  height: 25px;
  line-height: 25px;
  font-size: 12px;
  border-top-left-radius: 25px;
  border-bottom-left-radius: 25px;
  color: $uni-text-color;
  background-color: $uni-bg-color-hover;
}

.uni-calendar__header-text {
  text-align: center;
  width: 100px;
  font-size: $uni-font-size-base;
  color: $uni-text-color;
}

.uni-calendar__header-btn-box {
  /* #ifndef APP-NVUE */
  display: flex;
  /* #endif */
  flex-direction: row;
  align-items: center;
  justify-content: center;
  width: 50px;
  height: 50px;
}

.uni-calendar__header-btn {
  width: 10px;
  height: 10px;
  border-left-color: $uni-text-color-placeholder;
  border-left-style: solid;
  border-left-width: 2px;
  border-top-color: $uni-color-subtitle;
  border-top-style: solid;
  border-top-width: 2px;
}

.uni-calendar--left {
  transform: rotate(-45deg);
}

.uni-calendar--right {
  transform: rotate(135deg);
}

.uni-calendar__weeks {
  position: relative;
  /* #ifndef APP-NVUE */
  display: flex;
  /* #endif */
  flex-direction: row;
}

.uni-calendar__weeks-item {
  flex: 1;
}

.uni-calendar__weeks-day {
  flex: 1;
  /* #ifndef APP-NVUE */
  display: flex;
  /* #endif */
  flex-direction: column;
  justify-content: center;
  align-items: center;
  height: 45px;
  border-bottom-color: #f5f5f5;
  border-bottom-style: solid;
  border-bottom-width: 1px;
}

.uni-calendar__weeks-day-text {
  font-size: 14px;
}

.uni-calendar__box {
  position: relative;
}

.uni-calendar__box-bg {
  /* #ifndef APP-NVUE */
  display: flex;
  /* #endif */
  justify-content: center;
  align-items: center;
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
}

.uni-calendar__box-bg-text {
  font-size: 200px;
  font-weight: bold;
  color: $uni-text-color-grey;
  opacity: 0.1;
  text-align: center;
  /* #ifndef APP-NVUE */
  line-height: 1;
  /* #endif */
}
</style>

20.主页悬浮按钮,uni使用

适用于小程序和H5

子页面
<template>
  <view>
    <view
      class="fixedView icon"
      @longpress.stop="touchIcon"
      @touchmove.stop.prevent="moveIcon"
      @tap.stop="tapIcon"
      :style="{
        left: iconPosition.left + 'px',
        top: iconPosition.top + 'px',
        width: iconSize.width + 'rpx',
        height: iconSize.height + 'rpx',
      }"
    >
      <image
        :src="iconPath || icon_path"
        :style="{
          width: iconSize.width + 'rpx',
          height: iconSize.height + 'rpx',
        }"
        mode="aspectFill"
      ></image>
    </view>
  </view>
</template>

<script>
export default {
  data() {
    return {
      screenHeight: uni.getSystemInfoSync().screenHeight,
      icon_path:
        'data:image/png;base64,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',
      windowSize: {
        width: 0,
        height: 0,
        margin: {
          left: 10,
          right: 10,
          top: 10,
          bottom: 10,
        },
      },
      iconSize: {
        width: 100,
        height: 100,
      },
      iconPosition: {
        left: 0,
        top: 0,
        touchPostion: {
          x: 0,
          y: 0,
        },
      },
    }
  },
  props: {
    startPostion: {
      type: Number,
      default: 0,
    },
    iconWidth: {
      type: Number,
      default: 100,
    },
    iconHeight: {
      type: Number,
      default: 100,
    },
    marginLeft: {
      type: Number,
      default: 10,
    },
    marginRight: {
      type: Number,
      default: 10,
    },
    marginTop: {
      type: Number,
      default: 10,
    },
    marginBottom: {
      type: Number,
      default: 10,
    },
    iconPath: {
      type: String,
      default: '',
    },
    /*tapFunction:{
				type:Function,
				default:this.tapIcon
			}*/
  },
  mounted() {
    this.$set(this.iconSize, 'width', this.iconWidth)
    this.$set(this.iconSize, 'height', this.iconHeight)
    this.$set(this.windowSize.margin, 'left', this.marginLeft)
    this.$set(this.windowSize.margin, 'right', this.marginRight)
    this.$set(this.windowSize.margin, 'top', this.marginTop)
    this.$set(this.windowSize.margin, 'bottom', this.marginBottom)
    this.$set(this.windowSize, 'width', uni.getSystemInfoSync().windowWidth)
    this.$set(this.windowSize, 'height', uni.getSystemInfoSync().windowHeight)
    switch (this.startPostion) {
      case 1:
        //初始位置左上角
        this.$set(this.iconPosition, 'left', this.windowSize.margin.left)
        this.$set(this.iconPosition, 'top', this.windowSize.margin.top)
        break
      case 2:
        //初始位置右上角
        this.$set(
          this.iconPosition,
          'left',
          this.windowSize.width -
            uni.upx2px(this.iconSize.width) -
            this.windowSize.margin.right,
        )
        this.$set(this.iconPosition, 'top', this.windowSize.margin.top)
        break
      case 3:
        //初始位置左下角
        this.$set(this.iconPosition, 'left', this.windowSize.margin.left)
        this.$set(
          this.iconPosition,
          'top',
          this.windowSize.height -
            uni.upx2px(this.iconSize.height) -
            this.windowSize.margin.bottom,
        )
        break
      case 4:
        //初始位置右下角
        this.$set(
          this.iconPosition,
          'left',
          this.windowSize.width -
            uni.upx2px(this.iconSize.width) -
            this.windowSize.margin.right,
        )
        this.$set(
          this.iconPosition,
          'top',
          this.windowSize.height -
            uni.upx2px(this.iconSize.height) -
            this.windowSize.margin.bottom,
        )
        break
      default:
        //初始位置左居中
        this.$set(this.iconPosition, 'left', this.windowSize.margin.left)
        this.$set(this.iconPosition, 'top', this.screenHeight / 2)
    }
  },
  methods: {
    touchIcon(e) {
      this.$set(this.iconPosition.touchPostion, 'x', e.touches[0].clientX)
      this.$set(this.iconPosition.touchPostion, 'y', e.touches[0].clientY)
    },
    moveIcon(e) {
      this.$set(
        this.iconPosition,
        'left',
        e.touches[0].clientX - uni.upx2px(this.iconSize.width / 2),
      )
      this.$set(
        this.iconPosition,
        'top',
        e.touches[0].clientY - uni.upx2px(this.iconSize.height / 2),
      )

      this.$set(
        this.iconPosition,
        'left',
        Math.min(
          this.windowSize.width -
            uni.upx2px(this.iconSize.width) -
            this.windowSize.margin.right,
          this.iconPosition.left,
        ),
      )
      this.$set(
        this.iconPosition,
        'left',
        Math.max(this.windowSize.margin.left, this.iconPosition.left),
      )
      this.$set(
        this.iconPosition,
        'top',
        Math.min(
          this.windowSize.height -
            uni.upx2px(this.iconSize.height) -
            this.windowSize.margin.bottom,
          this.iconPosition.top,
        ),
      )
      this.$set(
        this.iconPosition,
        'top',
        Math.max(this.windowSize.margin.top, this.iconPosition.top),
      )
    },
    tapIcon(e) {
      console.log('you tap icon')
      this.$emit('tapIcon')
    },
  },
}
</script>

<style scoped lang="scss">
.fixedView {
  position: fixed;
  z-index: 200;
}

.icon {
  border-radius: 50%;
  overflow: hidden;
  border: none;
}
</style>




主页面
<template>
  <topicon
    class="topicon"
    :iconWidth="120"
    :iconHeight="120"
    :iconPath="require('@/static/homeIcon.png')"
    :marginBottom="60"
    :marginTop="45"
    :marginLeft="5"
    :marginRight="5"
    @tapIcon="tapIcon"
  ></topicon>
</template>

<script>
import topicon from "@/components/gwh-backTopIcon/gwh-backTopIcon.vue";
export default {
  components: {
    topicon,
  },
  methods: {
    tapIcon() {
      uni.reLaunch({
        url: "/pages/index/index",
      });
    },
  },
};
</script>

21.获取canvas生成的图片路径

uni.canvasToTempFilePath(object, component)

把当前画布指定区域的内容导出生成指定大小的图片,并返回文件路径。在自定义组件下,第二个参数传入自定义组件实例,以操作组件内 <canvas> 组件。

https://uniapp.dcloud.net.cn/api/canvas/canvasToTempFilePath.html#

22.保存图片到本地相册

uni.saveImageToPhotosAlbum(OBJECT)

https://uniapp.dcloud.net.cn/api/media/image.html#saveimagetophotosalbum

23.weapp-qrcode生成二维码 (canvas)

https://developers.weixin.qq.com/community/develop/article/doc/00002064e6c920917be96c1ed56013

24.picker延迟问题

关闭等待动画加载完成后才改变选项值

  :immediate-change="true"

25.文字横向无限滚动效果

组件引入使用

  <text-scroll class="context" :text="boardRemark"></text-scroll>
  .context {
    font-size: 24rpx;
    color: #333333;
    max-width: 561rpx;
    width: 561rpx;
    display: inline-block;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
<template>
  <view class="tip">
    <view class="inner" :class="{ move: scroll }" :style="styleName">
      <text class="tip-inder">{{ text }} {{ scroll ? text : '' }}</text>
    </view>
  </view>
</template>
<script>
export default {
  props: {
    text: {
      type: String,
      defualt: ''
    },
  },
  data () {
    return {
      styleName: "animation-duration: 20s",
      scroll: true,
      tipWidth: 0
    };
  },
  watch: {
    text: {
      handler (val) {
        this.textScroll()
      },
      immediate: false
    }
  },
  methods: {
    textScroll () {
      // 等待节点挂载后再执⾏,热门线路tip滚动实现
      this.$nextTick(() => {
        let query = wx.createSelectorQuery().in(this)
        query.select('.tip').boundingClientRect(data => {
          this.tipWidth = data.width
          console.log('tip', this.tipWidth)
        }).exec();
      })
    }
  }
}
</script>
<style lang="scss" scoped>
.tip {
  width: 100%;
  background: #ffffff;
  color: #4d82ff;
  font-size: 28rpx;
  height: 80rpx;
  line-height: 80rpx;
  overflow: hidden;
  box-sizing: border-box;
  white-space: nowrap;
}
.tip .inner {
  overflow: hidden;
  display: inline-block;
}
.tip .inner .tip-inder {
  white-space: nowrap;
  padding-left: 30rpx;
}
.tip .inner.move {
  // animation: move 6s infinite linear;
  animation-name: scroll;
  animation-timing-function: linear;
  animation-iteration-count: infinite;
}
@keyframes scroll {
  0% {
    transform: translateX(0);
  }
  100% {
    transform: translateX(-50%);
  }
}
</style>

26.打开地图对应位置

uni.openLocation({
    latitude: 30.077217,
    longitude:106.592148,
    name:'重庆合川区第二人民医院',
    address:'重庆市合川区三汇镇汇兴西路197号',
    success: function () {
        console.log('success');
    }
});

2.微信小程序

1.人脸识别

wx.startFacialRecognitionVerify({  
  name:'xxxxx',  
  idCardNumber: '1234566455',  
  //成功回调
  success: (res) => {  
    console.log(res);  
  },  
  //失败回调
  fail: (err) => {  
    console.log(err);  
  }  
});

2.微信支付

微信支付的两种方式
WeixinJSBridge,wx.chooseWXPay区别

wx.chooseWXPay({
    timestamp: 0, // 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符
    nonceStr: '', // 支付签名随机串,不长于 32 位
    package: '', // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=***)
    signType: '', // 签名方式,默认为'SHA1',使用新版支付需传入'MD5'
    paySign: '', // 支付签名
    success: function (res) {
        // 支付成功后的回调函数
    }
});

function onBridgeReady(){
   WeixinJSBridge.invoke(
       'getBrandWCPayRequest', {
           "appId" : "wx2421b1c4370ec43b",     //公众号名称,由商户传入     
           "timeStamp":" 1395712654",         //时间戳,自1970年以来的秒数     
           "nonceStr" : "e61463f8efa94090b1f366cccfbbb444", //随机串     
           "package" : "prepay_id=u802345jgfjsdfgsdg888",     
           "signType" : "MD5",         //微信签名方式:     
           "paySign" : "70EA570631E4BB79628FBCA90534C63FF7FADD89" //微信签名 
       },
       function(res){     
           if(res.err_msg == "get_brand_wcpay_request:ok" ) {}     // 使用以上方式判断前端返回,微信团队郑重提示:res.err_msg将在用户支付成功后返回    ok,但并不保证它绝对可靠。 
       }
   ); 
}

if (typeof WeixinJSBridge == "undefined"){
   if( document.addEventListener ){
       document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
   }else if (document.attachEvent){
       document.attachEvent('WeixinJSBridgeReady', onBridgeReady); 
       document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
   }
}else{
   onBridgeReady();
}


//如果没有WeixinJSBridge  可全局声明(根目录建shim.d.ts 里面声明):declare var WeixinJSBridge:any

3.wx.exitMiniProgram() 退出小程序

退出小程序

3.支付宝小程序

授权登录步骤:

方式一:获取anthcode(必须使用静默授权)=>后台换取token=>前台获取会员基本信息=>更新用户信息到后台。(注意:getopenuserinfo第一次需要用官方组件授权,之后可以直接调用。登录去需要判断授权信息来决定静默授权还是主动授权)

方式二:主动授权(必须)获取anthcode=>code给后台换取用户信息(后台需要使用alipay.user.userinfo.share)获取用户信息。其中包括用户实名信息。后台需注意参数,需要两token 一个是固定的。

0.授权获取用户信息 getopenuserinfo

先弹窗提醒用户 确认的时候onGetAuthorize 后可以调取api获取用户信息

<button
class="button"
open-type="getAuthorize"
scope="userInfo"
@getAuthorize="onGetAuthorize"
:style="{ color: '#0ab2c1' }"
>
  确认授权
</button>

1.v-show不生效

2.基础库1.0不支持分包,需要勾上IDE的使用2.0基础库。(切记)

3.v-html无效 需要使用 mini-html-parser 转换。

<rich-text nodes="{{nodes}}" onTap="tap"></rich-text>

4.showToast()不支持duration持续时间属性

5.this.$forceUpdate() 强制刷新视图

6.查看授权内容

 my.getSetting({
        success: async res => {
          console.log(res.authSetting, '授权信息 ')
          if (res.authSetting.userInfo) {
            //授权过
            await this.$store.dispatch('getUserInfo')
            this.getpatientList() //就诊人
            uni.$emit('updateCard')
            this.getannounceAnyData()
          } else {
            //提示授权
            this.$nextTick(() => {
              this.$refs.getInfoOpen.open()
            })
          }
        },
      })
    },

7.input光标错位问题

小程序中 input 如果父类是 position: fixed,可以加上 enableNative="{{false}}",解决输入框错位/光标上移问题。个别情况下定位问题会导致光标错位,所以需要把 false 改为 true,代码块为 enableNative="{{true}}"


8.获取用户信息

9.h5跳转小程序带参

query = xxx

alipays://platformapi/startapp?appId=2021003105603058&page=%2Fpages%2Flogin%2FuserLogin&query=redirect%3D%2Fpages-zy%2FappointmentDoc%2FdeptList

4.微信小程序原生开发

1.自定义导航栏

Taro

1.使用地图导航

1)小程序

import Taro from '@tarojs/taro';
模拟数据
const params = {
	title:'清华大学紫荆学生公寓5号楼',
	address:'北京海淀区清华大学紫荆学生公寓5号楼',
	latitude :'40.010907',
	longitude:'116.327148'
}
 const name = params.title;
 const address = params.address;
 const latitude =  Number(params.latitude);
 const longitude =  Number(params.longitude);
 
Taro.openLocation({
        name,
        address,
        latitude,
        longitude
 });

2)h5

const lat = latitude+","+longitude;
  let addrStr = `coord:${lat};title:${name};addr:${address}&referer=myapp`
  setTimeout(() => {
      location.href = `//apis.map.qq.com/uri/v1/marker?marker=${addrStr}`;
  },100)

2.

5.Ucharts

uCharts是一款基于canvas API开发的适用于所有前端应用的图表库,开发者编写一套代码,可运行到 Web、iOS、Android(基于 uni-app / taro )、以及各种小程序(微信/支付宝/百度/头条/飞书/QQ/快手/钉钉/淘宝/京东/360)、快应用等更多支持 canvas API 的平台。

https://www.ucharts.cn/v2/#/guide/index

本文作者:丶乔

本文链接:https://www.cnblogs.com/sclweb/p/17640140.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   丶乔  阅读(255)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起
  1. 1 尚好的青春 孙燕姿
  2. 2 孙燕姿
  3. 3 克卜勒 孙燕姿
- 孙燕姿
00:00 / 00:00
An audio error has occurred, player will skip forward in 2 seconds.