dcloudio / uni-app

A cross-platform framework using Vue.js
https://uniapp.dcloud.io
Apache License 2.0
40.09k stars 3.63k forks source link

【微信小程序】v-slot作用域有问题 #495

Closed LastHeaven closed 3 years ago

LastHeaven commented 5 years ago

问题描述 使用插槽内容访问子组件中才有的数据时,导致插槽内容无法访问父组件数据

复现步骤 组件A

<template>
  <view><slot name="title" show="test"></slot></view>
</template>

父组件

<template>
<view>
  {{title}}
  <A>
     <view v-slot:title="{show}">
         {{title}}
     </view>
  </A>
</view>
</template>
<script>
export default {
  data () {
    return {
      title: 'test'
    }
  }
}
</script>

预期结果 可以看到A组件外面的tiltle渲染成了test,A里面的title渲染成了test

实际结果 A组件外面的tiltle渲染成了test,A里面的title渲染成了undefined

系统信息:

补充信息 [可选] [根据你的分析,出现这个问题的原因可能在哪里?]

hqzh commented 4 years ago

同样问题

xiaofuliang commented 4 years ago

同样问题

5Mi commented 4 years ago

同样问题

zhetengbiji commented 4 years ago

目前小程序端,作用域插槽内无法使用作用域外的数据

Jonny-china commented 3 years ago

一年半了,还没有解决吗

zhetengbiji commented 3 years ago

针对作用域插槽仅能使用解构插槽类型以及不能使用复杂表达式和作用域外数据的问题,进行了改进,有需求的开发者可以使用 3.1.10 alpha 体验,配置方式:在 manifest.json - mp-weixin 增加新的选项 betterScopedSlots,此配置仅在 alpha 版开放,后续可能会取消或更改此选项。

更新:配置项已修改为:scopedSlotsCompiler: legacy、auto、augmented 默认 auto

JesseChain commented 3 years ago

针对作用域插槽仅能使用解构插槽类型以及不能使用复杂表达式和作用域外数据的问题,进行了改进,有需求的开发者可以使用 3.1.10 alpha 体验,配置方式:在 manifest.json - mp-weixin 增加新的选项 betterScopedSlots,此配置仅在 alpha 版开放,后续可能会取消或更改此选项。

@zhetengbiji 大佬, 开启了betterScopedSlots选项后,只要嵌套了v-for指令,都会编译失败

<view v-for="i in 3" :key="i">
    <CountDown #default="{time}">
        <view>{{time.hours}}:{{time.minutes}}:{{time.seconds}}</view>
    </CountDown>
</view>

或者

<view class="waterfall flex items-start" v-if="columnsData" :style="extraStyle">
    <view v-for="(column, index) in columnsData" :key="index" class="waterfall-column flex-auto">
        <view class="waterfall-item" v-for="data in column" :key="data[nodeKey]">
            <slot :data="data" :extra="extra"></slot>
        </view>
    </view>
</view>
TypeError: Property value expected type of string but got null
    at Object.validate (C:\Users\Jesse\Desktop\Code\basic-mall-applet\node_modules\@babel\types\lib\definitions\utils.js:160:13)
    at validateField (C:\Users\Jesse\Desktop\Code\basic-mall-applet\node_modules\@babel\types\lib\validators\validate.js:24:9)
    at validate (C:\Users\Jesse\Desktop\Code\basic-mall-applet\node_modules\@babel\types\lib\validators\validate.js:17:3)
    at builder (C:\Users\Jesse\Desktop\Code\basic-mall-applet\node_modules\@babel\types\lib\builders\builder.js:38:27)
    at Object.stringLiteral (C:\Users\Jesse\Desktop\Code\basic-mall-applet\node_modules\@babel\types\lib\builders\generated\index.js:354:31)
    at updateIds (C:\Users\Jesse\Desktop\Code\basic-mall-applet\node_modules\@dcloudio\uni-template-compiler\lib\script\traverse\resolve-scoped-slots.js:33:22)
    at C:\Users\Jesse\Desktop\Code\basic-mall-applet\node_modules\@dcloudio\uni-template-compiler\lib\script\traverse\resolve-scoped-slots.js:41:7
    at Array.forEach (<anonymous>)
    at getResolveScopedSlots (C:\Users\Jesse\Desktop\Code\basic-mall-applet\node_modules\@dcloudio\uni-template-compiler\lib\script\traverse\resolve-scoped-slots.js:40:30)
    at Object.CallExpression (C:\Users\Jesse\Desktop\Code\basic-mall-applet\node_modules\@dcloudio\uni-template-compiler\lib\script\traverse\visitor.js:226:15)
    at NodePath._call (C:\Users\Jesse\Desktop\Code\basic-mall-applet\node_modules\@babel\traverse\lib\path\context.js:55:20)
    at NodePath.call (C:\Users\Jesse\Desktop\Code\basic-mall-applet\node_modules\@babel\traverse\lib\path\context.js:42:17)
    at NodePath.visit (C:\Users\Jesse\Desktop\Code\basic-mall-applet\node_modules\@babel\traverse\lib\path\context.js:92:31)
    at TraversalContext.visitQueue (C:\Users\Jesse\Desktop\Code\basic-mall-applet\node_modules\@babel\traverse\lib\context.js:115:16)
    at TraversalContext.visitSingle (C:\Users\Jesse\Desktop\Code\basic-mall-applet\node_modules\@babel\traverse\lib\context.js:84:19)
    at TraversalContext.visit (C:\Users\Jesse\Desktop\Code\basic-mall-applet\node_modules\@babel\traverse\lib\context.js:143:19)
