小程序开发技巧总结

前言

最近公司要开发一款电商小程序,匆忙看了一遍文档就开始干活了。整体开发体验个人感觉不太好,特别是如果之前习惯了Vue开发,突然去开发小程序,感觉很鸡肋。以下是我在开发中遇到的一些问题以及解决方法的总结,仅供参考

引入iconfont

在小程序中引入字体图标要比web麻烦一些,简单说需要三步:

  1. 下载iconfont,把iconfont.css复制到iconfont.wxss,在app.wxss中引入
  2. 查看iconfont在unicode模式下的在线链接,替换iconfont.wxss中的链接为远程链接

  1. 在wxml文件中引入对应的icon class
<icon class="iconfont icon-pay"></icon>

使用less

vscode有一个easy less插件,是我感觉使用less最简单的方式

  1. vscode安装easy less插件
  2. 创建一个less目录,用于存放less文件
  3. 文件头部添加编译注释 // out: ../pages/index/index.wxss, compress: true, sourceMap: false
  4. ctrl + s保存后自动编译

编译后的结果

按钮重置

小程序中的按钮功能强大,很多功能必须要用按钮,比如弹出用户授权,调用客服功能。默认的样式一般无法满足需求,可以把按钮样式统一重置,然后自己写样式

button {
  padding: 0;
  background: #fff;
  line-height: 0;
  &::after {
    border-color: transparent;
  }
}
.button-hover {
  background: #fff;
}

支持async-await

async-await是ES7的语法,截止我写这篇文章为止,小程序还是不支持async-await语法的,所以需要使用regenerator-runtime这个库

  1. 下载regenerator-runtime并放到utils目录下
  2. 在util.js引入import regeneratorRuntime from ‘./regenerator-runtime/runtime-module‘
  3. 封装wxRequest,让它支持async-await
const wxRequest = async (url, params = {}) => {
  Object.assign(params, {
    token: wx.getStorageSync(‘token‘)
  })
  // 所有的请求,header默认携带token
  let header = params.header || {
    ‘Content-Type‘: ‘application/json‘,
    ‘token‘: params.token || ‘‘
  }
  let data = params.data || {}
  let method = params.method || ‘GET‘
  // hideLoading可以控制是否显示加载状态
  if (!params.hideLoading) {
   wx.showLoading({
     title: ‘加载中...‘,
   })
  }
  let res = await new Promise((resolve, reject) => {
    wx.request({
      url: url,
      method: method,
      data: data,
      header: header,
      success: (res) => {
        if (res && res.statusCode == 200) {
          resolve(res.data)
        } else {
          reject(res)
        }
      },
      fail: (err) => {
        reject(err)
      },
      complete: (e) => {
        wx.hideLoading()
      }
    })
  })
  return res
}

export {
  wxRequest
}

使用方法:

import regeneratorRuntime from ‘../../utils/regenerator-runtime/runtime-module.js‘
import {
  wxRequest
} from ‘../../utils/util.js‘

Page({
  data: {
   list:[],
   count: 0,
   page: 1,
   limit: 10
  },
  onLoad: function() {
    this.getList()
    // 请求已经结束 做其他事
  },
  getList: async function() {
    await wxRequest(app.globalData.baseUrl + ‘/test‘,{
      hideLoading: true,
      data: {
        limit: this.data.limit,
        page: this.data.page
      }
    }).then((ret) => {
      this.setData({
        list: ret.data.data,
        count: ret.data.num
      })
    })
  }
})

封装之后用起来还是很爽的,扩展起来也方便

动态设置data中某个值

应用场景:循环出来的列表,需要根据点击项,动态改变列表中对应id的数据

// 动态传递id
<block wx:for="{{list}}" wx:key="{{index}}">
  <view catch:tap="onChangeName" data-id="{{item.id}}"></view>
</block>

Page({
  data: {
    list:[{
      id: 0,
      name: ‘wang‘
    },{
      id: 1,
      name: ‘li‘
    }]
  },
  onChangeName: function(event){
    // 拿到id
   let id = event.target.dataset.id
   let key = `list[${id}].name`, val = ‘zhang‘
   // 设置值
   this.setData({
    [key]: val
   })
  }
})

