zoukankan      html  css  js  c++  java
  • 干货分享:小程序项目实践和经验总结

    最近接触小程序开发,我特将本次开发过程中所使用到的相关知识点进行了总结,以作为经验的积累。希望给自己以后的开发,提供一些帮忙,同时提高解决问题的能力。如有错误,请大家指正。

    github地址项目地址

    weui:使用微信原生视觉体验样式库

    认识: WeUI 是一套同微信原生视觉体验一致的基础样式库,由微信官方设计团队为微信内网页和微信小程序量身设计,令用户的使用感知更加统一。

    官网: https://weui.io/

    github地址: https://github.com/weui/weui-wxss

    微信推出了一套官方样式库,方便大家开发,对于一些类似的UI界面我们需要引入即可,无需重复造轮子。我们只需导入weui.wxss等即可减少大量的css布局工作.

    关于本地图片资源路径(background)

    小程序只有image标签支持本地图片资源路径,wxss里的background-image不支持。
    如果想在css中使用背景图,解决方法:

    1、将本地图片用线上地址转化成base64路径。线上转化base64的地址:http://imgbase64.duoshitong.com/

    2、url里面的图片来源必须填写外链。如下:

    area{
       background: url('https://mirror-gold-cdn.xitu.io/168e088859e325b9d85?imageView2/1/w/100/h/100/q/85/format/webp/interlace/1' ) no-repeat center;
    }
    

    websocket问题

    体验版支持ws协议,需要打开调试模式
    如果websocket是连接的域名非IP地址,则不能通过连接代理更改电脑的host来指定socket域名的解析地址
    如果有测试环境,建议:

    1. 建一个专有的测试环境websocket域名
    2. 直接使用测试环境的IP地址访问websocket

    关于时间格式在ios中处理方法

    背景: 由于ios只识别格式yyy/mm/dd格式,如"2018-10-31 20:30:00"格式无法识别;
    默认情况下数据库拿到的日期格式为“2018-08-30 12:00:00”,如果不替换“-”的话,在IOS下是不能通过getDate(datestring)获取到日期对象的。Android下两种格式均表现正常。

    解决方法: 通过正则替换掉所有的"-",如下:

    var dateStr = "2018-09-08 12:30:30"; // 后台返回的时间字符串
    dateStr = dateStr.replace(/-/g, '/');
    console.log(dateStr); 
    结果为:2018/09/08 12:30:30
    

    小程序DOM上附属参数,函数中获取参数方法

    view.wxml:

     // DOM上附属参数
    <view 
      data-id='{{fangyuanItem.id}}' 
      data-houseitemid='{{fangyuanItem.houseItemId}}' 
      catchtap='viewMendianDetail'>
    </view>
    

    view.js:

      // 函数中获取参数
      page({
          data:{},
          viewMendianDetail: function (e) {
            var roomtypeid = e.currentTarget.dataset.id;
            var houseItemId = e.currentTarget.dataset.houseitemid;
          }
      })
    

    注意: 附属参数时,data-key,key格式为小写;

    小程序 navigator 无法跳转 tabBar上的页面

    方法一:navigator 的 open-type 设置为 switchTab

    代码如下:

    <navigator url="../cart/index" open-type="switchTab">
       <text>首页</text>
    </navigator>
    

    方法二:wx.switchTab({})

    代码如下:

    index.wxml:

     <text catchtap="toIndex">首页</text>
    

    index.js:

     page({
        toIndex(){
            wx.switchTab({  
              url: '../cart/index'
            }) 
        }
     })
    

    wx.navigateTo和wx.switchTab导航传参

    wx.navigateTo导航传参

    1.wx.navigateTo,url通过参数拼接传参;

    // 访问房型详情
    viewMendianDetail: function (e) {
      var roomtypeid = e.currentTarget.dataset.id;
      var houseItemId = e.currentTarget.dataset.houseitemid;
      wx.navigateTo({
        url: '/pages/index/index?houseItemId=' + houseItemId + '&roomtypeid=' + roomtypeid,
      })
    }
    

    2.定位到的组件中通过生命周期函数onLoad接收参数对象,并设置本组件中的数据

    pages/index/index:

     onLoad: function (options) {
        //console.log(options)
        var houseItemId = options.houseItemId
        var roomtypeid = options.roomtypeid
        this.setData({
            houseItemId: houseItemId,
            roomTypeId: roomtypeid
        })
    }
    

    wx.switchTab导航传参

    1.前提:app.js中有定义全局变量searchInfo,如下:

    App({
        globalData: {
            searchInfo:{
              searchInput:"",
              laiyuan:0
            }
      }
    });
    

    2.通过app.globalData定义全局参数,如下:

    a.wxml:

    const app = getApp()
    page({
        data:{},
        toZhaofang:function(e){
            app.globalData.searchInfo = {
              "searchInput": searchInput,
              "laiyuan": 1
            }
            wx.switchTab({
              url: '/pages/tabbar/zhaofang/index',
            })
       }
    })
    

    3.通过app.globalData来接收全局参数,如下:
    zhaofang/index.wxml:

     const app = getApp()
     page({
        onLoad(){ 
           let searchInfo = app.globalData.searchInfo
           let searchInput = searchInfo.searchInput;
        }
     })
    

    自定义小程序转发功能

    默认情况下,我们需要点击小程序右上角的...才能看到转发,这样并不能对用户起到引导作用,通常的做法是使用一个button,并且设置open-type为share,这样就可以通过按钮启动分享。
    但是原生按钮很难看,我们可以设置一个图片,并且调整按钮的样式;

    效果如图:

    share.wxml:

    <button open-type="share"><image src="/images/icon-share.png"></image></button>
    

    share.wxss:

    button {
        padding:0;
        70rpx;
        height:70rpx;
        display:block;
        border:0;
        background: transparent;
    }
    button::after {
        border:0; 
    }
    

    注意: 尤其是对 button::after 要进行设置,否则按钮的边框是无法去掉的。

    通过 wx.getSystemInfo()来获取手机信息(包括宽,高)

    小程序提供的getSystemInfo()方法,该方法可以获取到设备的常用信息,如手机型号.设备像素比.屏幕宽高等等.最常用的就是屏幕宽高了.
    为了保证获取信息的准确性,wx.getSystemInfoSync是在页面初始化的时候就计算了。所以最好的方法是使用异步接口,并且在onReady函数中调用。

    info.js:

    Page({
      onReady: function (options) {
        this.getSystemInfo();
      },
      getSystemInfo:function(){
        wx.getSystemInfo({
          success: function (res) {
             console.log("手机屏幕的宽度为:" + res.screenWidth);
             console.log("手机屏幕的高度为:" + res.screenHeight);
            console.log("可视网页的宽度为:" + res.windowWidth);
            console.log("可视网页的高度为:" + res.windowHeight);
            console.log("手机的系统为:" + res.system);
            console.log("微信版本号为:" + res.version);
          }
        })
      }
    })
    

    结果如图:

    模板(template)定义与传参

    定义: WXML提供模板(template),可以在模板中定义代码片段,然后在不同的地方调用。
    使用 name 属性,作为模板的名字。如:

    1.定义模板文件
    baseTemplate.wxml:

    <template name="msgItem">
      <view>
        <text> {{index}}: {{msg}} </text>
        <text> Time: {{time}} </text>
      </view>
    </template>
    

    2.使用模板并通过data传递参数
    使用 is 属性,声明需要的使用的模板,然后将模板所需要的 data 传入。如下:
    user.wxml:

    <import src="../template/baseTemplate.wxml" />
     <block wx:for="{{goodlist}}" wx:key="idx">
        <template is="msgItem" data="{{...item}}"></template>
    </block>
    

    注意:

    1.通过data="{{...item}}"的方式传递参数时,被调用的模板中,不需要再写item;

    2.如果要传多个数据到模板,用逗号分开,item 是对象,index是单个数据,要用键值对.

    <view class="tab-list" wx:for="{{list}}" wx:key="index">
       <template is="day-tab" data="{{item,index:index,target:target}}" wx:key="index"></template>
    </view>
    

    user.js,数据定义格式如下:

    page({
       data:{
           goodlist:[
               { index: 0,msg: 'this is a template',time: '2016-06-18'},
               { index: 1,msg: 'this is a template1',time: '2017-06-18'},
               { index: 2,msg: 'this is a template2',time: '2018-06-18'}
           ]
       }
    })
    

    城市选择组件picker使用

    效果如图:


    组件介绍

    picker:从底部弹起的滚动选择器。

    代码如下:

    picker.wxml:

    <picker  
        mode='selector' 
        range="{{region}}" 
        range-key="{{'cityName'}}" 
        value='{{indexCity}}'
        bindchange="chooseCity" 
        >
        <view class="picker">  
            {{region[indexCity].cityName}}
        </view>  
    </picker>
    

    picker.js:

    page({
       data:{
           region:[
               {"cityName":"北京市","cityId":"12345"},
               {"cityName":"上海市","cityId":"67890"},
               {"cityName":"武汉市","cityId":"54321"},
           ]
       },
       chooseCity(e){
         var value = e.detail.value;  // index下标
       }
    })
    

    属性介绍

    mode(string):选择器类型;mode 的合法值:

    • selector:普通选择器;
    • multiSelector:多列选择器;
    • time:时间选择器;
    • date:日期选择器;
    • region:省市区选择器

    滑动组件scroll-view

    介绍: scroll-view:可滚动视图区域。使用竖向滚动时,需要给scroll-view一个固定高度,通过 WXSS 设置 height。组件属性的长度单位默认为px,2.4.0起支持传入单位(rpx/px)。

    详细文档请参考

    效果如图:

    使用方法如下:

    <scroll-view scroll-x="true"></scroll-view>
    

    注意:

    1.scroll-view的scroll-x失效的解决办法

    给scroll-view加上white-space: nowrap; 给scroll-view的子元素box加上display:inline-block即可。

    代码如下:

    .scroll-box {
       white-space: nowrap;
    }
    .scroll-box .box{
       display:inline-block
    }
    

    2.文本数据默认显示2行,超出部分用"..."代替:

    样式代码如下:

    line-height: 40rpx;
    white-space:pre-line;
    display:-webkit-box;
    -webkit-box-orient:vertical;
    -webkit-line-clamp:2;
    overflow:hidden;
    

    视图容器cover-image和cover-view

    使用背景:

    在微信小程序经常会用到一些原生组件,比如map、video、canvas、camera,这些原生组件想让其他元素覆盖在其上,必须使用cover-view或者cover-image组件。

    cover-view

    介绍: 覆盖在原生组件之上的文本视图。可覆盖的原生组件包括 map、video、canvas、camera、live-player、live-pusher。只支持嵌套 cover-view、cover-image,可在 cover-view 中使用 button。组件属性的长度单位默认为px,2.4.0起支持传入单位(rpx/px)。

    注意: 只支持基本的定位、布局、文本样式。不支持设置单边的border、background-image、shadow、overflow: visible等。

    1、支持background-color,不支持background-image,如果你发现你的素材在真机出不来,而且你又设置了背景图片的话,那你可以把这些元素全部替换成cover-image。

    2、不支持overflow: visible也是有点坑,这样的话,你想超出依然显示,就需要设置一个同级元素并提升层级才能达到效果了。

    效果如图:

    示例代码如下:

    video.wxml:

    <video id="myVideo" src="http://wxsnsdy.tc.qq.com/105/20210/snsdyvideodownload?filekey=30280201010421301f0201690402534804102ca905ce620b1241b726bc41dcff44e00204012882540400&bizid=1023&hy=SH&fileparam=302c020101042530230204136ffd93020457e3c4ff02024ef202031e8d7f02030f42400204045a320a0201000400" controls="{{false}}" event-model="bubble">
      <cover-view class="controls">
        <cover-view class="play" bindtap="play">
          <cover-image class="img" src="/path/to/icon_play" />
        </cover-view>
        <cover-view class="pause" bindtap="pause">
          <cover-image class="img" src="/path/to/icon_pause" />
        </cover-view>
        <cover-view class="time">00:00</cover-view>
      </cover-view>
    </video>
    

    video.wxss:

    .controls {
      position: relative;
      top: 50%;
      height: 50px;
      margin-top: -25px;
      display: flex;
    }
    .play,.pause,.time {
      flex: 1;
      height: 100%;
    }
    .time {
      text-align: center;
      background-color: rgba(0, 0, 0, .5);
      color: white;
      line-height: 50px;
    }
    .img {
       40px;
      height: 40px;
      margin: 5px auto;
    }
    

    video.js

    Page({
      onReady() {
        this.videoCtx = wx.createVideoContext('myVideo')
      },
      play() {
        this.videoCtx.play()
      },
      pause() {
        this.videoCtx.pause()
      }
    })
    

    cover-image

    介绍: 覆盖在原生组件之上的图片视图,可覆盖的原生组件同cover-view,只支持嵌套在cover-view里。

    cover-image发现了两个问题:

    1、虽说和image组件基本一样,但是设置mode属性也就是图片裁剪、缩放的模式无效

    2、宽度固定,高度auto,时,按照正常效果应该是图片按比例伸缩展示,但是发现该组件高度一直为0,只能根据应用场景寻找其他替代方案了。

    视图容器swiper

    介绍: 滑块视图容器。其中只可放置swiper-item组件,否则会导致未定义的行为。

    效果如图:

    代码如下:

    swiper.wxml:

    <view class="area">
       <view class="fuTitle">swiper</view>
       <view class="intro"> 
          <text class="one-title">介绍:</text>
          <text>滑块视图容器。其中只可放置swiper-item组件,否则会导致未定义的行为。</text>
       </view>
       <view class="item">
          <swiper 
            indicator-dots="{{indicatorDots}}"
            indicator-color="{{indicatorColor}}"
            indicator-active-color="{{indicatorActiveColor}}"
            previous-margin="{{previousMargin}}"
            next-margin="{{nextMargin}}"
            display-multiple-items="{{itemsNum}}"
            autoplay="{{autoplay}}" 
            interval="{{interval}}" 
            duration="{{duration}}"
            bindchange="bindchange"
            easing-function="{{easing}}"
            >
            <block wx:for="{{imgUrls}}" wx:key="{{index}}">
              <swiper-item item-id="{{index}}">
                <image src="{{item}}" class="slide-image" width="355" height="150"/>
              </swiper-item>
            </block>
          </swiper>
       </view>
    </view>
    

    swiper.js

    Page({
        data: {
             imgUrls:[
               "../../images/bo1.jpg",
               "../../images/bo2.jpg",
               "../../images/bo3.jpg",
               "../../images/bo4.jpg"
             ],
             indicatorDots: true,    // 是否显示滚动圆点图标
            indicatorColor: "#07c160", // 指示点颜色
            indicatorActiveColor: "#28d3ee", // 当前选中的指示点颜色
            previousMargin: "10rpx", // 前边距,可用于露出前一项的一小部分,接受 px 和 rpx 值
            nextMargin: "10rpx",     // 后边距,可用于露出后一项的一小部分,接受 px 和 rpx 值
            itemsNum:1,              // 同时显示的滑块数量
            easing: "default",       // 指定 swiper 切换缓动动画类型
            autoplay: true,         // 是否自动播放
            interval: 5000,         // 自动切换时间间隔
            duration: 1000          // 滑动的动画时长
        }
    })
    

    rich-text实现富文本解析

    介绍: 富文本。主要用来解析服务端传递过来的富文本html格式的数据,进行展示在页面上。类似于vue的v-html指令;

    效果如图:

    代码如下:

    richText.wxml:

    <view class="rich-area">
          <rich-text nodes="{{article_content}}" bindtap="tapRichText"></rich-text>
    </view>
    

    richText.js:

    Page({
       data: {
         article_content: '<p>自我介绍1</p><p><img src="https://mirror-gold-cdn.xitu.io/168e088859e325b9d85?imageView2/1/w/100/h/100/q/85/format/webp/interlace/1" width="100" height="100"/></p><p>自我介绍2</p><p><img src="https://mirror-gold-cdn.xitu.io/168e088859e325b9d85?imageView2/1/w/100/h/100/q/85/format/webp/interlace/1" width="100" height="100"/></p><p>自我介绍3</p><p><img src="https://mirror-gold-cdn.xitu.io/168e088859e325b9d85?imageView2/1/w/100/h/100/q/85/format/webp/interlace/1" width="100" height="100"/></p>',
       }
    });
    

    小程序中运用高德地图绘制静态图

    功能背景

    在小程序的页面中,需要显示某个位置的具体地理坐标并做好标记;如果直接使用map组件,无法满足功能需求,同时会存在页面层级重叠的问题;所有就选择了高德地图微信小程序sdk,绘制静态图来呈现。

    效果如图:

    开发步骤

    1.获取高德Key

    点我获取Key>>
    点我查看申请高德Key的方法>>

    2.绘制静态图

    简介:
    由于微信内无法运行第三方地图,高德对广大开发者提供了静态地图功能,可快速生成一张地图图片,可以指定显示的地图区域、图片大小、以及在地图上添加覆盖物,如标签、标注、折线、多边形。 可用于快速生成一张个性化涂鸦的静态地图用于查看和分享。

    静态图上绘制点

    1、在页面的 js 文件中,实例化 AMapWX 对象,请求显示静态地图。

    首先,引入 amap-wx.js 文件(amap-wx.js 从相关下载页面下载的 zip 文件解压后得到)。

    xinxi.js:

    var amapFile = require('path/to/amap-wx.js');//如:..­/..­/libs/amap-wx.js
    

    然后,构造 AMapWX 对象,并调用 getStaticmap 方法。
    其中,注意: 把百度地图坐标转换成高德,腾讯地图坐标

    var zuobiaoArr = network.bMapTransQQMap(lng,lat)
    
    Page({
      data: {
        pointObj:{
          lng:'您的坐标经度值',
          lat:'您的坐标纬度值'
        },
        src: ''
      },
      onLoad: function() {
        var that = this;
        var myAmapFun = new amapFile.AMapWX({key:"您的Key"});
        wx.getSystemInfo({
          success: function(data){
            var height = data.windowHeight;
            var width = data.windowWidth;
            var size = width + "*" + height;
            myAmapFun.getStaticmap({
              zoom: 8,
              size: size,
              scale: 2,
              markers: "mid,0xFF0000,A:"+pointObj.lng+","+pointObj.lat",
              success: function(data){
                that.setData({
                  src: data.url
                })
              },
              fail: function(info){
                wx.showModal({title:info.errMsg})
              }
            })
          }
        })
      }
    })
    

    注意:
    data.windowHeight,data.windowWidth获取的是整个窗口的高度和宽度,这里可以根据需求自己设定地图要显示的宽高。
    markers: "mid,0xFF0000,A:"+pointObj.lng+";"+pointObj.lat",用于设置地图上要显示的标记坐标;如果要显示多个标记,格式为:

    markers: "mid,0xFF0000,A:116.37359,39.92437;116.47359,39.92437"; // 多个坐标点以";"分割;
    

    2、编写页面的 wxml 文件,搭建页面结构。

    xinxi.wxml:

    <view class="img_box">
      <img src="{{src}}">
    </view>
    

    3、编写页面的 wxss 文件,设置页面样式。

    xinxi.wxss:

    .img_box{
      position: absolute;
      top: 0;
      bottom: 0;
      left: 0;
      right: 0;
    }
    .img_box image{
       100%;
      height: 100%;
    }
    ……
    

    4.注意细节:

    如果你提供的 pointObj:{lng:'您的坐标经度值',lat:'您的坐标纬度值'}数据对象为百度地图的坐标值,我们需要将其转换为高德地图坐标值(它们的坐标计算方式不同);

    转换方法如下:

    //百度地图坐标转为高德,腾讯地图坐标
    function bMapTransQQMap(lng, lat) {
        let x_pi = 3.14159265358979324 * 3000.0 / 180.0;
        let x = lng - 0.0065;
        let y = lat - 0.006;
        let z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_pi);
        let theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_pi);
        let lngs = z * Math.cos(theta);
        let lats = z * Math.sin(theta);
        return {
            lng: lngs,
            lat: lats
        }
    }
    let pointObj = bMapTransQQMap(lng,lat); // 转换之后的坐标值;
    

    结束:

    如果你也一样喜欢前端开发,欢迎加入我们的讨论/学习群,群内可以提问答疑,分享学习资料;

    欢迎添加群主微信和qq群答疑:

  • 相关阅读:
    C#实现京东登录密码加密POST
    查询SQL Server数据库所有表字段备注
    DataGridView数值列和日期列
    (转)Android 系统 root 破解原理分析
    Dynamics AX 中重点数据源方法
    .NET中Debug模式与Release模式
    DotNetBar的初步使用
    省市区联动小功能
    多余的Using Namespaces或引用会影响程序的执行效率么?
    MSIL指令集
  • 原文地址:https://www.cnblogs.com/wdlhao/p/11319487.html
Copyright © 2011-2022 走看看