taro
taro copied to clipboard
picker-view 组件循环渲染时会生成多余的空节点
相关平台
支付宝小程序
复现仓库
https://github.com/eiinu/taro-picker-view.git 小程序基础库: 2.8.8 使用框架: Vue 3
复现步骤
<template>
<view style="height: 300px;">
<picker-view :value="value" @change="onChange">
<picker-view-column v-for="(column, index) in columns">
<view v-for="(item, index) in column.list" :key="index">{{ item.name }}</view>
</picker-view-column>
</picker-view>
</view>
</template>
<script>
export default {
name: "Index",
data() {
return {
columns: [
{
list: [
{ name: '选项一' },
{ name: '选项二' },
{ name: '选项三' },
],
}
],
value: [1],
}
},
methods: {
onChange: function(e) {
console.log('onChange', e.detail.value)
this.value = e.detail.value
}
}
}
</script>
期望结果
只渲染列表中的内容
实际结果
前后多出一个 picker-view-column,导致 onChange 事件的参数数组长度不匹配。
每一列中前后多出一个空 view 节点,导致显示错误、index 与预期不匹配。
环境信息
👽 Taro v3.6.8
Taro CLI 3.6.8 environment info:
System:
OS: macOS 12.5.1
Shell: 5.8.1 - /bin/zsh
Binaries:
Node: 16.15.1 - ~/.nvm/versions/node/v16.15.1/bin/node
Yarn: 1.22.19 - /usr/local/bin/yarn
npm: 8.11.0 - ~/.nvm/versions/node/v16.15.1/bin/npm
npmPackages:
@tarojs/cli: 3.6.8 => 3.6.8
@tarojs/components: 3.6.8 => 3.6.8
@tarojs/helper: 3.6.8 => 3.6.8
@tarojs/plugin-framework-vue3: 3.6.8 => 3.6.8
@tarojs/plugin-html: 3.6.8 => 3.6.8
@tarojs/plugin-platform-alipay: 3.6.8 => 3.6.8
@tarojs/plugin-platform-h5: 3.6.8 => 3.6.8
@tarojs/plugin-platform-jd: 3.6.8 => 3.6.8
@tarojs/plugin-platform-qq: 3.6.8 => 3.6.8
@tarojs/plugin-platform-swan: 3.6.8 => 3.6.8
@tarojs/plugin-platform-tt: 3.6.8 => 3.6.8
@tarojs/plugin-platform-weapp: 3.6.8 => 3.6.8
@tarojs/runtime: 3.6.8 => 3.6.8
@tarojs/shared: 3.6.8 => 3.6.8
@tarojs/taro: 3.6.8 => 3.6.8
@tarojs/taro-loader: 3.6.8 => 3.6.8
@tarojs/webpack5-runner: 3.6.8 => 3.6.8
babel-preset-taro: 3.6.8 => 3.6.8
eslint-config-taro: 3.6.8 => 3.6.8
npmGlobalPackages:
typescript: 4.7.4
用 官方提供的 demo 就可以复现这个问题, 版本 3.6.17 环境 支付宝小程序
代码
<template>
<view class="taro-example">
<view>{{ year }}年{{ month }}月{{ day }}日</view>
<picker-view
indicator-style="height: 30px;"
style="width: 100%; height: 300px"
:value="value"
@change="onChange"
>
<picker-view-column>
<view v-for="(item, index) in years" :key="index">{{ item }}年</view>
</picker-view-column>
<picker-view-column>
<view v-for="(item, index) in months" :key="index">{{ item }}月</view>
</picker-view-column>
<picker-view-column>
<view v-for="(item, index) in days" :key="index">{{ item }}日</view>
</picker-view-column>
</picker-view>
</view>
</template>
<script>
export default {
name: 'PickerDemo',
data() {
const date = new Date()
const years = []
const months = []
const days = []
for (let i = 1990; i <= date.getFullYear(); i++) {
years.push(i)
}
for (let i = 1; i <= 12; i++) {
months.push(i)
}
for (let i = 1; i <= 31; i++) {
days.push(i)
}
return {
years: years,
year: date.getFullYear(),
months: months,
month: 2,
days: days,
day: 2,
value: [3, 1, 1]
}
},
methods: {
onChange: function (e) {
const val = e.detail.value
console.log(val)
this.year = this.years[val[0]]
this.month = this.months[val[1]]
this.day = this.days[val[2]]
}
}
}
</script>
使用 picker-column-column
配合 v-for
也存在多余渲染的问题
现在想了解一下这类问题,进展如何
这个什么时候解决啊~
另外支付宝,微信小程序带插槽组件渲染时也会出现这个问题
@Chen-jj 空文本节点删除问题,在hydrate中移除可能导致cn路径变化。那么,是否可以考虑修改PlainText模板,添加类似wx:if指令来删除空文本。比如:
另外,支付宝这边需要单独修改pickerView, pickerColumnView的模板(看源码不清楚为什么和微信的不一样,单独设置了模板)
原因是,for 循环会以 Fragment 作为父节点,这里会生成 2 个文字节点: https://github.com/vuejs/core/blob/main/packages/runtime-core/src/renderer.ts#L1059-L1060
web 中空字符串节点没有影响,可以在这里把空字符串的节点过滤掉吗? https://github.com/NervJS/taro/blob/main/packages/taro-runtime/src/hydrate.ts#L83 @Chen-jj
@Chen-jj 空文本节点删除问题,在hydrate中移除可能导致cn路径变化。那么,是否可以考虑修改PlainText模板,添加类似wx:if指令来删除空文本。比如:
另外,支付宝这边需要单独修改pickerView, pickerColumnView的模板(看源码不清楚为什么和微信的不一样,单独设置了模板)
@we125182 感谢建议~这种方法我们验证下。
支付宝单独处理的原因是 PickerView
后面一定要紧跟 PickerViewColumn
,而不能跟 Block
要怎么搞啊 太难了
另外支付宝,微信小程序带插槽组件渲染时也会出现这个问题
![]()
现在有什么办法手动修复此问题吗,skyline下布局出大问题
这个问题不打算修复吗