TypeError: Cannot read property 'push' of undefined
    at getRenderSlot (C:\Users\Jesse\Desktop\Code\basic-mall-applet\node_modules\@dcloudio\uni-template-compiler\lib\script\traverse\render-slot.js:30:36)
    at Object.CallExpression (C:\Users\Jesse\Desktop\Code\basic-mall-applet\node_modules\@dcloudio\uni-template-compiler\lib\script\traverse\visitor.js:228:15)
    at NodePath._call (C:\Users\Jesse\Desktop\Code\basic-mall-applet\node_modules\@babel\traverse\lib\path\context.js:55:20)
    at NodePath.call (C:\Users\Jesse\Desktop\Code\basic-mall-applet\node_modules\@babel\traverse\lib\path\context.js:42:17)
    at NodePath.visit (C:\Users\Jesse\Desktop\Code\basic-mall-applet\node_modules\@babel\traverse\lib\path\context.js:92:31)
    at TraversalContext.visitQueue (C:\Users\Jesse\Desktop\Code\basic-mall-applet\node_modules\@babel\traverse\lib\context.js:115:16)
    at TraversalContext.visitMultiple (C:\Users\Jesse\Desktop\Code\basic-mall-applet\node_modules\@babel\traverse\lib\context.js:79:17)
    at TraversalContext.visit (C:\Users\Jesse\Desktop\Code\basic-mall-applet\node_modules\@babel\traverse\lib\context.js:141:19)
    at Function.traverse.node (C:\Users\Jesse\Desktop\Code\basic-mall-applet\node_modules\@babel\traverse\lib\index.js:82:17)
    at NodePath.visit (C:\Users\Jesse\Desktop\Code\basic-mall-applet\node_modules\@babel\traverse\lib\path\context.js:99:18)
    at TraversalContext.visitQueue (C:\Users\Jesse\Desktop\Code\basic-mall-applet\node_modules\@babel\traverse\lib\context.js:115:16)
    at TraversalContext.visitMultiple (C:\Users\Jesse\Desktop\Code\basic-mall-applet\node_modules\@babel\traverse\lib\context.js:79:17)
    at TraversalContext.visit (C:\Users\Jesse\Desktop\Code\basic-mall-applet\node_modules\@babel\traverse\lib\context.js:141:19)
    at Function.traverse.node (C:\Users\Jesse\Desktop\Code\basic-mall-applet\node_modules\@babel\traverse\lib\index.js:82:17)
    at NodePath.visit (C:\Users\Jesse\Desktop\Code\basic-mall-applet\node_modules\@babel\traverse\lib\path\context.js:99:18)
    at TraversalContext.visitQueue (C:\Users\Jesse\Desktop\Code\basic-mall-applet\node_modules\@babel\traverse\lib\context.js:115:16)
NineSu commented 3 years ago

提名上奏啊,这也太无奈了吧 = = 有没有解决方案吖

zhetengbiji commented 3 years ago

提名上奏啊,这也太无奈了吧 = = 有没有解决方案吖

解决方案来了,看你楼上的楼上

zhetengbiji commented 3 years ago

HBuilderX alpha 3.1.19+ 已修复

NineSu commented 3 years ago

HBuilderX alpha 3.1.19+ 已修复

cli 版本 怎么破 0 0

zhetengbiji commented 3 years ago

HBuilderX alpha 3.1.19+ 已修复

cli 版本 怎么破 0 0

酱破:https://uniapp.dcloud.io/quickstart-cli?id=%e4%bf%ae%e6%94%b9%e4%be%9d%e8%b5%96%e4%b8%ba%e6%8c%87%e5%ae%9a%e7%89%88%e6%9c%ac

meooxx commented 3 years ago

Bad: scoped-slot 下面空的shadow-root节点, 节点被渲染到外面去了,尤其只有一个

image good: scoped-slot 下有节点 image

code(伪代码):

// parent

            <A
                :source="list"
                style="width: 100%;"
                v-slot:default="{ item, direct }"
                :newItems="newItems"
            >
                <ItemThumb @itemtap="handleItemTap" :item="item" :direct="direct" />
            </A>

// A.vue
// left list, 和right list 是由source 分出俩列数组数据
<template>
    <view class="c">
        <template>
            <view class="left-scroll column-wrapper">
                <view v-for="item in leftList" :key="item.id" class="item-template-container">
                    <slot :item="item" :direct="0" />
                </view>
            </view>
            <view class="right-scroll column-wrapper">
                <view v-for="item in rightList" :key="item.id" class="item-template-container">
                    <slot :item="item" :direct="1" />
                </view>
            </view>
        </template>
        <view :class="['v', v ? '' : 'virtual-hide']">
            <view v-for="item in temp" :key="item.id" class="d">
                <slot :item="item" />
            </view>
        </view>
    </view>