flex布局,溢出省略号无效

订单列表一般都是左边一个图片,右边是标题或描述。这时候图片宽度是固定的,标题长度自适应

.wrap {
  display: flex;
}
.sub {
  flex: 1;
  width: 0; // 宽度设为0
}
.sub text {
  display: block; // 一定要设置成block
}

<view calss="wrap">
  <image src="i.png"/>
  <view class="sub">
    <text>一段文本一段文本一段文本一段文本一段文本一段文本</text>
    <view>其他</view>
  </view>
</view>

组件事件传递

任务:父组件向子组件传递初始数据,当子组件点击以后可以triggerEvent自定义事件,父组件执行自定义事件,重新请求数据并传给子组件

/* 子组件 */
<view>
  <view bind:tap="setId" data-id="1"></view>
</view>

properties: {
  list: {
    type: Array,
    default: []
  }
},

methods: {
  setId(e) {
    let id = e.currentTarget.dataset.id
    this.triggerEvent(‘deleteFav‘, id)
  }
}

/* 父页面 */
<child bind:customEvent="deleteFav"></child>

data: {
  list: []
},
deleteFav(e) {
  let id = e.detail // 获取传递过来的数据
  // 根据id请求数据,然后重新setData
  let newData = [1,2,3]
  this.setData({
    list: newData
  })
}

使用wxParse解析HTML

  1. 下载wxParse,放到utils目录下
  2. 在JS页面引入:import WxParse from ‘../../utils/wxParse/wxParse‘
Page({
  data:{
    contentHTML:‘‘ // 解析后的HTML
  },
  onLoad: function() {
    // 请求到的HTML数据
    let content = ‘<div>我是HTML代码</div>‘, that = this;
    WxParse.wxParse(‘contentHTML‘, ‘html‘, content, that, 0);
  }
})
  1. 显示解析内容
<import src="../../utils/wxParse/wxParse.wxml"/>
<view>
  <!-- 显示内容 -->
  <template is="wxParse" data="{{wxParseData:contentHTML.nodes}}" />
</view>

图片等比例

image标签有个mode属性,可以设置图片如何显示,如果文档看的不仔细还真容易发现

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

上拉加载和下拉刷新

{
  "onReachBottomDistance": 0,
  "enablePullDownRefresh": true
}
data: {
  limit: 30,
  page: 1,
  list:[],
  count:0
},
// 下拉
onPullDownRefresh: function () {
  this.setData({
    page: 1,
    list:[]
  })
  this.getData()
  wx.stopPullDownRefresh()
},
// 上拉
onReachBottom: function () {
  if(this.data.list.length >= this.data.count) {
    return false
  }
  this.setData({
    page: this.data.page + 1
  })
  this.getData()
},
getData: async function () {
  await wxRequest(app.globalData.baseUrl + ‘/test‘, {
    data: {
      page: this.data.page,
      limit: this.data.limit,
    }
  }).then((ret) => {
    let list = this.data.list.concat(ret.data.list)
    this.setData({
      list: list,
      count: ret.data.count
    })
  })
}

上传图片

任务:小程序上传图片到服务器,最多上传三张,前端可以删除图片

效果图如下

使用到的API有两个:wx.uploadFile wx.chooseImage

示例WXML:

<view class="sale after-pic">
  <block wx:for="{{imgList}}" wx:key="{{index}}">
    <view class="pic">
      <image src="{{item}}" />
      <icon type="clear" size="20" catchtap="clearImg" data-id="{{index}}"/>
    </view>
  </block>
  <image src="../../images/upload.png" catchtap="chooseImage" />
</view>
<button catchtap="onSub">提交</button>

imgList是wx.chooseImage成功后返回的图片临时地址

示例JS

