最近公司需要研发微信小程序,中间踩了一些坑记录下来。
利用axios发送交易
import axios from '../../node_modules/axios/dist/axios'
axios.defaults.adapter = function(config) {
let baseURL;
if (process.env.METHOD === 'proxy1') {
baseURL = 'http://localhost:3001/getMovie' // 本地代理1(100次/小时)
} else if (process.env.METHOD === 'proxy2') {
baseURL = 'http://localhost:3002' // 本地代理2(100次/小时)
} else if (process.env.METHOD === 'nginx') {
baseURL = 'https://www.daxierhao.com/v2/movie' // nginx 代理(100次/小时)
}
console.log('baseURL',baseURL)
//发交易之前显示加载中
wx.showLoading({ title: '拼命加载中...' })
//发交易调用(开发放开注释)
return new Promise((resolve, reject) => {
console.log(config);
wx.request({
...config,
url: baseURL + config.url,
data: config.params,
success: res => {
console.log(res)
if (res.statusCode < 200 || res.statusCode > 300) {
return reject(res.data || {});
}
return resolve(res.data || {});
},
complete: res => {
wx.hideLoading()
// TODO:
}
});
})
}
export default axios
直接使用axios报错,因为微信小程序必须走wx.request发送交易。
vuex状态管理添加
store.js
import { getBoardData } from '@/utils/api'
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
page: 1,
hasMore: true,
movies: [],
type: ''
},
mutations: {
listClearState: (state) => {
console.log('listClearState')
state.page = 1
state.hasMore = true
state.movies = []
},
listMovieList: (state, { data, type }) => {
state.type = type
console.log(data);
if (data.subjects.length) {
state.movies.push.apply(state.movies, data.subjects)
// state.movies=state.movies.concat(data.subjects)
console.log('movies concat end',state.movies.length)
//测试到底用的,10是后台返回的数据,判断是否还有下一页
if(state.movies.length>10){
state.hasMore = false
}
}
}
},
actions: {
async getMovies({ state, commit }, { type, search }) {
console.log('actions')
if (!state.hasMore) return
let data = await getBoardData({ board: type, page: state.page++, search })
commit('listMovieList', { data, type })
}
}
})
export default store
对应页面 调用action方法
import store from './store'
import { mapState, mapActions, mapMutations } from 'vuex'
export default {
computed: {
...mapState(['movies', 'hasMore', 'type'])
},
methods: {
...mapActions(['getMovies']),
...mapMutations({
clearState: 'listClearState'
}),
async getShowList () {
await this.getMovies({})
}
},
store
}
利用mapState,mapActions,mapMutations进行数据的解构,将store里面的state值和action、mutation上面的方法解构出来。可以直接写this.page
获取到用到state上的值,而不用store.state.page
先获取到store上的值,然后赋值给this上的变量,页面视图进行取值。同理
...mapActions(['getMovies']),
...mapMutations({
clearState: 'listClearState'
})
可以直接使用this.getMovies
和this.clearState
使用store上的方法。action中可以进行异步操作,mutation中不能有异步操作
页面进行dispatch一个action,actions中commit一个mutation进行数据更新。
组件
父组件
<movie-list :movies="movies" :has-more="hasMore"></movie-list>
:movies
是通过props传递到子组件,:
是v-bind:
的缩写,进行动态绑定
子组件
<template>
<div class="weui-panel weui-panel_access page__tpd" v-for="movie in movies" :key="movie.title">
<div class="weui-panel__bd">
<navigator url="" class="weui-media-box weui-media-box_appmsg" hover-class="weui-cell_active">
<div class="weui-media-box__hd weui-media-box__hd_in-appmsg">
<image class="weui-media-box__thumb" :src="icon60" />
</div>
<div class="weui-media-box__bd weui-media-box__bd_in-appmsg">
<div class="weui-media-box__title">{{movie.title}}</div>
<div class="weui-media-box__desc">{{movie.original_title}}</div>
</div>
</navigator>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
icon20: base64.icon20,
icon60: base64.icon60
}
},
props: {
movies: {
type: Array,
default () {
return []
}
},
hasMore: {
type: Boolean,
default: true
},
type: String
},
mounted(){
console.log(this.movies)
}
}
</script>
上拉加载更多
async onPullDownRefresh() { // 下拉刷新
console.log('下拉刷新')
this.clearState()
await this.getShowList()
wx.stopPullDownRefresh()
},
onReachBottom() { // 上拉加载
console.log('上拉加载')
this.getShowList()
},
onUnload() { // 清空状态
console.log('清空状态')
this.clearState()
}
onPullDownRefresh微信的生命周期函数中上拉触发,onReachBottom微信的生命周期函数中下拉触发。
下拉刷新还需要设置配置
对应的main.js开启下拉刷新
export default {
config: {
enablePullDownRefresh: true
}
}
本地开发转发后台
由于本地开发,前后端分离,需要转发后台接口
在/build/webpack.dev.conf.js
中的plugins
中新加'process.env.METHOD': JSON.stringify(process.env.METHOD)
这个时候页面里面调用process.env.METHOD
就可以获取到在package.json中保存的全局变量
package.json新加命令:
"dev:proxy1": "cross-env METHOD=proxy1 npm-run-all --parallel dev proxy1",
"dev:proxy2": "cross-env METHOD=proxy2 npm-run-all --parallel dev proxy2",
"proxy1": "node kelan/app.js",
"proxy2": "node kelan/proxy.js",
在命令行执行npm run dev:proxy1
在根目录下面新建 kelan 文件夹,新建app.js文件
const Koa = require('koa')
const router = require('koa-router')()
const request = require('co-request')
const URI = 'http://127.0.0.1:3000'
router.prefix('/prefix')
router.get(['/:type', '/:type/:id'], async ctx => {
let result
try {
let url = ctx.url.replace(/\/prefix(\w*)/, URI + '$1')
console.log(':::', url, ':::')
result = await request({uri: url, method: ctx.method}) // 返回的是字符串
console.log('result', result);
} catch (error) {
throw new Error(error)
} finally {
ctx.body = JSON.parse(result.body)
}
})
const app = new Koa()
app.use(router.routes())
app.listen(3001, () => {
console.log(`Server started on 3001`)
})
用koa2进行代理转发
注意事项
在mpvue中,组件功能、vuex和vue保持一致,路由的单页面网上有大牛进行了封装,最新版mpvue1.0.10官方没给出解决方案。
- 开发调试的时候需要打debugger需要将小程序自带的调试工具中的es6转为es5功能关闭
- created和mounted在进入首页的时候其他页面的create和mounted都自动执行了一次,之后再次进入页面就不执行了。所以在初始化页面的时候就需要用onShow进行第一次进入页面进行数据重置等。
参考资料:
https://github.com/Meituan-Dianping/mpvue
https://github.com/mini-mpvue/mpvue-douban
由于是公司项目,不方便给出代码。可以参考:https://github.com/mini-mpvue/mpvue-douban
网友评论