taro icon indicating copy to clipboard operation
taro copied to clipboard

picker-view 组件循环渲染时会生成多余的空节点

Open eiinu opened this issue 1 year ago • 13 comments

相关平台

支付宝小程序

复现仓库

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 与预期不匹配。 image

环境信息

👽 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

eiinu avatar Jun 14 '23 10:06 eiinu

用 官方提供的 demo 就可以复现这个问题, 版本 3.6.17 环境 支付宝小程序

image

代码

<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>

miracletjf avatar Oct 11 '23 09:10 miracletjf

使用 picker-column-column 配合 v-for 也存在多余渲染的问题 现在想了解一下这类问题,进展如何

miracletjf avatar Oct 11 '23 09:10 miracletjf

这个什么时候解决啊~

awumiao avatar Oct 13 '23 02:10 awumiao

另外支付宝,微信小程序带插槽组件渲染时也会出现这个问题 截屏2023-12-16 21 45 46

we125182 avatar Dec 16 '23 13:12 we125182

@Chen-jj 空文本节点删除问题,在hydrate中移除可能导致cn路径变化。那么,是否可以考虑修改PlainText模板,添加类似wx:if指令来删除空文本。比如: image 另外,支付宝这边需要单独修改pickerView, pickerColumnView的模板(看源码不清楚为什么和微信的不一样,单独设置了模板)

we125182 avatar Jan 14 '24 15:01 we125182

原因是,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

zhiqingchen avatar Jan 29 '24 11:01 zhiqingchen

@Chen-jj 空文本节点删除问题,在hydrate中移除可能导致cn路径变化。那么,是否可以考虑修改PlainText模板,添加类似wx:if指令来删除空文本。比如: image 另外,支付宝这边需要单独修改pickerView, pickerColumnView的模板(看源码不清楚为什么和微信的不一样,单独设置了模板)

@we125182 感谢建议~这种方法我们验证下。

支付宝单独处理的原因是 PickerView 后面一定要紧跟 PickerViewColumn,而不能跟 Block

Chen-jj avatar Jan 30 '24 11:01 Chen-jj

要怎么搞啊 太难了

jerryyan1990 avatar Apr 03 '24 08:04 jerryyan1990

另外支付宝,微信小程序带插槽组件渲染时也会出现这个问题

截屏2023-12-16 21 45 46

现在有什么办法手动修复此问题吗,skyline下布局出大问题

BoneTM avatar Apr 05 '24 13:04 BoneTM

这个问题不打算修复吗

Guan-Meng-Yuan avatar Jul 20 '24 04:07 Guan-Meng-Yuan