美文网首页
mpvue开发微信小程序踩过的坑

mpvue开发微信小程序踩过的坑

作者: 扶搏森 | 来源:发表于2018-05-11 19:39 被阅读0次

    最近公司需要研发微信小程序,中间踩了一些坑记录下来。

    利用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.getMoviesthis.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

    alt 微信小程序二维码

    相关文章

      网友评论

          本文标题:mpvue开发微信小程序踩过的坑

          本文链接:https://www.haomeiwen.com/subject/kbrqdftx.html