【uniapp】微信小程序端自定义组件 v-model 不生效问题及解决

2,885 阅读1分钟

问题原因:小程序端自定义组件的 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 更语义化些。不管了,反正核心问题解决了,这个小问题各位就自行选择吧。