</template>

有问题的包 good: @dcloudio/uni-template-compiler": "^2.0.0-31920210514002 bad: @dcloudio/uni-template-compiler@2.0.0-31920210709003

@zhetengbiji

wraptor commented 3 years ago

还是没修复,而且更新后旧代码反而不行了,回退回去就可以了,更新新版本的慎重

zhetengbiji commented 3 years ago

还是没修复,而且更新后旧代码反而不行了,回退回去就可以了,更新新版本的慎重

能否提供更具体的描述或者测试

zhetengbiji commented 3 years ago

Bad: scoped-slot 下面空的shadow-root节点, 节点被渲染到外面去了,尤其只有一个

image good: scoped-slot 下有节点 image

code(伪代码):

// parent

            <A
                :source="list"
                style="width: 100%;"
                v-slot:default="{ item, direct }"
                :newItems="newItems"
            >
                <ItemThumb @itemtap="handleItemTap" :item="item" :direct="direct" />
            </A>

// A.vue
// left list, 和right list 是由source 分出俩列数组数据
<template>
    <view class="c">
        <template>
            <view class="left-scroll column-wrapper">
                <view v-for="item in leftList" :key="item.id" class="item-template-container">
                    <slot :item="item" :direct="0" />
                </view>
            </view>
            <view class="right-scroll column-wrapper">
                <view v-for="item in rightList" :key="item.id" class="item-template-container">
                    <slot :item="item" :direct="1" />
                </view>
            </view>
        </template>
        <view :class="['v', v ? '' : 'virtual-hide']">
            <view v-for="item in temp" :key="item.id" class="d">
                <slot :item="item" />
            </view>
        </view>
    </view>
</template>

有问题的包 good: @dcloudio/uni-template-compiler": "^2.0.0-31920210514002 bad: @dcloudio/uni-template-compiler@2.0.0-31920210709003

@zhetengbiji

部分小程序平台(含微信小程序)不支持复用相同插槽(比如 for 循环)只能渲染出一个。新版作用域插槽编译模式编译为了小程序的插槽所以也存在同样问题。可以尝试切换到旧版编译模式:scopedSlotsCompiler:legacy

meooxx commented 3 years ago

Bad:

scoped-slot 下面空的shadow-root节点, 节点被渲染到外面去了,尤其只有一个

image

good:

scoped-slot 下有节点

image

code(伪代码):


// parent

            <A

                :source="list"

                style="width: 100%;"

                v-slot:default="{ item, direct }"

                :newItems="newItems"

            >

                <ItemThumb @itemtap="handleItemTap" :item="item" :direct="direct" />

            </A>

// A.vue

// left list, 和right list 是由source 分出俩列数组数据

<template>

    <view class="c">

        <template>

            <view class="left-scroll column-wrapper">

                <view v-for="item in leftList" :key="item.id" class="item-template-container">

                    <slot :item="item" :direct="0" />

                </view>

            </view>

            <view class="right-scroll column-wrapper">

                <view v-for="item in rightList" :key="item.id" class="item-template-container">

                    <slot :item="item" :direct="1" />

                </view>

            </view>

        </template>

        <view :class="['v', v ? '' : 'virtual-hide']">

            <view v-for="item in temp" :key="item.id" class="d">

                <slot :item="item" />

            </view>

        </view>

    </view>

</template>

有问题的包

good: @dcloudio/uni-template-compiler": "^2.0.0-31920210514002

bad: @dcloudio/uni-template-compiler@2.0.0-31920210709003

@zhetengbiji

部分小程序平台(含微信小程序)不支持复用相同插槽(比如 for 循环)只能渲染出一个。新版作用域插槽编译模式编译为了小程序的插槽所以也存在同样问题。可以尝试切换到旧版编译模式:scopedSlotsCompiler:legacy

已经回退版本了,差点背锅。这种升级是不是要谨慎一点,把好的搞挂了

wraptor commented 3 years ago

还是没修复,而且更新后旧代码反而不行了,回退回去就可以了,更新新版本的慎重

能否提供更具体的描述或者测试

主要场景一个list组件,v-for渲染槽,引用方使用scope取值,大概如下

<template slot-scope="{item,total}"> xxx  </template>

scope传多个值,有的值可以有的不行,item.xxx直接报错,item.aaa又可以取到值,等等之类 取的值会错乱,表现在原先total为0,后面改为1,页面还是0,再改为2页面变成1等等等等

没有深究问题所在,多个页面引组件依赖繁多,生产环境不敢折腾,只知道升级后代码运行报错、以某个页面试点改到不报错后,数据还是错乱,直接回退hbuildx版本万事大吉

JesseChain commented 3 years ago

还是没修复,而且更新后旧代码反而不行了,回退回去就可以了,更新新版本的慎重

能否提供更具体的描述或者测试

主要场景一个list组件,v-for渲染槽,引用方使用scope取值,大概如下


<template slot-scope="{item,total}"> xxx  </template>

scope传多个值,有的值可以有的不行,item.xxx直接报错,item.aaa又可以取到值,等等之类

