问题原因:小程序端自定义组件的 v-model 的 prop 和 event 字段必须使用默认的名称,即 value 和 input。
事件背景
最近在项目中封装了一个图片上传的组件,项目需要编译到微信小程序和 APP 两端。自定义组件用到了 v-model 对已上传图片进行双向绑定。开发主要在 APP 端调试,功能一切 ok,但当测试在小程序端测试时发现功能无法正常使用。
组件代码如下:
export default {
model: {
prop: 'imageList',
event: 'change'
},
props: {
imageList: {
type: Array,
default: () => []
}
},
}
imageList 用来存储上传的图片集合。当上传的图片发生变化时,通过 emit('change', imageList) 方式将事件广播出去。
代码怎么看都没有毛病,但在小程序端就是无法双向绑定。经过一番搜索之后,发现是 uniapp 的一个坑点:微信小程序中自定义组件不支持 model 选项 #1274
链接里说 prop 和 event 都得是默认。但亲测 event 可以是其他名称,这里我就使用的 change。所以解决问题的关键在于prop 必须为 value, event 则可以为任意名称。
解决方案
- 自定义组件
ImageUploader
export default {
model: {
prop: 'value
event: 'change'
},
props: {
value
type: Array,
default: () => []
}
},
}
- 引用组件
<template>
<!--#ifdef MP-WEIXIN-->
<ImageUploader :value="photos" @change="onImageChange"></ImageUploader>
<!--#endif-->
<!--#ifndef MP-WEIXIN-->
<ImageUploader v-model="photos"></ImageUploader>
<!--#endif-->
</template>
<script>
import ImageUploader from '@/components/image-uploader/ImageUploader.vue'
export default {
components: {
ImageUploader
}
}
</script>
文章写到这里我才发现,如果事件名称定义为 input template 上或许就不需要再进行条件判断。但我还是觉得图片上传组件吗,上传列表发生改变用 change 更语义化些。不管了,反正核心问题解决了,这个小问题各位就自行选择吧。