Page({
  data: {
    imgList:[]
  },
  // 使用async await是因为图片上传是异步的
  onSub: async function() {
    // 点击提交后,开始上传图片
     let imgUrls = []
     for (let index = 0; index < this.data.imgList.length; index++) {
       await this.uploadFile(this.data.imgList[index]).then((res) => {
         // 这里要注意把res.data parse一下,默认是字符串
         let parseData = JSON.parse(res.data)
         imgUrls.push(parseData.data) // 图片地址
       })
     }
     console.log(imgUrls) // 3张图片上传成功后,执行其他操作
  },
  // 删除某张图片
  clearImg: function (params) {
    let imgList = this.data.imgList
    let id = params.currentTarget.dataset.id // 图片索引
    imgList.splice(id, 1) // 删除
    this.setData({
      imgList: imgList
    })
  },
  chooseImage: function (params) {
    wx.chooseImage({
      count: 3, // 做多3张
      sizeType: [‘original‘, ‘compressed‘],
      sourceType: [‘album‘, ‘camera‘],
      success: (res) => {
        // 存储临时地址
        this.setData({
          imgList: res.tempFilePaths
        })
      }
    })
  },
  uploadFile: function (filePath) {
    // 返回Promise是为了解决图片上传的异步问题
    return new Promise( (resolve, reject) => {
      wx.uploadFile({
        url: app.globalData.baseUrl + ‘/file/upload‘, // 上传地址
        filePath: filePath,
        name: ‘file‘, // 这里的具体值,问后端人员
        formData: {},
        header: {
          "Content-Type": "multipart/form-data"
        },
        success: (res) => {
           resolve(res)
         },
         fail: (err) => {
           reject(err)
           console.log(err)
         }
      })
    })
  }
})

动态标题

onLoad的时候动态设置标题

wx.setNavigationBarTitle({
  title: ‘新标题‘
})

结语

以上是仅为我个人在开发过程中遇到的一些问题,若有错误还请批评指正,感谢阅读

本文转载于猿2048:小程序开发技巧总结

原文地址:https://www.cnblogs.com/jlfw/p/12706682.html

时间: 04-15

小程序开发技巧总结的相关文章

微信小程序开发技巧总结(持续更新...)

小程序开发技巧总结 结合自己在平时的开发中遇到的各种问题,和浏览各种问题的解决方案总结出一些自己在日常开发中常用的技巧和知点,希望各位不吝斧正. 数据的生命周期 1.短生命周期数据存储 以小程序启动到彻底关闭为周期的的数据建议存储在app.js文件夹中,引用app.js: const app =getApp(); 假设Value是在小程序本次生命周期中经常使用到的一个数据,比如说请求API的Token,动态的令牌等.那么就可以把这个值赋值到全局变量中去.实际上,并不是只有app.js中的glob

你需要知道的小程序开发技巧