取的值会错乱,表现在原先total为0,后面改为1,页面还是0,再改为2页面变成1等等等等

没有深究问题所在,多个页面引组件依赖繁多,生产环境不敢折腾,只知道升级后代码运行报错、以某个页面试点改到不报错后,数据还是错乱,直接回退hbuildx版本万事大吉

我也遇到了一样的问题,是个Waterfall瀑布流组件,用到了作用域插槽,外部使用时插槽内接收到的数据错乱,单独开了一个新项目没复现出来,业务繁忙没时间深究,以后会提供个完整的案例

xiaofuliang commented 3 years ago

我也是更新新版本后不行,只渲染了列表的第一个,回退版本后可以

zhetengbiji commented 3 years ago

出现问题的可以收到配置 scopedSlotsCompiler:legacy 为旧版编译模式,默认为 auto,只在判断出现了旧版编译模式处理不了的情况(使用作用域外数据或使用复杂表达式)时才使用新版编译模式,如果手动切回旧版正常,说明这里判断存在问题。

for 循环嵌套插槽只渲染一个的问题外,可以更新 uni 相关依赖到 2.0.0-alpha-31920210715002。

另外如果有谁有详细的复现方式或者示例,可以继续回复,将会跟进。

georgewei commented 3 years ago

macOS上使用HbuilderX 3.1.22.20210709,配置scopedSlotsCompiler为legacy,编译后如果在插槽内使用函数,传入函数的参数为undefined。示例代码如下:

<template>
    <view>
        <waterfall-flow ref="wf-promotions" :srcData="promotions" :columnCount="2" #default="{item, position}">
            <view>
                <video v-if="isFirstUrlVideo(item)" :src="item.images[0].url" :autoplay="true" :show-mute-btn="true" />
                <image v-else :src="item.images[0].url" mode="widthFix" />
            </view>
        </waterfall-flow>
    </view>
</template>

<script>
    import WaterfallFlow from '@/pages/nav/component/waterfall-flow.vue'
    import FileUtils from '@/script/fileUtils'

    export default {
        components: {
            WaterfallFlow
        },
        data() {
            return {
                promotions: [
                    {
                        images: [
                            {
                                url: "" // Set video or image url here
                            }
                        ]
                    }
                ]
            }
        },
        methods: {
            isFirstUrlVideo(item) {
                if (item && item.images && item.images.length) {
                    return FileUtils.isVideo(item.images[0].url);
                }
                return false;
            }
        }
    }
</script>

在isFirstUrlVideo()方法第1行设置断点,控制台先输出了以下错误信息:

mp.runtime.esm.js?66fd:613 [Vue warn]: Property or method "item" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property. See: https://vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.

然后程序才停在断点处,这时开发工具提示item为undefined。

查看编译后的代码,出错处的代码为:

var render = function() {
  var _vm = this
  var _h = _vm.$createElement
  var _c = _vm._self._c || _h
  var m0 = _vm.isFirstUrlVideo(_vm.item) // 怀疑这一行编译错了

  if (!_vm._isMounted) {
    _vm.e0 = function($event) {
      return this.onSwiperImageLoad($event, _vm.index)
    }
  }

  _vm.$mp.data = Object.assign(
    {},
    {
      $root: {
        m0: m0
      }
    }
  )
}
zhetengbiji commented 3 years ago

macOS上使用HbuilderX 3.1.22.20210709,配置scopedSlotsCompiler为legacy,编译后如果在插槽内使用函数,传入函数的参数为undefined。示例代码如下:

<template>
  <view>
      <waterfall-flow ref="wf-promotions" :srcData="promotions" :columnCount="2" #default="{item, position}">
          <view>
              <video v-if="isFirstUrlVideo(item)" :src="item.images[0].url" :autoplay="true" :show-mute-btn="true" />
              <image v-else :src="item.images[0].url" mode="widthFix" />
          </view>
      </waterfall-flow>
  </view>
</template>

<script>
  import WaterfallFlow from '@/pages/nav/component/waterfall-flow.vue'
  import FileUtils from '@/script/fileUtils'

  export default {
      components: {
          WaterfallFlow
      },
      data() {
          return {
              promotions: [
                  {
                      images: [
                          {
                              url: "" // Set video or image url here
                          }
                      ]
                  }
              ]
          }
      },
      methods: {
          isFirstUrlVideo(item) {
              if (item && item.images && item.images.length) {
                  return FileUtils.isVideo(item.images[0].url);
              }
              return false;
          }
      }
  }
</script>

在isFirstUrlVideo()方法第1行设置断点,控制台先输出了以下错误信息:

mp.runtime.esm.js?66fd:613 [Vue warn]: Property or method "item" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property. See: https://vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.

然后程序才停在断点处,这时开发工具提示item为undefined。

查看编译后的代码,出错处的代码为:

var render = function() {
  var _vm = this
  var _h = _vm.$createElement
  var _c = _vm._self._c || _h
  var m0 = _vm.isFirstUrlVideo(_vm.item) // 怀疑这一行编译错了

  if (!_vm._isMounted) {
    _vm.e0 = function($event) {
      return this.onSwiperImageLoad($event, _vm.index)
    }
  }

  _vm.$mp.data = Object.assign(
    {},
    {
      $root: {
        m0: m0
      }
    }
  )
}

