uni-app vue3 + 支付宝小程序插槽数据变更后视图更新期间内部组件props数据错误,微信小程序/h5平台正常

发布于 1周前 作者 vueper 来自 Uni-App

uni-app vue3 + 支付宝小程序插槽数据变更后视图更新期间内部组件props数据错误,微信小程序/h5平台正常

产品分类:

uniapp/小程序

PC开发环境操作系统:

Mac

PC开发环境操作系统版本号:

macos 14.5

第三方开发者工具版本号:

最新

基础库版本号:

最新

项目创建方式:

CLI

CLI版本号:

3.0.0-4020920240930001

开发环境 版本号 项目创建方式
Mac macOS 14.5 CLI

示例代码:

{
  layout: 'default',
  style: {
    navigationBarTitleText: '测试',
  },
}
<template>
  <QueryList :list-data="mockListData">
    <template #default="{ listData }">
      <wd-checkbox-group :modelValue="curValue" @change="onChange" cell shape="square">
        <wd-checkbox
          v-for="option in listData"
          :modelValue="option.value"
          :key="option.value"
          shape="square"
        >
          <view>{{ option.label }} {{ option.value }}</view>
        </wd-checkbox>
      </wd-checkbox-group>
    </template>
  </QueryList>
</template>

<script lang="ts" setup>
import QueryList from './components/queryList.vue'

const curValue = ref([])
const onChange = ({ value }) => {
  console.log('onChange value', value)
  curValue.value = value
}
const mockListData = ref([
  { label: '测试1', value: 1 },
  { label: '测试2', value: 2 },
  { label: '测试3', value: 3 },
  { label: '测试4', value: 4 },
])
</script>

<style lang="scss" scoped>
//
</style>

querylist.vue

<template>
  <view>
    <slot :listData="listData"></slot>
  </view>
</template>

<script lang="ts" setup>
defineProps({
  listData: {
    type: Array,
    default: () => [],
  },
})
</script>

<style lang="scss" scoped>
//
</style>

操作步骤:

  1. 下载demo项目,然后pnpm i && pnpm dev:mp-alipay
  2. 支付宝开发工具打开dist/dev/mp-alipay。任意勾选checkbox,控制台会有warning。

预期结果:

每次render拿到的props数据都正常

实际结果:

第一次render拿到的props数据正常,第二次为undefined

bug描述:

项目背景:vue3(3.0.0-4030620241128001) + wot-design-ui。demo附件已上传。

通过组件暴露的default插槽,props.modelValue第一次拿到的数据正常,点击勾选后,wd-checkbox的props.modelValue异常,拿到unfined,导致了后续的勾选交互异常。插槽内的变量模板是正常渲染的。


1 回复

uni-app 中使用 Vue 3 开发支付宝小程序时,遇到插槽数据变更后视图更新期间内部组件 props 数据错误的问题,这通常与 Vue 的响应式系统和支付宝小程序的视图更新机制有关。以下是一个可能的代码示例和解决方案,帮助你排查和解决这个问题。

示例代码

假设我们有一个父组件 Parent.vue 和一个子组件 Child.vue。父组件通过插槽传递数据给子组件。

Parent.vue

<template>
  <view>
    <button @click="updateData">Update Data</button>
    <slot-scope name="default" :data="slotData">
      <template #default="{ data }">
        <Child :data="data" />
      </template>
    </slot-scope>
  </view>
</template>

<script setup>
import { ref } from 'vue';
import Child from './Child.vue';

const slotData = ref({ text: 'Initial Text' });

function updateData() {
  slotData.value = { text: 'Updated Text' };
}
</script>

Child.vue

<template>
  <view>{{ data.text }}</view>
</template>

<script setup>
import { defineProps } from 'vue';

const props = defineProps({
  data: {
    type: Object,
    required: true
  }
});
</script>

问题分析

在支付宝小程序中,由于视图更新机制的不同,可能导致插槽内容在数据变更后未能及时响应。这通常与 Vue 的响应式系统和支付宝小程序的原生渲染机制之间的兼容性问题有关。

解决方案

  1. 确保数据响应性: 确保 slotData 是一个响应式引用,如上例所示使用 ref

  2. 使用 watch 监听数据变化: 在父组件中使用 watch 监听 slotData 的变化,并在变化时强制重新渲染插槽内容。

    <script setup>
    import { ref, watch, nextTick } from 'vue';
    import Child from './Child.vue';
    
    const slotData = ref({ text: 'Initial Text' });
    
    function updateData() {
      slotData.value = { text: 'Updated Text' };
    }
    
    watch(() => slotData.value, (newVal) => {
      nextTick(() => {
        // 强制更新插槽内容(如果需要)
      });
    });
    </script>
    
  3. 检查支付宝小程序平台特有的问题: 查阅 uni-app 和支付宝小程序的官方文档,了解是否有关于插槽和数据响应性的特定说明或已知问题。

  4. 简化插槽使用: 如果可能,尝试简化插槽的使用,避免复杂的嵌套和动态数据传递,以减少潜在的兼容性问题。

通过以上步骤,你可以更准确地定位和解决支付宝小程序中插槽数据变更后视图更新期间内部组件 props 数据错误的问题。

回到顶部