likes
comments
collection
share

微信小程序技术总结

作者站长头像
站长
· 阅读数 38

小程序单向数据流

单向数据流就是从逻辑层到视图层,vue也是单向数据流Model - view,但是实现了双向数据绑定。而小程序没有做劫持代理,所以不能进行双向数据绑定。但现在小程序是有双向数据绑定这个概念的,叫简易的双向数据绑定。

胶囊按钮

需求:logo需要同右边的胶囊按钮顶部对齐。

解决方法:使用 wx.getMenuButtonBoundingClientRect()

微信小程序技术总结


输出下 wx.getMenuButtonBoundingClientRect(),可以看见胶囊按钮的信息,需要注意的是单位为px。

微信小程序技术总结

wx.getMenuButtonBoundingClientRect().top就能获取到胶囊按钮距离信息栏的距离,然后将px转为rpx。

//视图层
<view style="height:{{logHeight}}rpx"></view>

//逻辑层
  data: {
      //logo图片高度,加入默认高度,防止页面渲染时图片闪动。
      logHeight:60,
  },

  attached:function(){
    let height=wx.getMenuButtonBoundingClientRect().top//获取顶部距离,单位是px  
    let deviceWidth = wx.getSystemInfoSync().windowWidth; //获取设备屏幕宽度
    let capsuleTop = (750 / deviceWidth) * height //得到rpx的值
    this.setData({
      capsuleTop
    })
  },

获取一个元素信息

需求:获取一个图片的高度,自适应图片宽度变化,高度也会变化。

解决办法:wx.createSelectorQuery()

注意两点:

1.要在ready函数中执行

2.在组件中使用wx.createSelectorQuery()之后,要用in()来指定范围。(将选择器的选取范围更改为自定义组件 component 内)或者在自定义组件或包含自定义组件的页面中,应使用 this.createSelectorQuery() 来代替

   视图层
   
   <image id="logoImg"  src="xxx.jpg" mode="widthFix"/>
   
   逻辑层
   
  //在组件在视图层布局完成后执行
  ready:function(){
    //加入定时器防止渲染时慢,无法获取节点。
    setTimeout(()=>{
      //创建节点选择器 ,in(this)传入组件实例防止获取为null,或者let query =this.createSelectorQuery()
      let query=wx.createSelectorQuery().in(this)
      //选择需要获取的元素
      query.select('#logoImg').boundingClientRect()
      //获取元素信息  
      query.exec(function(res){
        //获取元素高度(px)
        let clientHeight = res[0].height 
      })
    },120)

  },

输出下 query.exec(function(res){console.log(res)}) 会看见这个图片的信息,单位同样是px,需要转化成rpx。

微信小程序技术总结

小程序eCharts使用

第一步:进入eCharts官网点击下载选择下载,进入在线制定。按需要下载,减少体积

微信小程序技术总结

第二步:点击在线制定

微信小程序技术总结

第三步:选择需要的图形

微信小程序技术总结

第四步:下载

微信小程序技术总结

第五步:选择文档下的应用篇,选择跨平台方案,选择微信小程序

微信小程序技术总结

第六步:下载echarts-for-weixinecharts-for-weixin

微信小程序技术总结

用ec-canvas文件就行

微信小程序技术总结

第七步:将ec-canvas文件放入项目中

我这里是在组件中创建了echarts文件夹,就把ec-canvas文件中的文件全部放进去。注意如果是按需制定的echarts,将echarts.js替换成在线制定生成的echarts.min.js。

同时修改ec-canvas.js 中的 import * as echarts from './echarts'的引用文件。

微信小程序技术总结

第八步使用

配置组件使用

  "usingComponents": {
    "ec-canvas": "../echarts/ec-canvas"
  }

视图层

 <ec-canvas  id="mychart-dom-mapr" canvas-id="mychartBar"  ec="{{ ec }}"></ec-canvas>

逻辑层

//引入eCharts
import * as eCharts from '../../components/echarts/echarts'

  data: {
    ec: {
      onInit: initChart
    },
   }
   
   function initChart(canvas, width, height) {
         //绘制宽高
          let chart = echarts.init(canvas, null, {
            width: width,
            height: height
          });
          
           canvas.setChart(chart); //容器初始化
           echarts.registerMap('china', geoJson); //地图数据注册
           let option = {}
          
           chart.setOption(option); //返回初始化结果
           return chart;
   }

另外一种封装成组件