scopedSlotsCompiler:legacy 为旧版编译模式,可以尝试切换为自动或者新版模式: auto 与 augmented

xiaofuliang commented 3 years ago

不敢升级到新版本,升级就炸了。。。而且现在列表这种老是报大量日志,会卡死。。 slot "" duplication is found under a single shadow root. The first one was accepted. slot "" duplication is found under a single shadow root. The first one was accepted.

zhetengbiji commented 3 years ago

不敢升级到新版本,升级就炸了。。。而且现在列表这种老是报大量日志,会卡死。。 slot "" duplication is found under a single shadow root. The first one was accepted. slot "" duplication is found under a single shadow root. The first one was accepted.

https://github.com/dcloudio/uni-app/issues/2782

georgewei commented 3 years ago

macOS上使用HbuilderX 3.1.22.20210709,配置scopedSlotsCompiler为legacy,编译后如果在插槽内使用函数,传入函数的参数为undefined。示例代码如下:

<template>
    <view>
        <waterfall-flow ref="wf-promotions" :srcData="promotions" :columnCount="2" #default="{item, position}">
            <view>
                <video v-if="isFirstUrlVideo(item)" :src="item.images[0].url" :autoplay="true" :show-mute-btn="true" />
                <image v-else :src="item.images[0].url" mode="widthFix" />
            </view>
        </waterfall-flow>
    </view>
</template>

<script>
    import WaterfallFlow from '@/pages/nav/component/waterfall-flow.vue'
    import FileUtils from '@/script/fileUtils'

    export default {
        components: {
            WaterfallFlow
        },
        data() {
            return {
                promotions: [
                    {
                        images: [
                            {
                                url: "" // Set video or image url here
                            }
                        ]
                    }
                ]
            }
        },
        methods: {
            isFirstUrlVideo(item) {
                if (item && item.images && item.images.length) {
                    return FileUtils.isVideo(item.images[0].url);
                }
                return false;
            }
        }
    }
</script>

在isFirstUrlVideo()方法第1行设置断点,控制台先输出了以下错误信息:

mp.runtime.esm.js?66fd:613 [Vue warn]: Property or method "item" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property. See: https://vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.

然后程序才停在断点处,这时开发工具提示item为undefined。 查看编译后的代码,出错处的代码为:

var render = function() {
  var _vm = this
  var _h = _vm.$createElement
  var _c = _vm._self._c || _h
  var m0 = _vm.isFirstUrlVideo(_vm.item) // 怀疑这一行编译错了

  if (!_vm._isMounted) {
    _vm.e0 = function($event) {
      return this.onSwiperImageLoad($event, _vm.index)
    }
  }

  _vm.$mp.data = Object.assign(
    {},
    {
      $root: {
        m0: m0
      }
    }
  )
}

scopedSlotsCompiler:legacy 为旧版编译模式,可以尝试切换为自动或者新版模式: auto 与 augmented

编译开关设置为auto有问题呀,前面这么多兄弟已经反映了

zhetengbiji commented 3 years ago

macOS上使用HbuilderX 3.1.22.20210709,配置scopedSlotsCompiler为legacy,编译后如果在插槽内使用函数,传入函数的参数为undefined。示例代码如下:

<template>
  <view>
      <waterfall-flow ref="wf-promotions" :srcData="promotions" :columnCount="2" #default="{item, position}">
          <view>
              <video v-if="isFirstUrlVideo(item)" :src="item.images[0].url" :autoplay="true" :show-mute-btn="true" />
              <image v-else :src="item.images[0].url" mode="widthFix" />
          </view>
      </waterfall-flow>
  </view>
</template>

<script>
  import WaterfallFlow from '@/pages/nav/component/waterfall-flow.vue'
  import FileUtils from '@/script/fileUtils'

  export default {
      components: {
          WaterfallFlow
      },
      data() {
          return {
              promotions: [
                  {
                      images: [
                          {
                              url: "" // Set video or image url here
                          }
                      ]
                  }
              ]
          }
      },
      methods: {
          isFirstUrlVideo(item) {
              if (item && item.images && item.images.length) {
                  return FileUtils.isVideo(item.images[0].url);
              }
              return false;
          }
      }
  }
</script>

在isFirstUrlVideo()方法第1行设置断点,控制台先输出了以下错误信息:

mp.runtime.esm.js?66fd:613 [Vue warn]: Property or method "item" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property. See: https://vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.

然后程序才停在断点处,这时开发工具提示item为undefined。 查看编译后的代码,出错处的代码为:

var render = function() {
  var _vm = this
  var _h = _vm.$createElement
  var _c = _vm._self._c || _h
  var m0 = _vm.isFirstUrlVideo(_vm.item) // 怀疑这一行编译错了

  if (!_vm._isMounted) {
    _vm.e0 = function($event) {
      return this.onSwiperImageLoad($event, _vm.index)
    }
  }

  _vm.$mp.data = Object.assign(
    {},
    {
      $root: {
        m0: m0
      }
    }
  )
}

