const mutations = {
"SET_id_CARD": (state, payload) => {
console.log(payload,'=> 身份证正面payload')
state.idCard = payload.idCard;
},
}
export default mutations
背景:
混合开发APP,使用了第三方SDK中暴露的方法,在业务中有上传图片和OCR识别的需求,所以需要用到暴露的方法调用相机或者相册,然后再通过返回的ID获取图片URL,并进行对应的OCR识别;
在这里,为了方便,所以使用了vuex中的store存储,具体原理就不讲了,直接进行步骤
首先需要创建store文件夹,如果没有vuex,需要根据自己的版本先安装:
Vue2项目安装:
npm install vuex@3
Vue3项目安装:
npm install vuex@4
我是先创建了modules块后发现自己不需要用到模块化,所以如果你的业务需求也比较简单,可以不要modules,直接创建modules以下的文件就可以了。
actions.js:
// 身份证正面
const setIdCard= ({ commit }, payload) => {
commit('SET_id_CARD', payload);
};
export default {
setIdCard
}
getters.js:
const getters = {
idCard: state => state.idCard
}
export default getters
index.js
import Vue from 'vue'
import Vuex from 'vuex'
import user from './modules/user'
import mutations from './mutations'
import state from './state'
import actions from './actions'
import getters from './getters'
Vue.use(Vuex)
const store = new Vuex.Store({
modules: {
user
},
getters,
state,
actions,
mutations
})
export default store
mutations.js
const mutations = {
"SET_id_CARD": (state, payload) => {
state.idCard = payload.idCard;
}
}
export default mutations
status.js
//在这里因为我是直接使用van-uploader组件,为了方便直接使用了数组的形式
const state = {
idCard: [], //身份证正面
}
export default state
在所需要的组件中:
<template>
<van-uploader v-model="$store.state.idCard" :max-count="1" multiple :after-read="(file) => afterRead(file,'0')"
@delete="(file) => beforeDelete(file,'0')" class="uploaderBox"
@click-upload="addImage('idCard')"
>
//这里使用@click-upload事件是因为,在移动端afterread是没有用的,无法唤起相机或者相册(之前试过Input标签也无法调起,所以只能使用第三方暴露的方法调起手机设备)
<div class="infoUp">点击上传</div>
<div>身份证正面</div>
</van-uploader>
</template>
<script>
import {mapGetters, mapMutations} from "vuex";
data(){
return {
idCardPics: '', //因为提交的时候是以字符串的形式,所以还需声明一个字段来承接store中的URL
}
}
computed: {
// 接收数据(这里的'currentType'和'uploadIds'是我的业务中需要区分标识的字段,所以我在代码中就不加了,demo主要是为了给大家做参考用的)
...mapGetters(['currentType','uploadIds','idCard']),
//这步是为了进行OCR的,配合watch进行监控url的变化,
"getPics"() {
let orcUrl = '';
if(this.$store.state.currentType) {
switch (this.$store.state.currentType) {
case "idCard":
orcUrl = this.$store.state.idCard.length ? this.$store.state.idCard[0].url : '';
this.idCardPics = orcUrl;
break;
}
}
return orcUrl
}
watch:{
getPics(newValue,oldValue) {
if(newValue) {
let data = {};
data.url = newValue; //如果有变化,那就赋值
if(this.$store.state.currentType) {
switch (this.$store.state.currentType) {
case "idCard":
data.side = 'front';
this.OCRidCard(data,'front') //这里是我处理OCR的事件,大家可以更换其他的事件
break;
}
}
}
}
},
methods: {
// 修改数据
...mapMutations(['SET_CURRENT_TYPE','SET_UPLOAD_IDS','SET_id_CARD']),
//OCR识别
OCRidCard(data){
}
//删除图片
beforeDelete(file,index) {
switch (index) {
case '0':
this.SET_id_CARD({
idCard: []
})
this.idCardPics = '';
break;
}
}
}
//因为其他地方也可能用到,所以在组件销毁时,我会把store值初始化
destroyed() {
this.SET_CURRENT_TYPE({
currentType: ''
});
this.SET_UPLOAD_IDS({
uploadIds: ''
});
this.SET_id_CARD({
idCard: []
});
}
</script>
注意:刚开始我想省劲,声明一个字段,给好多场景使用,但是最后发现还是这样最好使,你只需要注意声明的字段不要和组件data中的字段一样就可以了。就类似这样的样子(样式我就不传了,根据自己的业务风格去调整就行)
虽然还是有一些不太懂的地方,但是简单的业务基本上都实现了,而且也进行了测试没有问题(因为我的比较奇葩,需要在main.js里访问接口获取图片,所以那些你们用不到的地方我就不展示了)