逻辑层

     /**
   * 组件的初始数据
   */
  data: {
    ec: {
      onInit: null
    },
  },
   
   //在组件实例进入页面节点树时执行
   attached:function(){
    this.setData({
      ec: {
        onInit: this.initChart
      }
    })
  },
   
   /**
   * 组件的方法列表
   */
  methods: {
    // eCharts 可视化地图
    initChart:function(e,width,height){
      //绘制宽高 地图模糊时候使用devicePixelRatio 调整清晰度
      const chart = eCharts.init(e,null,{
        width:width,
        height:height,
        devicePixelRatio: 2.5
      });

  //容器初始化
  e.setChart(chart); 
  //地图数据注册
  eCharts.registerMap('china', geoJson); 
  
  //初始化数据
  let option = {
      
  }
  chart.setOption(option); //返回初始化结果
  return chart;
},

大致效果:

微信小程序技术总结

navigateTo超出10个页面,粗糙解决办法

wx.navigateTo打开页面最多只能打开10个,超过10个之后就没反应。

// 导航列表跳转对应页面
handleNavigate:function(e){
  //获取全局变量
  const app=getApp()
  //获取全局变量中adCenterPitchOn的值
  let adCenterPitchOn=app.globalData.adCenterPitchOn

  //判断如果当前选中的id与全局变量中adCenterPitchOn不相等进行跳转,相等就不进入跳转程序,减少重复跳转。
  if(e.currentTarget.dataset.id!=adCenterPitchOn){
    this.setData({
      pitchOn:e.currentTarget.dataset.id
    })
    
    
    //navigateTo跳转不能打开10个页面,需要进行判断超过10个页面就关闭所有页面,重新进行页面栈个数统计
    let pages=getCurrentPages()//获取当前打开的页面
    let pagesLength=pages.length//获取当前打开页面的数量
    
    //打开页面数量大于等于10 使用reLaunch关闭所有页面,重新进行页面栈个数统计。
    if(pagesLength>=10){
      
      wx.reLaunch({
        url:e.currentTarget.dataset.path,
      })
    }else{
      //小于10 就使用navigateTo
      wx.navigateTo({
        url: e.currentTarget.dataset.path,
      })
    }
  }
}

这里不直接使用reLaunch是因为会重新渲染,跳转一次屏幕就会有闪动。所以进行粗糙的处理到了10个页面,使用reLaunch,十次之后才会闪动一次。

自定义tabBar

第一步:开启tabBar自定义

在app.json中找的tabBar加入custom:true

微信小程序技术总结

同时官方文档建议还是将list内容写上,用来兼容低版本。

微信小程序技术总结

第二步:创建目录

创建custom-tab-bar与pages同级。

微信小程序技术总结

第三步:custom-tab-bar中wxml编写

  <view 
  wx:key="index" 
  wx:for="{{list}}" 
  data-pagePath="{{item.pagePath}}" 
  data-index="{{index}}" 
  bindtap="getTabBarIndex"
  >
    <image  
    src="{{ selected===index? item.selectedIconPath : item.iconPath}}" 
    mode="widthFix>
    </image>
  </view>

第三步:tab-service工具类

创建一个工具类,用来处理custom-tab-bar切换

 //获取静态资源地址
 import config from '../config/config'

 //写好数据   
 let tabData = {
  selected:"",//当前选中tabBar
  list:[
    {
      "pagePath": "/pages/home/home",
      "iconPath": config.staticHost+"tabBar_home_def.png",
      "selectedIconPath": config.staticHost+"tabBar_home_active.png"
    },
    {
      "pagePath": "/pages/adCenter/adCenter",
      "iconPath": config.staticHost+"tabBar_advertising_def.png",
      "selectedIconPath": config.staticHost+"tabBar_advertising_active.png"
    },
    {
      "pagePath": "/pages/processing/processing",
      "iconPath": config.staticHost+"tabBar_data_def.png",
      "selectedIconPath": config.staticHost+"tabBar_data_active.png"
    },
    {
      "pagePath": "/pages/finance/finance",
      "iconPath": config.staticHost+"tabBar_money_def.png",
      "selectedIconPath": config.staticHost+"tabBar_money_active.png"
    },
    {
      "pagePath": "/pages/me/me",
      "iconPath": config.staticHost+"tabBar_me_def.png",
      "selectedIconPath": config.staticHost+"tabBar_me_active.png"
    }
  ]
}



// 更新底部高亮 获取下标,进行替换
const updateIndex = (that, index) => {
  tabData.selected = index
  updateTab(that, index)
}

// 更新Tab状态  点选选中效果不改变或者点击两次才改变解决办法
const updateTab = (that,index) => {
  if (typeof that.getTabBar === 'function' && that.getTabBar()) {
      //将值改为当前页面的下标
      that.getTabBar().setData(tabData);
  }
}

// 将可调用的方法抛出让外面调用
module.exports = {
   updateTab, updateIndex
}

第四步:custom-tab-bar中js逻辑层编写

点击时触发,进行跳转

 getTabBarIndex:function(e){
  //获取当前点击的下标及位置
  const tabBarData=e.currentTarget.dataset
  const presentPath=tabBarData.pagepath
  //跳转到对应页面,并关闭其他所有非 tabBar 页面
  wx.switchTab({
    url:presentPath,
  })
}

第五步:调用及高亮不变处理

在tab页引入const tabService = require("../../utils/tab-service");

const tabService = require("../../utils/tab-service");

Page({

  /**
   * 页面的初始数据
   */
  data: {
  },

  //将当前所在页的下标传入,解决选中没有高亮问题;
  onShow:function(){
    tabService.updateIndex(this, 4);
  },

})

微信小程序技术总结

获取机型

ios和android显示的效果会有差异,这就需要通过识别机型进行适配。

在app.js中使用 wx.getSystemInfoSync().platform获取手机型号

onLaunch() {
//获取机型
const res = wx.getSystemInfoSync().platform
//将机型放进缓存
if(res=='ios'){
    wx.setStorageSync('facility', "ios")
  }else{
    wx.setStorageSync('facility', "android")
 }
},

真机测试才行,模拟测试值是devtools

简单封装下wx.request

 //导入服务器配置信息
import config from '../config/config'

 export default (url,data,method='GET')=>{
  //初始化Promise实例
  return new Promise((resolve,reject)=>{
    wx.request({
      url:config.host+url,
      data,
      method,
      success:(res)=>{
        //成功之后修改Promise状态
        resolve(res)
      },
      fail:(err)=>{
        //失败之后修改Promise状态
        reject(err)
      }
    })
  })
 }
 
     

使用方法:

import req from '../../utils/request' //引入封装的地址
onLoad:async function(){
//获取数据
let pageImgData = await req('/cas/query')
},

关于传值的方法

全局变量使用

在app.js中使用globalData定义全局变量。

  // 定义全局变量
  globalData: {
    userInfo: null,
    tabBarIndex:0,
  }

app.globalData.变量名获取定义的变量值

 //获取全局变量
const app=getApp()
console.log(app.globalData.tabBarIndex)

//直接修改变量,不需要setData
app.globalData.tabBarInde=1

父组件传值给子组件

父组件使用子组件,传入父组件定义的值:tableHeaderData和tableList

     <DataList 
         tableHeader="{{tableHeaderData}}" 
         tableList="{{tableList}}" >
     </DataList>

子组件通过properties接收父组件传来的值

   /**
   * 组件的属性列表
   */
  properties: {
    //列表表头数据
    tableHeader:{
      type:Array,
      value:[],
    },
    //列表数据
    tableList:{
      type:Array,
      value:[]
    },
  },

父组件没有传值,子组件也不会报错。所以父组件可以按需传入相应得值。

    //父组件
   <DataList></DataList>
   
  //子组件接收值
  properties: {
    //列表表头数据
    tableHeader:{
      type:Array,
      value:[],
    },
  },

子组件传值给父组件

子组件通过triggerEvent给父组件传值

  //将值传给父组件
  this.triggerEvent("getLogHeight",62)      

父组件接收子组件传入的值

   //父组件使用子组进行件接收
   <NavLog bind:getLogHeight="getLogHeight"></NavLog>


  //父组件逻辑层进行获取
  getLogHeight:function(e){
    console.log(e.detail)
  }  
  

微信小程序技术总结

缓存

//设置缓存,传入数据
 wx.setStorageSync('facility', 2)
 
//获取缓存下的值
wx.getStorageSync('facility')

页面跳转传值

wx.navigateTo({
    url: 'xxx?data='+this.data.job,
 })
 
 

保留小数点后两位数

这样的写法报错,是因为wxml中不能直接使用较高级的js语法。
{{(item[secondArguments]/item[thirdArguments]).toFixed(2)}}


微信小程序技术总结

解决方案:引入wxs模块实现

根据开发场景使用,这里就单独创建一个wxs,放入工具文件夹中。

微信小程序技术总结

wxs中写入方法

 function ftoFixed(num) {
    return num.toFixed(2);
 }
 module.exports.ftoFixed = ftoFixed;

wxml中使用wxs

//引入wxs
<wxs module="utilsWxs" src="../../utils/utils.wxs"></wxs>

<text>
   {{utilsWxs.ftoFixed(item[secondArguments]/item[thirdArguments])}} 
</text>

本文用于学习记录,如有错误地方请多指正,谢谢。