scopedSlotsCompiler:legacy 为旧版编译模式,可以尝试切换为自动或者新版模式: auto 与 augmented

编译开关设置为auto有问题呀,前面这么多兄弟已经反映了

你说的问题是指的 v-fro 嵌套 slot 的问题吗?

georgewei commented 3 years ago

macOS上使用HbuilderX 3.1.22.20210709,配置scopedSlotsCompiler为legacy,编译后如果在插槽内使用函数,传入函数的参数为undefined。示例代码如下:

<template>
    <view>
        <waterfall-flow ref="wf-promotions" :srcData="promotions" :columnCount="2" #default="{item, position}">
            <view>
                <video v-if="isFirstUrlVideo(item)" :src="item.images[0].url" :autoplay="true" :show-mute-btn="true" />
                <image v-else :src="item.images[0].url" mode="widthFix" />
            </view>
        </waterfall-flow>
    </view>
</template>

<script>
    import WaterfallFlow from '@/pages/nav/component/waterfall-flow.vue'
    import FileUtils from '@/script/fileUtils'

    export default {
        components: {
            WaterfallFlow
        },
        data() {
            return {
                promotions: [
                    {
                        images: [
                            {
                                url: "" // Set video or image url here
                            }
                        ]
                    }
                ]
            }
        },
        methods: {
            isFirstUrlVideo(item) {
                if (item && item.images && item.images.length) {
                    return FileUtils.isVideo(item.images[0].url);
                }
                return false;
            }
        }
    }
</script>

在isFirstUrlVideo()方法第1行设置断点,控制台先输出了以下错误信息:

mp.runtime.esm.js?66fd:613 [Vue warn]: Property or method "item" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property. See: https://vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.

然后程序才停在断点处,这时开发工具提示item为undefined。 查看编译后的代码,出错处的代码为:

var render = function() {
  var _vm = this
  var _h = _vm.$createElement
  var _c = _vm._self._c || _h
  var m0 = _vm.isFirstUrlVideo(_vm.item) // 怀疑这一行编译错了

  if (!_vm._isMounted) {
    _vm.e0 = function($event) {
      return this.onSwiperImageLoad($event, _vm.index)
    }
  }

  _vm.$mp.data = Object.assign(
    {},
    {
      $root: {
        m0: m0
      }
    }
  )
}

scopedSlotsCompiler:legacy 为旧版编译模式,可以尝试切换为自动或者新版模式: auto 与 augmented

编译开关设置为auto有问题呀,前面这么多兄弟已经反映了

你说的问题是指的 v-fro 嵌套 slot 的问题吗?

我测试的结果是scopedSlotsCompiler为auto时上面的代码中的瀑布流中的内容没有渲染,页面空白。控制台错误信息是

[Vue warn]: Property or method "item" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property. See: https://vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.

found in

---> at pages/nav/component/waterfall-flow.vue pages/nav/article/index.vue(env: macOS,mp,1.05.2107221; lib: 2.16.1)

WaterfallFlow的template代码如下:

<template>
    <view class="waterfall-flow-component">
        <view class="waterfall-flow-list">
            <view class="waterfall-flow" :style="{'width': `${100/columnCount}%`}"
                v-for="(columnItem, columnIndex) of columnCount" :key="colmnIndex"
                :id="('waterfall-flow-'+(columnIndex))"
            >
                <view class="waterfall-flow-item"
                    v-for="(item, index) of columns[columnIndex]" :key="index"
                >
                    <slot :item="item" :position="{col: columnIndex, row: index}"></slot>
                </view>
            </view>
        </view>
    </view>
</template>
zhetengbiji commented 3 years ago

macOS上使用HbuilderX 3.1.22.20210709,配置scopedSlotsCompiler为legacy,编译后如果在插槽内使用函数,传入函数的参数为undefined。示例代码如下:

<template>
  <view>
      <waterfall-flow ref="wf-promotions" :srcData="promotions" :columnCount="2" #default="{item, position}">
          <view>
              <video v-if="isFirstUrlVideo(item)" :src="item.images[0].url" :autoplay="true" :show-mute-btn="true" />
              <image v-else :src="item.images[0].url" mode="widthFix" />
          </view>
      </waterfall-flow>
  </view>
</template>

<script>
  import WaterfallFlow from '@/pages/nav/component/waterfall-flow.vue'
  import FileUtils from '@/script/fileUtils'

  export default {
      components: {
          WaterfallFlow
      },
      data() {
          return {
              promotions: [
                  {
                      images: [
                          {
                              url: "" // Set video or image url here
                          }
                      ]
                  }
              ]
          }
      },
      methods: {
          isFirstUrlVideo(item) {
              if (item && item.images && item.images.length) {
                  return FileUtils.isVideo(item.images[0].url);
              }
              return false;
          }
      }
  }
</script>

在isFirstUrlVideo()方法第1行设置断点,控制台先输出了以下错误信息:

mp.runtime.esm.js?66fd:613 [Vue warn]: Property or method "item" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property. See: https://vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.

然后程序才停在断点处,这时开发工具提示item为undefined。 查看编译后的代码,出错处的代码为:

