小程序开发技巧总结
最近公司想开发一个电商小程序,匆匆看完文档就开始工作。整体开发体验感觉不太好,尤其是之前习惯了Vue开发,突然去开发小程序。以下是我在开发中遇到的一些问题和解决方法的总结,仅供参考。
引入iconfont
在小程序中引入字体图标比web要麻烦一点。简单来说,需要三个步骤:
下载iconfont,将iconfont.css复制到iconfont.wxss,引入app.wxss
在unicode模式下检查iconfont的在线链接,并将iconfont.wxss中的链接替换为远程链接。
介绍对应的icon classion class=' icon font icon-pay '/icon copy code
使用less
vs code有一个简单的less插件,这是我最容易少用的方法。
Vscode安装不太容易的插件
创建一个较少的目录来存储较少的文件。
向文件头//out:添加编译注释./pages/index/index.wxss,compress : true,sourcemap 3360 false
Ctrl保存后自动编译
编译结果
按钮重置
小程序中的按钮功能强大,很多功能都必须使用按钮,比如弹出用户授权、调用客服功能。默认样式一般无法满足需求。您可以统一重置按钮样式,然后编写自己的样式。
按钮{ padd : 0;背景# fff线高: 0; after { border-color :透明;}}.按钮悬停{ background: # fff} Copy代码
支持async-await
async-await是ES7的语法。在撰写本文时,applet仍然不支持async-await语法,因此我们需要使用再生器库。
下载再生器,并将再生器-运行时放在的utils目录中。
2.从“”导入再生器运行时。在util.js中引入了“/Regenerator-runtime/runtime-module”来封装wxRequest,这样就可以支持async-await const wxRequest=async(URL,Params={ })={ object . assign(Params,{ token 3360 wx . getstoragesync(' token ')})//所有请求,Header都携带tokenletheader=Params . Header | | { ' content-type ' 3: ' application/JSON ',' token ' 3360 Params . token | | ' ' } letdata=1
ams.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
- 下载wxParse,放到utils目录下
- 在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); }})复制代码
- 显示解析内容
<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()},// 上拉onReachBottom: function () { if(this.data.list.length >= this.data.count) { return false } this.setData({ page: this.data.page + 1 }) this.getData() wx.stopPullDownRefresh()},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) =>{ // 图片上传成功后,后端会返回一个地址,可以把它存到imgUrls this.imgUrls.push(res.data.data) }, fail:(err) => { console.log(err) } }) }) }})复制代码
动态标题
onLoad的时候动态设置标题
wx.setNavigationBarTitle({ title: '新标题'})复制代码
结语
以上是仅为我个人在开发过程中遇到的一些问题,若有错误还请批评指正,感谢阅读.