一.准备工作
全局安装vue-cli
如果需要使用vue旧版本init功能,需安装桥接工具
1
| npm install -g @vue/cli-init
|
随后创建一个基于mpvue-quickstart模板的新项目
1
| vue init mpvue/mpvue-quickstart my-project
|
然后填写项目名、微信appid、项目描述、作者
切换到生成的项目根目录,使用下列命令进行安装
打包微信小程序,使用下列命令同步编译微信开发者工具
随后用微信小程序开发框架导入即可
注意开发时随时查阅小程序开发文档:https://developers.weixin.qq.com/miniprogram/dev/api/
引入ColorUI:下载好后,打开template,把colorui文件夹复制到小程序static文件夹下,并且在全局src->main.js导入包,如下所示
1 2 3 4 5 6 7 8 9 10 11 12
| import Vue from 'vue' import App from './App'
import '../static/colorui/animation.wxss' import '../static/colorui/main.wxss' import '../static/colorui/icon.wxss'
Vue.config.productionTip = false App.mpType = 'app'
const app = new Vue(App) app.$mount()
|
开发时可查阅ColorUI文档:https://www.kancloud.cn/m22543/colorui/1289223
二.mpvue基础
简单的mpvue模板
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <template> <div>
</div> </template>
<script> export default{ data(){ return{} } } </script> <style> </style>
|
data的return中可以像Vue那样定义数据,其大部分语法和Vue基本一致
生命周期
1 2 3 4 5 6 7 8 9 10 11
| onLoad(){ console.log('--onload--'); }, beforeMount(){ console.log('--onload--'); this.handleGetUserInfo(); }, mounted(){ console.log('--onload--'); }
|
非冒泡事件
1 2 3
| <div @tap="toDetail" class="goStudy"> <p @tap.stop="handleChild">欢迎使用小程序</p> </div>
|
新建页面及跳转
使用wx.navigatTo方法,对应url参考:/pages/list/main,注意以main结尾,list为pages下的文件夹,其中包含一个main.js,写法如下:
1 2 3 4 5 6
| import Vue from 'vue' import List from './list.vue'
const list = new Vue(List)
list.$mount()
|
还有一个list.vue文件参照上方template模板来写。
创建main.json来配置局部页面信息。
实测出现错误如下
VM704:1 未找到 app.json 中的定义的 pages “pages/list/main” 对应的 WXML 文件
解决方法:重新执行npm start
组件复用
同样要新建一个页面,main.js必须存在但是可以不写内容,将页面写好后即可进行引用:
1 2 3 4 5 6 7
| <script> import ListTemp from'../list_template/list_template.vue' export default{ components: {ListTemp} } </script>
|
随后在template中使用模板即可,注意要用<div></div>标签包围,示例:
1 2 3 4
| <div> <ListTemp></ListTemp> //相当于引入上方list_template.vue页面 <ListTemp></ListTemp> </div>
|
Vuex
获取全局数据
安装
全局加载,修改全局main.js文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| import Vue from 'vue' import store from './store/store' import App from './App'
import '../static/colorui/animation.wxss' import '../static/colorui/main.wxss' import '../static/colorui/icon.wxss'
Vue.config.productionTip = false App.mpType = 'app'
Vue.prototype.$store=store
const app = new Vue(App)
app.$mount()
|
中途遇到依赖问题,根据提示安装其他依赖即可
由于时间仓促,并没有仔细研究Vuex的工作原理,只了解大概使用方式
首先在pages下创建store文件夹,里面分别有以下文件
actions.js
getter.js
mutation-type.js
mutations.js
state.js
store.js
将模拟数据放在src->datas->list-data.js中
1)mutation-type.js
1
| export const RECEIVE_LIST = 'receive_list'
|
2)action.js
1 2 3 4 5 6 7 8 9 10
| import { RECEIVE_LIST } from "./mutation-type" import listData from '../datas/list-data'
export default{ getList({commit}){ console.log("actions") commit(RECEIVE_LIST, listData) } }
|
3)mutations.js
1 2 3 4 5 6 7 8
| import {RECEIVE_LIST} from './mutation-type'
export default{ [RECEIVE_LIST](state, {list_data}){ state.listTmp = list_data console.log(state.listTmp) } }
|
4)state.js
1 2 3
| export default{ listTmp: [] }
|
5)store.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| import Vue from 'vue' import Vuex from 'vuex' import store from './store' import state from './state' import actions from './actions' import mutations from './mutations' import getters from './getter'
Vue.use(Vuex)
export default new Vuex.Store({ state, actions, getters, mutations })
|
目前暂时用到模拟数据,因此getter.js暂时不写
接下来加载动态数据,首先来到list.vue中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <script> import {mapState} from 'vuex' import ListTemp from'../list_template/list_template.vue' export default{ components: {ListTemp}, //组件注册 beforeMount(){ //分发action修改状态,填入action名字 this.$store.dispatch('getList') }, //之前打成compunted,但程序没有任何报错,要特别注意 computed:{ //映射状态到组件,名字和state.js中一致 ...mapState(['listTmp']) } } </script>
|
接下来遍历数据,并传入至list_template.vue这个组件模板中(其他模板同理)
1 2 3 4
| <div> <ListTemp v-for="(item,index) in listTmp" :key="index" :item="item" :index="index"></ListTemp> </div> <!--使用:key="index"解除警告,item为listTmp中的一个对象数据,前面加:来传入模板-->
|
在list_template.vue中,可以使用Vue语法来获取数据,如,但是要注意声明传入参数:
1 2 3 4 5 6 7
| <script> export default{ props:[ 'item','index' ] } </script>
|
这里注意使用v-bind:src来绑定图片,可以替换为 : 这个符号
1
| <image :src="item.avatar" mode="widthFix"></image>
|
加载详情页数据
首先创建详情页detail,过程不再叙述
在list_template.vue中,绑定跳转事件并且要传入index索引
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| <script> export default{ props:[ 'item','index' ], methods:{ toDetail(){ //跳转到详情页+传递参数index wx.navigateTo({ url: '/pages/detail/main?index='+this.index, success: (result) => { }, fail: () => {}, complete: () => {} }); } } } </script>
|
在detail.vue中,获取索引及数据,由于之前已经分发过actions,跳转至此页无需再分发
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| <script> import {mapState} from 'vuex' export default{ // onLoad(options){ // console.log(options) // } 原生小程序写法 data(){ return { detailObj:{} } }, beforeMount(){ //取代onload中options this.index = this.$mp.query.index; }, mounted(){ //更新state数据 this.detailObj = this.listTmp[this.index]; }, computed:{ ...mapState(['listTmp']) } } </script>
|
随后按照Vue的语法,在详情页载入数据即可
URL数据请求
注意,小程序中无法使用axios,会报XMLHttpRequest is not a constructor错误
安装flyio
全局main.js引入flyio,注意要放在挂载应用前
1 2 3
| var Fly=require("flyio/dist/npm/wx") let fly = new Fly Vue.prototype.$fly = fly
|
Get请求示例
1 2 3 4 5 6 7 8 9
| const TEST_URL="http://47.95.32.217:8080/monitorApplication/maintenance/getAll?pageNum=0&pageSize=19";
this.$fly.get(TEST_URL) .then(function (response) { console.log(response); }) .catch(function (error) { console.log(error); });
|
获取用户code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| wx.login({ success: function (res) { console.log(res) if (res.code) { console.log('通过login接口的code换取openid'); wx.request({ url: 'https://api.weixin.qq.com/sns/jscode2session', data: { appid: '', secret: '', grant_type: 'authorization_code', js_code: res.code }, method: 'GET', header: { 'content-type': 'application/json'}, success: function(openIdRes){ console.info("登录成功返回的openId:" + openIdRes.data.openid); }, fail: function(error) { console.info("获取用户openId失败"); console.info(error); } }) } } })
|
三.小程序案例
使用Promise.all上传多张图片
在项目开发中,会遇到上传图片未完成就提交了商品信息的情况,这样提交的图片URL为undefined,这是由于wx.uploadFile为异步执行造成的,因此要使用promise来保证其先执行完,再进行其他操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| var tempFilePaths = this.imgList; var submitImgList = this.submitImgList;
var promise = Promise.all(tempFilePaths.map((tempFilePath, index) => { var that = this; return new Promise(function (resolve, reject) { wx.uploadFile({ url: that.globalData.backgroundURL + 'upload/productImage', filePath: tempFilePath, name: 'productImage', formData: { }, success: function (res) { resolve(res.data); var data = JSON.parse(res.data); that.submitImgList.push(that.globalData.backgroundURL + data.data); that.resultCode = 200. }, fail: function (err) { reject(new Error('failed to upload file')); } }); }); }));
var that = this; promise.then(function (results) { console.log(results); that.submitProduct(); }).catch(function (err) { console.log(err); });
|