var render = function() {
  var _vm = this
  var _h = _vm.$createElement
  var _c = _vm._self._c || _h
  var m0 = _vm.isFirstUrlVideo(_vm.item) // 怀疑这一行编译错了

  if (!_vm._isMounted) {
    _vm.e0 = function($event) {
      return this.onSwiperImageLoad($event, _vm.index)
    }
  }

  _vm.$mp.data = Object.assign(
    {},
    {
      $root: {
        m0: m0
      }
    }
  )
}

scopedSlotsCompiler:legacy 为旧版编译模式,可以尝试切换为自动或者新版模式: auto 与 augmented

编译开关设置为auto有问题呀,前面这么多兄弟已经反映了

你说的问题是指的 v-fro 嵌套 slot 的问题吗?

我测试的结果是scopedSlotsCompiler为auto时上面的代码中的瀑布流中的内容没有渲染

具体描述一下,如果不是 v-for 嵌套 slot 的问题,应该可以解决。

georgewei commented 3 years ago

@zhetengbiji 请问HBuilderX 3.2.2.20210818有没有修复v-for 嵌套 slot 的问题?scopedSlotsCompiler应该设置为什么值?

swamp-y commented 1 year ago

单个插槽legacy模式,父组件值和子组件插槽传值都能拿到 但是多个插槽情况: legacy模式,父组件值为undifined,插槽值能拿到 augmented模式,父组件值能拿到,插槽值无法获取

uni-app v3.6.2 uni-app cli v2.0.1-36220220914001

Environment Info:

System: OS: macOS 13.1 CPU: (8) x64 Apple M2 Binaries: Node: 14.20.0 - ~/.nvm/versions/node/v14.20.0/bin/node Yarn: Not Found npm: 6.14.17 - ~/.nvm/versions/node/v14.20.0/bin/npm Browsers: Chrome: 109.0.5414.87 Firefox: Not Found Safari: 16.2 npmPackages: @dcloudio/types: ^3.0.4 => 3.0.15 @dcloudio/uni-app-plus: ^2.0.1-35320220729002 => 2.0.1-36220220914001 @dcloudio/uni-app-plus-nvue: 0.0.1 @dcloudio/uni-app-plus-nvue-v8: 0.0.1 @dcloudio/uni-automator: ^2.0.1-35320220729002 => 2.0.1-36220220914001 @dcloudio/uni-cli-i18n: ^2.0.1-35320220729002 => 2.0.1-36220220914001 @dcloudio/uni-cli-shared: ^2.0.1-35320220729002 => 2.0.1-36220220914001 @dcloudio/uni-h5: ^2.0.1-35320220729002 => 2.0.1-36220220914001 @dcloudio/uni-helper-json: * => 1.0.13 @dcloudio/uni-i18n: ^2.0.1-35320220729002 => 2.0.1-36220220914001 @dcloudio/uni-migration: ^2.0.1-35320220729002 => 2.0.1-36220220914001 @dcloudio/uni-mp-360: ^2.0.1-35320220729002 => 2.0.1-36220220914001 @dcloudio/uni-mp-alipay: ^2.0.1-35320220729002 => 2.0.1-36220220914001 @dcloudio/uni-mp-baidu: ^2.0.1-35320220729002 => 2.0.1-36220220914001 @dcloudio/uni-mp-jd: ^2.0.1-35320220729002 => 2.0.1-36220220914001 @dcloudio/uni-mp-kuaishou: ^2.0.1-35320220729002 => 2.0.1-36220220914001 @dcloudio/uni-mp-lark: ^2.0.1-35320220729002 => 2.0.1-36220220914001 @dcloudio/uni-mp-qq: ^2.0.1-35320220729002 => 2.0.1-36220220914001 @dcloudio/uni-mp-toutiao: ^2.0.1-35320220729002 => 2.0.1-36220220914001 @dcloudio/uni-mp-vue: ^2.0.1-35320220729002 => 2.0.1-36220220914001 @dcloudio/uni-mp-weixin: ^2.0.1-35320220729002 => 2.0.1-36220220914001 @dcloudio/uni-mp-xhs: ^2.0.1-35320220729002 => 2.0.1-36220220914001 @dcloudio/uni-quickapp-native: ^2.0.1-35320220729002 => 2.0.1-36220220914001 @dcloudio/uni-quickapp-webview: ^2.0.1-35320220729002 => 2.0.1-36220220914001 @dcloudio/uni-stacktracey: ^2.0.1-35320220729002 => 2.0.1-36220220914001 @dcloudio/uni-stat: ^2.0.1-35320220729002 => 2.0.1-36220220914001 @dcloudio/uni-template-compiler: ^2.0.1-35320220729002 => 2.0.1-36220220914001 @dcloudio/vue-cli-plugin-hbuilderx: ^2.0.1-35320220729002 => 2.0.1-36220220914001 @dcloudio/vue-cli-plugin-uni: ^2.0.1-35320220729002 => 2.0.1-36220220914001 @dcloudio/vue-cli-plugin-uni-optimize: ^2.0.1-35320220729002 => 2.0.1-36220220914001 @dcloudio/webpack-uni-mp-loader: ^2.0.1-35320220729002 => 2.0.1-36220220914001 @dcloudio/webpack-uni-nvue-loader: 0.0.1 @dcloudio/webpack-uni-pages-loader: ^2.0.1-35320220729002 => 2.0.1-36220220914001 @hap-toolkit/dsl-vue: 0.6.13 @vue/babel-helper-vue-jsx-merge-props: 1.4.0 @vue/babel-helper-vue-transform-on: 1.0.2 @vue/babel-plugin-jsx: 1.1.1 @vue/babel-plugin-transform-vue-jsx: 1.4.0 @vue/babel-preset-app: 4.5.19 @vue/babel-preset-jsx: 1.4.0 @vue/babel-sugar-composition-api-inject-h: 1.4.0 @vue/babel-sugar-composition-api-render-instance: 1.4.0 @vue/babel-sugar-functional-vue: 1.4.0 @vue/babel-sugar-inject-h: 1.4.0 @vue/babel-sugar-v-model: 1.4.0 @vue/babel-sugar-v-on: 1.4.0 @vue/cli-overlay: 4.5.19 @vue/cli-plugin-babel: ~4.5.19 => 4.5.19 @vue/cli-plugin-router: 4.5.19 @vue/cli-plugin-vuex: 4.5.19 @vue/cli-service: ~4.5.19 => 4.5.19 @vue/cli-shared-utils: 4.5.19 @vue/compiler-sfc: 2.7.10 @vue/component-compiler-utils: 3.3.0 (3.3.0) @vue/devtools-api: 6.0.0-beta.15 @vue/eslint-config-standard: 5.1.2 => 5.1.2 @vue/preload-webpack-plugin: 1.1.2 @vue/reactivity: 3.0.5 @vue/shared: ^3.0.0 => 3.2.39 @vue/web-component-wrapper: 1.3.0 eslint-plugin-vue: 7.20.0 => 7.20.0 mpvue-page-factory: 1.0.1 mpvue-template-compiler: 1.0.13 uni-h5-vue: 2.6.10 uni-mp-vue: 2.6.10 vue: ^2.6.11 => 2.7.10 vue-eslint-parser: 7.11.0 vue-hot-reload-api: 2.3.4 vue-loader: 15.10.0 (16.8.3, 15.10.0) vue-router: 3.0.1 vue-style-loader: 4.1.3 (4.1.3) vue-template-compiler: ^2.6.11 => 2.7.10 (2.7.10) vue-template-es2015-compiler: 1.9.1 vue3: 1.0.0 vuex: ^3.2.0 => 3.6.2 (3.6.2) npmGlobalPackages: @vue/cli: 5.0.8

