Shopware 6:sw-inherit-wrapper的currentValue选择后不更新问题
我定义了自定义实体enterprise,关联至product.extensions.myPlugin.enterpriseId。通过sw-inherit-wrapper包裹sw-entity-single-select选择enterprise的代码如下:
<sw-inherit-wrapper v-model="product.extensions.myPlugin.enterpriseId" :has-parent="false" :inherited-value="null"> <template #content="{currentValue, updateCurrentValue, isInherited}"> <sw-entity-single-select class="enterprise-name" :key="isInherited" :value="currentValue" entity="enterprise" :placeholder="$tc('inputEnterprise.placeholder')" show-clearable-button allow-entity-creation :entity-creation-label="$tc('inputEnterprise.labelCreation')" @change="updateCurrentValue"></sw-entity-single-select> </template> </sw-inherit-wrapper>
该模板属于一个模态框,出现的问题是:从列表选择enterprise时,<sw-entity-single-select__selection-text>未更新;但关闭并重新打开父模态框后,enterprise已设置并正常显示,说明实体扩展已更新,但sw-entity-single-select的currentValue未同步。
补充:扩展在重写的sw-product-detail组件中设置,代码如下:
// sw-product-detail/index.js ... Component.override('sw-product-detail', { ... computed: { myPluginRepository() { return this.repositoryFactory.create('my_plugin'); }, }, watch: { product() { if(this.product.id) { this.__setMyPluginExtension() } } }, methods: { ... __setMyPluginExtension() { let extension = this.product.extensions.myPlugin ?? null; if(null === extension) { extension = this.myPluginRepository.create(Shopware.Context.api); extension.enterpriseId = null } this.product.extensions.myPlugin = extension; }, } }
重写的子组件sw-product-detail-base加载了该模态框,组件渲染时扩展已存在,默认值能正常显示,但选择时的同步问题仍存在。
分析与解决
1. 核心问题:change事件传递的是实体对象而非ID
sw-entity-single-select的change事件默认返回选中的实体对象,但你绑定的v-model是enterpriseId(字符串类型的ID),直接把对象传给updateCurrentValue会导致赋值不匹配,进而currentValue无法同步。
修改@change事件,提取实体的ID传递:
@change="(selectedEntity) => updateCurrentValue(selectedEntity?.id)"
2. 确保嵌套属性的响应式
Vue无法自动追踪后续添加的嵌套属性的变化,你直接给product.extensions.myPlugin赋值的方式可能导致enterpriseId的变化无法被响应式监听。
修改__setMyPluginExtension方法,用this.$set确保扩展属性的响应式:
__setMyPluginExtension() { let extension = this.product.extensions.myPlugin; if (!extension) { extension = this.myPluginRepository.create(Shopware.Context.api); extension.enterpriseId = null; // 用$set确保extensions对象新增的myPlugin属性被响应式追踪 this.$set(this.product.extensions, 'myPlugin', extension); } }
3. 调整组件的key值触发重新渲染
当前sw-entity-single-select的key绑定的是isInherited,而你设置了:has-parent="false",isInherited始终为false,导致值变化时组件不会重新渲染。
把key绑定为currentValue,确保值变化时组件重新渲染:
:key="currentValue"
4. 可选:用计算属性简化嵌套属性绑定
如果嵌套层级过深导致响应式问题,可在模态框组件中定义计算属性,简化v-model的绑定:
computed: { enterpriseId: { get() { return this.product.extensions.myPlugin?.enterpriseId || null; }, set(newId) { // 确保enterpriseId的变化被响应式追踪 this.$set(this.product.extensions.myPlugin, 'enterpriseId', newId); } } }
然后修改sw-inherit-wrapper的v-model:
<sw-inherit-wrapper v-model="enterpriseId" :has-parent="false" :inherited-value="null">
内容的提问来源于stack exchange,提问作者rammi22

