mpvue 问题汇总(持续更新)

1,016 阅读1分钟

先列举出来 慢慢填

钩子函数不运行

上来做前后端通信测试,就遇到一个奇怪的问题,钩子函数不运行了。

我也不知道具体是为什么,我觉得可能的原因是删除了东西之后dist是不会直接重新编译的。

我把dist文件夹删掉重新编译问题就解决了

Vuex使用

juejin.cn/post/684490…

Setting data field "$root.0.registered" to undefined is invalid.

因为我用了这么一段去读取storage,必须做一个判断,是undefined不能赋值。

另外state的赋值不能在回调中做,需要用一个闭包把data拿出来用。

initStates(states) {
    for (var key in states) {
        var data
        mpvue.getStorage({
            key,
            success(res)  {
                data = res.data
            }
        })
        if (data) {
            states[key] = data           
        }
    }
},

EventBus

事件总线建议不要用来做通信,mpvue的一个核心优势就是适配vuex,通信用vuex是最好的即使你只是一个小项目,vuex的使用成本本身很低。

那么什么情况下需要用到事件总线呢?


需求场景

我不希望登录逻辑只做在第一个页面渲染的时候,在所有需要登录的情况都能检查一遍登录。

思路

使用一个vue实例作为事件总线,监听loginRequired事件,执行登录逻辑。这里的登录逻辑是异步函数,因为小程序的接口是异步的。

触发事件的实例阻塞后续逻辑,持续监听loginState状态判断登录是否完成。


可以看到事件总线可以作为一个全局使用方法的封装,搭配Vuex可以很好地执行一些异步的功能。

实现

这里实现单独拿出来说,因为mpvue的机制和Vue不一样。

下面是我实现登录逻辑使用的eventbus

import Vue from 'vue'
import { login } from './utils/index' // 封装的一个异步登录函数

var bus = new Vue({
    methods: {
        login: async function () {
            var state = this.$store.state
            
            if (state.global.loginState <= 0) {
                this.$store.commit('changeLoginState', 1)
                await login.call(this)
            } else {
                return
            }
        },
    }
})

bus.$on('loginRequired', () => {
    console.log('on event loginRequired');
    this.a.login()
})

export default bus

讲一下细节

$on不能写在mounted里面

这里涉及到一个重要的点,mpvue中每个页面是一个独立的vue实例

我没有看mpvue的源码,反正这个mounted是不执行的,我测试了一下,APP.vue的mounted也是不执行的.

文档上没有注意到对这个的说法, 如果我眼瞎还请指正.

斗胆猜测一下,mpvue改了runtime,所以new Vue()的时候把init的一系列方法执行了,看到有文章说在打开小程序的时候所有页面的created钩子都执行了,而beforMountedmounted钩子都是在onReady之后执行的,可以得出一定要访问页面才会执行mounted

this并不指向实例

注意到调用method的时候使用的是this.a.login()。这个是mpvue预编译的造成的,具体的可以看一下预编译后的main.js。

computed不可用

这个问题还没有解决,我先暂时把要计算的内容直接放到v-if里面了。知道问题的铁汁们留个言哈

data里面有几个标志变量,需要根据多个标志计算内容是否显示,直接把关键的源码给出来。

...
    <div class="cu-btn bg-green lg" 
         v-if="idAvailable && !checking && confirming"
         @click="setContact"
    >
         确认关联
    </div>
    <div class="cu-btn bg-green lg" 
         v-if="idAvailable && !checking && !confirming"
    >
         确认成功
    </div>
...
computed {
     confirmed: () => this.idAvailable && !this.checking && !this.confirming
}

data () {
        return {
            from_id: undefined,
            idAvailable: false,
            checking: true, // 正在查询
            confirming: true, // 已经确认
        }
    },
...

写了计算属性之后会报错,而且是两次

Setting data field "$root.0.confirmed" to undefined is invalid.

问题的原因还不太清楚,我一会空了去提个issue,解决的话会更新的。