Vue自定义组件传递Array数据报Missing required prop错误如何解决
问题原因
报错来自两个核心问题:
defineCustomElement生成的是原生Web Components自定义元素,传参规则和普通Vue组件不一致:HTML原生属性(attribute)仅支持字符串类型,且非Vue模板环境下根本不识别v-bind(即:前缀)的绑定语法。你写的:students="..."会被浏览器当成名字带冒号的普通字符串属性,组件无法识别到名为students的prop,自然会触发必填校验报错。- 组件模板本身有语法错误:
- 末尾多了一个无对应开标签的
</div> ul标签上写的:classes="classes"是错误写法,原生DOM类名属性为class,不存在classes属性,类名不会生效。
- 末尾多了一个无对应开标签的
解决方法
根据你使用自定义元素的场景选择对应方案即可:
场景1:纯原生HTML页面(无外层Vue实例)使用
原生HTML不支持Vue模板语法,不能直接用:绑定数组,两种可选实现:
方式1:通过DOM属性直接赋值
标签上不用传students,等元素加载完成后直接通过JS给DOM属性赋值:
<students-list classes="col-sm-12"></students-list> <script> const studentList = document.querySelector('students-list') studentList.students = [{name: 'John'},{name: 'Sarah'},{name: 'Dave'}] </script>
方式2:配置prop自动解析JSON字符串
如果不想额外写JS赋值,可以在定义组件时给students prop加转换逻辑,自动把传入的JSON字符串转成数组:
customElements.define('students-list', defineCustomElement({ // 修正模板错误 template: `<ul :class="classes"> <li v-for="st in students" :key="st.name"> {{ st.name }} </li> </ul>`, props: { classes: { type: String, required: true, }, students: { type: Array, required: true, // 声明从同名HTML attribute读取值 attribute: 'students', // 校验值合法性,兼容数组、JSON字符串两种传入格式 validator(val) { if (typeof val === 'string') { try { return Array.isArray(JSON.parse(val)) } catch { return false } } return Array.isArray(val) }, // 统一把值转成数组类型 coerce(val) { if (typeof val === 'string') { return JSON.parse(val) } return val } } }, data() { return {} } }));
配置完成后就可以直接在HTML标签上写JSON字符串传值,注意属性值用单引号包裹,内部JSON用双引号:
<students-list classes="col-sm-12" students='[{"name": "John"},{"name": "Sarah"},{"name": "Dave"}]' ></students-list>
场景2:在其他Vue组件的模板中使用
首先需要在Vue编译器配置里把students-list标记为自定义元素(避免Vue把它当普通Vue组件解析),传非字符串类型的prop时加.prop修饰符,强制把值绑定到DOM属性上,而非设置成字符串类型的HTML attribute:
<template> <students-list classes="col-sm-12" :students.prop="[{name: 'John'},{name: 'Sarah'},{name: 'Dave'}]" ></students-list> </template>
如果是Vite项目,在vite.config.js里给@vitejs/plugin-vue添加配置即可识别自定义元素:
// vite.config.js import vue from '@vitejs/plugin-vue' export default { plugins: [ vue({ template: { compilerOptions: { isCustomElement: (tag) => tag === 'students-list' } } }) ] }
内容的提问来源于stack exchange,提问作者shaaraa
相关产品推荐
相关产品推荐

