如何向插槽内的Vuetify组件注入readonly属性实现查看模式控件只读
解决方案
问题根因
- 组件mounted触发时,插槽内的v-autocomplete已经完成props初始化和首次渲染,此时修改
componentOptions.propsData属于修改静态配置,不会触发子组件的响应式更新,因此配置不生效 - Vuetify的
v-autocomplete的readonly属性为布尔类型,你传入空字符串会被解析为false,自然无法触发只读效果
可行实现方案
方案一:作用域插槽实现(最推荐,符合Vue单向数据流规范)
不需要操作组件实例,通过作用域插槽将只读状态透出给父层,由父层绑定到对应输入组件,适配所有输入类组件,兼容性最好。
InputWrapper组件代码:
<template> <v-col :cols="cols" :class="{ 'input-wrapper': true, readonly: isReadOnly }"> <slot :readonly="isReadOnly"></slot> </v-col> </template> <script> export default { name: 'InputWrapper', computed: { isReadOnly() { return this.readonly || this.$route.params.action === 'view'; } }, props: { readonly: { type: Boolean, default: false }, cols: { type: Number, default: 12 } } }; </script>
父组件调用示例:
<InputWrapper :cols="6"> <template #default="{ readonly }"> <v-autocomplete v-model="formData.selected" :items="selectOptions" :readonly="readonly" label="选择项" /> </template> </InputWrapper>
方案二:直接修改子组件响应式props(适合不想调整现有调用代码的场景)
如果希望保持现有父组件调用方式不变,可以直接修改子组件实例的响应式$props属性,修改后会自动触发子组件更新:
<script> export default { name: 'InputWrapper', mounted() { if (this.isReadOnly && this.$slots.default?.[0]?.componentInstance) { const childInstance = this.$slots.default[0].componentInstance // 传入布尔值true,而非空字符串 this.$set(childInstance.$props, 'readonly', true) } }, computed: { isReadOnly() { return this.readonly || this.$route.params.action === 'view'; } }, props: { readonly: { type: Boolean, default: false }, cols: { type: Number, default: 12 } } }; </script>
注意:该方案依赖Vuetify组件内部props的定义方式,若后续升级Vuetify版本可能出现兼容问题,优先选择方案一。
内容的提问来源于stack exchange,提问作者domaci_a_nas
相关产品推荐
相关产品推荐

