微信小程序

280 阅读8分钟

不定时更新记录,为有一天能自己看看,发现还可以进步

7.小程序分享,让系统自动截图技巧\color{#0000ff}{7.小程序分享,让系统自动截图技巧}

小程序分享时,不指定固定的图片,微信就会截取当前页面从顶部开始某一区域(高度是大概三分之一屏左右)。

image.png

红框就是我们不想要的,没有重要信息
如果我们想要分享出去的小程序链接图片区域能展示一些用户感兴趣的信息,这个截取的区域就比较重要了。

  1. 平时我们的正常页面元素较多,截取的区域重要信息不多,那我们可以给不重要的区域元素加上一个wx:if(uni-app: v-if)
  2. 点击分享按钮时把这些区域都隐藏掉,就完美截到想要的区域了。
  3. 最关键的是分享完怎么显示出隐藏的区域,微信小程序有一个重要的周期函数,onShow()就可以解决这个问题
    <view v-if="isShow">不需要截图显示区域</view>
     
    onShow(){
      // 显示全部
      this.isShow = true;
    },
    methods: {
       /** 分享*/
      onShareAppMessage() {
        this.isShow = false;
        return {
            title: '有一票新的订单,快来看看吧~', // 分享标题
            path: '/pages/****/index' // 默认为当前页面路径
            //,imageUrl: '/static/img/logoShare.png' // 默认为当前页面的截图
        }
      }
    }

8.小程序获取当前(中文)位置\color{red} {8.小程序获取当前(中文)位置}

小程序已经有自带的API接口(wx.authorize wx.getLocation)获取定位了,但只是拿到一个经纬度坐标。很多时候我们需要是中文的地理位置,就需要借助一些工具了

高德的微信小程序SDK
首先在高德开放平台,注册账号并且申请相关的 key 等信息;
然后下载它的微信小程序版 SDK:微信小程序 SDK
放到一个common里公共文件夹,方便引用。下面是单文件引用。

// 要用到的index页面
import amap from '../../common/amap-wx.js';  
export default {  
    data() {  
        return {  
            amapPlugin: null,  
            key: '高德key',  
            addressName: '',  
            weather: {  
                hasData: false,  
                data: []  
            }  
        }  
    },  
    onLoad() {  
        this.amapPlugin = new amap.AMapWX({  
            key: this.key  
        });
        this.getRegeo();
    },  
    methods: {  
        getRegeo() {  
            uni.showLoading({  
                title: '获取信息中'  
            });  
            this.amapPlugin.getRegeo({  
                success: (data) => {  
                    console.log(data)  
                    this.addressName = data[0].name;  
                    uni.hideLoading();  
                }  
            });  
        }  
    }  
}

百度地图服务接口
首先在百度开放平台,注册账号并且申请相关的 ak(就是一个key,百度文档叫ak) 等信息; 然后:

  • 一、是可以下载它的微信小程序版 SDK:微信小程序 SDK
  • 二、是直接调用百度的服务接口,它支持JavaScript调用 方法一和上面的高德地图类似,几乎一样,有文档链接就不说了。

方法二如下: 先从微信小程序自带的接口获取经纬度,就一开始说两个方法。

// index.vue
onLoad() {
    let _that = this;
    // 微信小程序获取授权定位
    uni.authorize({
      scope: 'scope.userLocation',
      success() {
        // 微信小程序获取经纬度
        uni.getLocation({
          type: 'wgs84',
          success: function (res) {
            console.log('当前位置的经度lng:' + res.longitude);
            console.log('当前位置的纬度lat:' + res.latitude);
            // 百度经纬度转换
            _that.getRegeo(res.longitude, res.latitude);
          }
        })
      }
    })
    },

写一个一个我们平时请求后端的接口一样的函数

// @/api/map/map.js
import {request } from '@/common/utils/index.js';

module.exports = {	
    getMapPlace(x,y) {
        // 百度的url是 lat<纬度>,lng<经度>
        let ak = '自己去申请的ak';
        let url = "https://api.map.baidu.com/reverse_geocoding/v3/?ak=" + ak + "&coordtype=bd09ll&location=" + y + "," + x + "&output=json";
	return request.req({
		url:url,
		method:"GET"
	})
    }
}

// index.vue
import { getMapPlace } from '@/api/map/map.js';
onLoad(){// 内容不复制了,在上面},
methods:{
       /** 获取定位 */
      getRegeo(lng, lat) {  
        uni.showLoading({
          title: '获取信息中'  
        });
        // 百度 经纬度转换
        getMapPlace(lng, lat).then((res) => {
          if(res.status === 0) {
              // 获取成功
              console.log(res)
          }
          uni.hideLoading();
        })
     }
 }

9.计算两个时间之差:相差 多少天 多少小时 多少分 多少秒

// 计算两个时间之间的差值
export function timeSpace(start, end){
      if(!end){
        end = new Date().getTime();
      }
      // 转换成时间戳
      if(typeof start === 'string'){
        start = new Date(start).getTime()
      }
      if(typeof end === 'string'){
        end = new Date(end).getTime()
      }
      // 相差毫秒数
      let space = end - start;
      // 相差天数
      let days = Math.floor(space / (24 * 3600 * 1000));
      // 去除天数剩下毫秒数
      let leave0 = space % (24 * 3600 * 1000);
      // 相差小时
      let hours = Math.floor(leave0 / (3600 * 1000));
      // 去除小时剩下毫秒数
      let leave1 = leave0 % (3600 * 1000);
      // 相差分钟
      let minutes = Math.floor(leave1 / (60*1000));
      // 去除分钟剩下毫秒数
      let leave2 = leave1 % (60*1000);
      // 相差秒
      let seconds = Math.floor(leave2 / 1000);
      return {
            day: days,
            hour:hours,
            minute: minutes,
            second: seconds
      };
  }

10.小程序、H5、app端复制功能

这个本来支持uni-app中使用,小程序和app的第一个逻辑就是uni-app的方法,如果只是微信原生小程序和浏览器需要,可以直接用第二个逻辑

export default function uniCopy({content,success,error}) {
    if(!content) return error('复制的内容不能为空 !')
	content = typeof content === 'string' ? content : content.toString() // 复制内容,必须字符串,数字需要转换为字符串
	/**
	 * 小程序端 和 app端的复制逻辑
	 */
	//#ifndef H5
	uni.setClipboardData({
		data: content,
		success: function() {
			success("复制成功~")
			console.log('success');
		},
		fail:function(){
			success("复制失败~")
		}
	});
	//#endif
	
	/**
	 * H5端的复制逻辑
	 */
	// #ifdef H5
	if (!document.queryCommandSupported('copy')) { //为了兼容有些浏览器 queryCommandSupported 的判断
		// 不支持
		error('浏览器不支持')
	}
	let textarea = document.createElement("textarea")
	textarea.value = content
	textarea.readOnly = "readOnly"
	document.body.appendChild(textarea)
	textarea.select() // 选择对象
	textarea.setSelectionRange(0, content.length) //核心
	let result = document.execCommand("copy") // 执行浏览器复制命令
	if(result){
		success("复制成功~")
	}else{
		error("复制失败,请检查h5中调用该方法的方式,是不是用户点击的方式调用的,如果不是请改为用户点击的方式触发该方法,因为h5中安全性,不能js直接调用!")
	}	
	textarea.remove()
	// #endif
}

1. rpx

rpx是小程序为适应不同宽度的手机屏幕,而发明的一种长度单位。不管什么手机屏幕,宽度一律为750rpx。实际运行程序,它会自动根据手机屏幕的尺寸,换算成px。它的好处是换算简单,如果一个元素的宽度是页面的一半,只要写成width: 375rpx;即可。

2. globalData

全局数据在app.js文件里,App()方法的参数配置对象有一个globalData属性,这个属性就是我们要在多个页面之间分享的值。事实上,配置对象的任何一个属性都可以共享,一般起名为globalData只是为了便于识别。

//app.js
App({
  globalData: {
    now: (new Date()).toLocaleString()
  }
});

// index.js
const app = getApp();
Page({
  data: {
    now: app.globalData.now
  }
});

getApp()函数是小程序原生提供的函数方法,用于从页面获取 App 实例对象。拿到实例对象以后,就能从它上面拿到全局配置对象的globalData属性,从而把app.globalData.now赋值给页面脚本的now属性,进而通过数据绑定机制,变成页面的全局变量now

3. this.setData()的第二个参数

this.setData()的第二个参数,至于第一个参数就是赋值,天天用不说了。this.setData()方法的第二个参数是一个函数,它会在页面变更完毕后(即this.setData()执行完)自动调用这个匿名函数,这个应用很多,用来做提示出来的时间点很准确。

// index.js
Page({
  data: {
    age: '23'
  },
  nextYearBtn(event) {
    this.setData({
      age: '24'
    }, function () {
      wx.showToast({
        title: '又过一年了',
        duration: 3650
      });
    }),
  }
});

4. block标签

<block>标签,他类似Vue中的 <template>。他的表现为,看例子:

<block>
  <view>block1</view>
  <view>block2</view>
  <view>block3</view>
</block>

//渲染后结果, 打开后台的wxml, 会发现block节点消失
  <view>block1</view>
  <view>block2</view>
  <view>block3</view>

在一个文件内,我们有几个同等级的标签,如果没有block节点,需要这么做:

<view>
  <view>block1</view>
  <view>block2</view>
  <view>block3</view>
</view>

这样做的后果是多渲染了一层DOM根节点,这样会造成一些内存增加,浪费了性能。
所以block会比较好解决这样的浪费,比较常用来配合wx:if

<block wx:if="{{ isShow }}">
  <view wx:for="{{ arr }}" wx:key="index">{{ item }}</view>
</block>

5. 图片高度自适应

图片宽度设置比例时,如100%,高度无法自适应。这个我想吐槽很久了,
因为小程序底层已经对 image 添加了宽高了,所以默认就是 240px。 解决方法是给 image 元素添加 mode 属性

    <image src="example.png" mode="widthFix"></image>

当添加此模式并给图片设置 100% 宽度后,小程序自动计算其高度,就可以让图片自适应了。
后面是废话。
一开始写小程序,我就发现这个了,开始以为自己的问题,然后发现这个根本就是没有适配这个,还要自己加属性才行。每次都要自己去查询图片的像素比例,自己换算比例,但是有时候后台给的base64验证码,我还要慢慢试探才知道宽高比例,不然就是产品问我为什么验证码变形了。。。。我:变形!。。是有什么奇奇怪怪的手机用我们的产品?!。。。是我的问题。

6. 传参

路由跳转传参,router 跳转传参及参数获取,在小程序开发中,方法不能直接这样传参bindtap='click(itme)',所以在执行方法时,又要使用该点击的 item 时就有点难搞了。微信就弄了一个属性data-[你自己命名]="{{要传的参数}}"。可以设置多个。
注意:通过 wxml 设置 data-[参数名] 传递参数,[参数名]只能是小写,不能有大写

//wxml
<view>
    <text wx:for="{{ arr }}" wx:key="{{ index }}" bindtap='click' data-id="{{ index }}">
        {{ item.name }}
    </text>
</view>

//js
function click(e) {
  // e 点击事件的产生的参数,如位置,属性等等
  let id = e.currentTarget.dataset.id;

  //跳转到classify 页面
  wx.navigateTo({
    url: '../index/index?id=' + id
  })
}
    

当然我们也可以这样做:wxml 页面(参数多时可用“&”)

<navigator url='../index/index?id=1&name=aaa'></navigator>

或者添加点击事件,jsnavigateTo 跳转传参,两种效果一样

 wx.navigateTo({
     url: '../index/index?id=1&name=aaa',
 })

最后上面两种到跳转后的页面都是这样的,onload 加载时

//index 页面 获取参数
onLoad: function (opts) {
  console.log(opts)
}