背景 一直以来进行了比较多的微信小程序开发... 总会接触到一些和官方组件或api相关或其无法解决的需求,于是决定在这里小小的整理一下自己的实现(次序不分先后) 自定义组件的使用 创建右键新建Component 引用在你需要引用的文件的json中定义 "注释": "前面为组件名,后面为路径,这里仅供参考" { "usingComponents": { "Menu": "../Components/Menu/Menu&

小程序开发另类小技巧 --用户授权篇

本文主要帮助大家解决部分功能接口二次授权+统一管理(包含对于wx对象的扩展)问题,例如获取地理位置信息,收获地址,录音等授权问题 小程序开发另类小技巧 --用户授权篇 getUserInfo较为特殊,不包含在本文范围内,主要针对需要授权的功能性api,例如:wx.startRecord,wx.saveImageToPhotosAlbum, wx.getLocation 原文地址:https://www.yuque.com/jinxuanzheng/gvhmm5/arexcn 仓库地址:https

@程序猿,你有一份小程序开发福利未领取!

只要关注第九程序官方微信公众号(djxcx9),@<微信小程序开发实战>图书一本哦!(详见文中活动规则!) "送书",就可获得参与活动链接! 奖品详情:这本书深入简出的介绍小程序的功能以及开发实战技巧!在上架不到半天的时间便被京东商城选为CTO 即日起至月日中午  关注第九程序公众号(),进入第九程序公众号,发送在微信文章底部留言说说示例:(送书)你对小程序开发的看法 截止到月日中午留言点赞数最高的前三名即可获得奖品.(为公平起见,第九程序将于月日中午截取留言区图片) 获奖

微信小程序开发优秀教程及文章合集第一期

我会不定期的选取一些优质教程,整理成辑,以便大家集中阅读: 新手向!微信小程序开发手记系列:微信小程序开发手记<一>:项目的代码结构微信小程序开发手记<二>:属性display微信小程序开发手记<三>:backgroud和border属性微信小程序开发手记<四>:视图容器微信小程序开发手记<五>:组件微信小程序开发手记<六>:API 艺龙系列:精品!艺龙小程序:开发项目遇到的问题以及解决方案:http://www.wxapp-unio

资讯 | 2018年1月15日微信公开课解读!微信小程序开发资源

引言:2018年1月15日 微信公开课PRO开课了,本次课时内容将涉及:小程序.智慧零售.企业微信.小游戏  (附学习参考资料) 为了快速理解「2018 微信公开课 PRO 版」上张小龙的一小时演讲内容,结合下午微信公开课课室A_B_C的课时安排,这里为大家提前整理了相应的小程序学习参考资料: 微信公开课pro_A课室(14:00-17:50) 主题:小程序产品能力.开发.应用及规则 一.如何开发一个优秀的微信小程序/小游戏 微信小程序官方工具  https://mp.weixin.qq.com

小程序开发中有趣的事情

小程序开发做了半年了,断断续续地利用课余时间写了一大部分. 期间遇到了很多坑和技巧,个人感觉十分有趣. 1.textarea 小程序里面的textarea是我遇到的第一个坑. textarea 在小程序里面看起来似乎和HTML里的一样,但是页面一滑动就有问题:欸欸欸??卧槽,卧槽,他怎么不动?:如果页面有弹层,弹层弹出的瞬间,卧槽卧槽?这个怎么在最上面?.textarea在小程序里面是原生层级最高的组件,z-index对他没用,并且在swipe.scroll-view.canve里面会出现奇奇怪

小程序+巧应用-微信小程序开发实战pdf

下载地址:网盘下载 系统全面地讲解微信小程序的开发技术.开篇创建一个小程序项目并解析体验,介绍如何由零开始创建一个小程序,全面体验小程序的开发工具.界面.开发框架.实现过程及其主要代码框架,了解小程序的应用场景及开发要求.接着介绍小程序开发基础,包括小程序开发的语言与语法.函数方法.模块.事件交互等.然后详细介绍了组件的应用与开发,包括开发过程与组件应用技巧,还详细分析了API接口,包括使用各个微信原生API接口进行小程序开发的技巧.最后介绍了几个小程序实战案例,让读者实践小程序各项能力的应用及

小程序开发总结一:mpvue框架及与小程序原生的混搭开发

mpvue-native:小程序原生和mpvue代码共存 问题描述 mpvue和wepy等框架是在小程序出来一段时间之后才开始有的,所以会出现的问题有:需要兼容已有的老项目,有些场景对小程序的兼容要求特别高的时候需要用原生的方式开发 解决思路 mpvue的入口文件导入旧版路由配置文件 公共样式 字体图标迁移 app.wxss -> app.vue中less(mpvue的公共样式) 旧项目导入 旧项目(native)拷贝到dist打包的根目录 这个要注意的就是拷贝的旧项目不能覆盖mpvue打包文件

小程序&#183;巧应用,微信小程序开发实战

系统全面地讲解微信小程序的开发技术.开篇创建一个小程序项目并解析体验,介绍如何由零开始创建一个小程序,全面体验小程序的开发工具.界面.开发框架.实现过程及其主要代码框架,了解小程序的应用场景及开发要求.接着介绍小程序开发基础,包括小程序开发的语言与语法.函数方法.模块.事件交互等.然后详细介绍了组件的应用与开发,包括开发过程与组件应用技巧,还详细分析了API接口,包括使用各个微信原生API接口进行小程序开发的技巧.最后介绍了几个小程序实战案例,让读者实践小程序各项能力的应用及掌握一些应用技巧.本