关于在vue3中的动态组件component标签上给ref属性动态赋值的问题

        前言:此问题困扰我已久,每次都是本地运行没问题,但发布到线上之后就获取不到动态组件的ref对象。

        之前的错误写法,本人前端经验不足,拿着老旧的思维逻辑拼凑,这种情况下在本地运行环境是可以实现点击下一步进行切换的,但打包压缩发布到线上之后,就失效了

<keep-alive>
      <component :is="activeValue" :ref="stepList[activeId].refName"  />
</keep-alive>    


 <el-button @click="handleCreatNext()" type="primary">下一步</el-button>

const Component1Ref = ref()
const Component2Ref = ref()

const stepList = ref([
  {
    id: 0,
    label: '子组件1',
    value: shallowRef(Component1),
    refName: 'Component1Ref'
  },
  {
    id: 1,
    label: '子组件2',
    value: shallowRef(Component2),
    refName: 'Component2Ref'
  }])

const handleCreatNext = async () => {
if (activeId.value == 0) {
    //处理步骤1的逻辑
    await Component1Ref.value.formRef.validate()
} else if (activeId.value == 1) {
    // 处理步骤2的逻辑
}
    if (activeId.value++ > 3) activeId.value = 0
  activeValue.value = stepList.value[activeId.value].value
}

正确做法请参考:

<keep-alive>
      <component :is="activeValue" :ref="(el) => currentComponent = el"  />
</keep-alive>    


 <el-button @click="handleCreatNext()" type="primary">下一步</el-button>

const currentComponent = ref(Component1);

const stepList = ref([
  {
    id: 0,
    label: '子组件1',
    value: shallowRef(Component1),
    refName: 'Component1Ref'
  },
  {
    id: 1,
    label: '子组件2',
    value: shallowRef(Component2),
    refName: 'Component2Ref'
  }])

const handleCreatNext = async () => {
 await nextTick();
if (activeId.value == 0) {
    //处理步骤1的逻辑
    await currentComponent.value.formRef.validate()
} else if (activeId.value == 1) {
    // 处理步骤2的逻辑
}
    if (activeId.value++ > 3) activeId.value = 0
  activeValue.value = stepList.value[activeId.value].value
}

### Vue3 中父组件传对象到子组件赋值失败的解决方案 在 Vue3 中,父组件向子组件传递对象时可能会遇到赋值失败的情况。这通常是因为数据尚未准备好或者未遵循 Vue 的响应式机制所致。以下是几种可能的原因以及对应的解决方案: #### 1. **确保父组件中的数据已初始化** 如果父组件的数据是在生命周期后期动态加载的(例如通过 API 请求),那么子组件接收到的初始 `props` 可能会是空值或默认值。可以通过以下方式解决此问题。 - 使用 `v-if` 控制子组件的渲染时机[^3]: ```vue <!-- 父组件 --> <template> <child-component v-if="parentObject" :data-object="parentObject"></child-component> </template> <script setup> import { ref } from &#39;vue&#39;; import ChildComponent from &#39;./ChildComponent.vue&#39;; const parentObject = ref(null); // 假设这是异步请求的结果 setTimeout(() => { parentObject.value = { key: &#39;value&#39; }; }, 1000); </script> ``` - 这样可以确保只有当 `parentObject` 不为空时才渲染子组件。 --- #### 2. **使用计算属性检测数据有效性** 在子组件中,可以通过计算属性来判断父组件传递的对象是否有效并控制显示逻辑[^4]。 ```vue <!-- 子组件 --> <template> <div v-if="isValidData">{{ displayData }}</div> </template> <script setup> import { computed, toRefs } from &#39;vue&#39;; const props = defineProps({ dataObject: { type: Object, required: true, }, }); // 计算属性用于验证数据的有效性 const { dataObject } = toRefs(props); const isValidData = computed(() => !!dataObject.value && Object.keys(dataObject.value).length > 0); const displayData = computed(() => isValidData ? JSON.stringify(dataObject.value) : &#39;&#39;); </script> ``` --- #### 3. **利用 `watch` 监听 `props` 更新** 对于异步场景下的父组件传值,可以在子组件中使用 `watch` 来监听 `props` 的变化,并及时更新内部状态[^5]。 ```vue <!-- 子组件 --> <script setup> import { watch, ref } from &#39;vue&#39;; const props = defineProps({ dataObject: { type: Object, default: () => ({}), }, }); const localState = ref({ ...props.dataObject }); watch( () => props.dataObject, (newVal) => { if (newVal) { localState.value = { ...newVal }; // 深拷贝防止直接修改原始对象 } }, { deep: true } ); </script> ``` --- #### 4. **检查父子组件之间的通信模式** Vue3 遵循单向数据流的原则,因此父组件传递给子组件的对象应视为只读。如果需要修改该对象,则应在子组件中创建其副本[^2]。 ```javascript // 子组件中深拷贝父组件传递的对象 const formDataCopy = reactive(JSON.parse(JSON.stringify(props.formData))); ``` 这样可以避免因直接修改 `props` 导致的潜在错误。 --- #### 5. **调试工具排查问题** 如果以上方法均无法解决问题,建议借助浏览器开发者工具查看实际传递的数据是否存在异常。具体操作包括但不限于: - 检查父组件中绑定的数据是否有误; - 查看子组件接收的 `props` 是否被正确解析。 --- ### 总结 综合来看,在 Vue3 中解决父组件传递对象至子组件赋值失败的问题可以从以下几个方面入手:延迟渲染子组件、监控 `props` 数据变更、合理运用计算属性以及严格遵守单向数据流的设计理念。每种方案都有适用范围,请根据实际情况灵活选用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值