zhetengbiji commented 1 year ago

针对 循环只能渲染一个的问题,参考:https://github.com/dcloudio/uni-app/issues/3503

ispiders commented 1 year ago

到现在依然存在这个问题啊,还没修复吗?

zhetengbiji commented 1 year ago

到现在依然存在这个问题啊,还没修复吗?

还有就继续修,详细描述一下

ispiders commented 1 year ago

@zhetengbiji

环境信息 微信小程序,cli编译 3.0.0-alpha-3040820220424001 vue: "^3.2.33" vite: "^2.9.6"


<!-- page -->
<template>
    <parent-com>
        parent
    </parent-com>
</template>

<!-- parent-com -->
<template>
    <!-- 只要这里添加v-slot="{a}",在page中就无法渲染出 parent -->
    <child-com>
        <slot></slot>
    </child-com>
</template>

<!-- child-com -->
<template>
    <view>
        <slot a="child"></slot>
    </view>
</template>
zhetengbiji commented 1 year ago

@zhetengbiji

环境信息 微信小程序,cli编译 3.0.0-alpha-3040820220424001 vue: "^3.2.33" vite: "^2.9.6"

<!-- page -->
<template>
    <parent-com>
        parent
    </parent-com>
</template>

<!-- parent-com -->
<template>
    <!-- 只要这里添加v-slot="{a}",在page中就无法渲染出 parent -->
    <child-com>
        <slot></slot>
    </child-com>
</template>

<!-- child-com -->
<template>
    <view>
        <slot a="child"></slot>
    </view>
</template>

vue3的最好另提一个,可以不用继续在这里盖楼

ispiders commented 1 year ago

@zhetengbiji 我不认为这是vue3的问题,感觉是uniapp针对小程序端的scopedSlots的处理有问题

zhetengbiji commented 1 year ago

@zhetengbiji 我不认为这是vue3的问题,感觉是uniapp针对小程序端的scopedSlots的处理有问题

我不认为这是vue3的问题,我认为是uniapp针对小程序端的scopedSlots的处理有问题 意思是关于uni-app vue3的最好另提一个,可以不用继续在这里盖楼(这里的用户反馈的都是关于uni-app vue2版的,不同的问题摞在一起很容易误导其他人)

guibubing commented 1 year ago

环境微信小程序,这里在ExCountdown里写了个计时器,current 是每秒的计时结果,父组件中在引用scope.current。问题是页面回退在进入当前页面的时候,scope.current不在生效,似乎是第一次页面回退的值。

{{ scope.current }}