y***@wisdomidata.com
y***@wisdomidata.com
  • 发布:2019-05-14 10:16
  • 更新:2021-06-15 12:06
  • 阅读:2075

【报Bug】自定义模式下,slot内组件可使用解构数据,但在父作用域内使用data属性无效

分类:uni-app

详细问题描述

定义一个组件A,A组件接收数组属性,在循环内部有slot插槽并绑定item数据,B是Vue页面使用A组件并解构item,渲染item里面的数据没有问题,但是引用本页面(父作用域)的data属性全部无效(包括methods内的方法)  
这个问题应该是slot内容组件的最基本用法,应该会有很多人发现这个问题吧,否则只能是我什么地方使用不当导致,请帮忙排查一下,谢谢!  

[内容]

重现步骤

[步骤]
见详细问题描述

[结果]
父模板内的slot内容组件无法使用父作用域的data属性

[期望]
可以使用父作用域的data属性,这一点在Vue官网有说明(父级模板里的所有内容都是在父级作用域中编译的;子模板里的所有内容都是在子作用域中编译的)

[如果语言难以表述清晰,拍一个视频或截图,有图有真相]

IDE运行环境说明

[HBuilder 或 HBuilderX。如果你用其他工具开发uni-app,也需要在此说明]

[IDE版本号]
HbuilderX 1.9.4

[windows版本号]

[mac版本号]

uni-app运行环境说明

[运行端是h5或app或某个小程序?]
小程序和APP都有问题,H5是OK的

[运行端版本号]
小程序为例:调试基础库版本2.6.4

[项目是cli创建的还是HBuilderX创建的?如果是cli创建的,请更新到最新版cli再试]
HBuilderX

[编译模式是老模板模式还是新的自定义组件模式?]

App运行环境说明

[Android版本号]

[iOS版本号]

[手机型号]

[模拟器型号]

附件

[IDE问题请提供HBuilderX运行日志。菜单帮助-查看运行日志,点右键打开文件所在目录,将log文件压缩成zip包上传]

[App问题请提供可重现问题的代码片段,你补充的细一点,问题就解决的快一点]

[App安装包或H5地址]

[可重现代码片段]
代码问题说明:w-addcard.vue里面status即为data属性,不起作用

w-list-action.vue文件模板代码

<template>  
    <view>  
        <view class="cu-list" :class="hasAvator ? 'menu-avatar': ''">  
            <view v-for="(item, index) in list" :key="index" class="cu-item flex-row" :class="current == index ? 'move-cur': ''" @click="$emit('itemClick', item)"  
             @touchstart="touchStart" @touchmove="touchMove" @touchend="touchEnd" :data-target="index">  
                **<slot v-bind:item="item"></slot>**  
                <view v-if="item.actions" class="move">  
                    <view v-for="(action1, actionIndex1) in item.actions" :key="actionIndex1" :class="action1.bgColor" @click="$emit('actionClick', index, actionIndex1)">{{action1.text}}</view>  
                </view>  
                <view v-else-if="actions" class="move">  
                    <view v-for="(action, actionIndex) in actions" :key="actionIndex" :class="action.bgColor" @click="$emit('actionClick', index, actionIndex)">{{action.text}}</view>  
                </view>  
            </view>  
        </view>  
    </view>  
</template>

w-addcard.vue页面的相关代码

<template>  
    <view>  
        <view class="full-screen">  
            <w-search-bar v-model="value"></w-search-bar>  
            <view class="has-searchbar-tabbar flex-column align-center">  
                <button class="cu-btn bg-green padding" @click="onClick">点我</button>  
                <w-list-action :list="list" :actions="actions" v-slot:default="{item}">  
                    <view class="is-width-100vw is-height-10vh flex-row flex-center">  
                        **<text>{{status}}</text>**  
                    </view>  
                </w-list-action>  
            </view>  
            <w-tabbar-center selectedColor="is-color-blue" :tabs="tabs" :current.sync="current"></w-tabbar-center>  
        </view>  
    </view>  
</template>  

<script>  
    import wTabbar from "../../../../../components/bar/tabbar/w-tabbar.vue";  
    import wTabbarCenter from "../../../../../components/bar/tabbar/w-tabbar-center.vue";  
    import wSearchBar from "../../../../../components/bar/searchbar/w-search-bar.vue";  
    import wSwiper from "../../../../../components/swiper/w-swiper.vue";  
    import wDrawer from "../../../../../components/drawer/w-drawer.vue";  
    import wListAction from "../../../../../components/list/w-list-action.vue";  

    export default {  
        components: {  
            wTabbar,  
            wTabbarCenter,  
            wSearchBar,  
            wSwiper,  
            wDrawer,  
            wListAction  
        },  

        data() {  
            return {  
                value: "",  
                current: 0,  
                show: false,  
                status: 'loading',  
                list: [{  
                        name: "第一个"  
                    },  
                    {  
                        name: "第二个"  
                    },  
                    {  
                        name: "第三个"  
                    }  
                ],  
                actions: [{  
                        bgColor: 'bg-gray',  
                        text: '置顶'  
                    },  
                    {  
                        bgColor: 'bg-red',  
                        text: '删除'  
                    }  
                ],  
                swipers: [{  
                    id: 0,  
                    type: 'image',  
                    url: 'https://ossweb-img.qq.com/images/lol/web201310/skin/big84000.jpg'  
                }, {  
                    id: 1,  
                    type: 'image',  
                    url: 'https://ossweb-img.qq.com/images/lol/web201310/skin/big84001.jpg',  
                }, {  
                    id: 2,  
                    type: 'image',  
                    url: 'https://ossweb-img.qq.com/images/lol/web201310/skin/big39000.jpg'  
                }, {  
                    id: 3,  
                    type: 'image',  
                    url: 'https://ossweb-img.qq.com/images/lol/web201310/skin/big10001.jpg'  
                }, {  
                    id: 4,  
                    type: 'image',  
                    url: 'https://ossweb-img.qq.com/images/lol/web201310/skin/big25011.jpg'  
                }, {  
                    id: 5,  
                    type: 'image',  
                    url: 'https://ossweb-img.qq.com/images/lol/web201310/skin/big21016.jpg'  
                }, {  
                    id: 6,  
                    type: 'image',  
                    url: 'https://ossweb-img.qq.com/images/lol/web201310/skin/big99008.jpg'  
                }],  
                tabs: [{  
                        text: "首页",  
                        badge: "99+",  
                        icon: 'iconfont icon-home',  
                        iconPath: "/static/img/tabBar/home.png",  
                        selectedIconPath: "/static/img/tabBar/home-hl.png"  
                    },  
                    {  
                        text: "工作台",  
                        iconPath: "/static/img/tabBar/bench.png",  
                        selectedIconPath: "/static/img/tabBar/bench-hl.png"  
                    },  
                    {  
                        text: "我的",  
                        badge: "9",  
                        icon: 'iconfont icon-person',  
                        iconPath: "/static/img/tabBar/person.png",  
                        selectedIconPath: "/static/img/tabBar/person-hl.png"  
                    }  
                ]  
            };  
        },  

        methods: {  
            itemClicked(index) {  
                uni.showToast({  
                    title: "你点击了" + index  
                })  
            },  
            onClick() {  
                this.status = 'over';  
                setTimeout(_ => {  
                    this.status = 'erro';  
                }, 3000);  
            }  
        }  
    }  
</script>

联系方式

[QQ]
409714243@qq.com

2019-05-14 10:16 负责人:无 分享
已邀请:

最佳回复

DCloud_UNI_GSQ

DCloud_UNI_GSQ

HBuilderX alpha 3.1.19+ 已修复

  • 3***@qq.com

    大佬,我用的hx正式版3.2.3,微信小程序端「不能使用作用域外数据」这个问题依然存在,是只在alpha版修复了吗?

    9 小时前

  • DCloud_UNI_GSQ

    回复 3***@qq.com: 详细描述一下

    4 小时前

麦克雷

麦克雷 - 肥比

我看这个问题2019年12月份都提出来了,他们都说这个问题有点难搞,现在还是不行,看来这个问题真的超级难搞

DCloud_UNI_GSQ

DCloud_UNI_GSQ

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

HBuilderX alpha 3.1.19+ 已修复

DCloud_UNI_GSQ

DCloud_UNI_GSQ

目前有此限制:当使用解构插槽时,插槽不能访问父作用域的数据

  • 1***@163.com

    我也遇到同样问题!不一样的是:子组件A(二级组件)调用孙子组件B(三级组件)时,孙子组件B slot内不能使用子组件A内的数据数据。但父组件(一级组件)调用孙子组件B(三级组件)时时隙内的数据使用父组件(一级组件)的数据属性值却能正常显示。

    2019-07-08 10:15

1***@163.com

1***@163.com

我也遇到同样问题!不一样的是:子组件A(二级组件) 调用孙子组件B(三级组件)时,孙子组件B slot内不能使用子组件A内的data数据。但父组件(一级组件)调用孙子组件B(三级组件)时slot内的数据使用父组件(一级组件)的data属性值却能正常显示。

k***@qq.com

k***@qq.com

我看这个问题2019年5月份都提出来了,现在还是不行,看来这个问题有点难搞

t***@163.com

t***@163.com

我看这个问题2019年8月份都提出来了,有人说这个问题有点难搞,我看现在还是不行,看来这个问题真的有点难搞

7***@qq.com

7***@qq.com - hello world

我看这个问题一年前都提出来了,现在还是不行,看来这个问题有点难搞

4***@qq.com

4***@qq.com

我看这个问题一年前都提出来了,现在还是不行,看来这个问题有点难搞

z***@techscan.cn

z***@techscan.cn

同样遇到这个问题

目前只能给父组件加上一个额外的prop,把需要传递的变量放进去,然后在组件中的slot上加上这个prop。
这样在template上的slot-scope中就能用到父组件中的变量了

1***@qq.com

1***@qq.com - ssss

支付宝小程序 依然有此问题,父组件的方法在插槽作用域内不能使用

清茶涩

清茶涩

难搞的一笔,现在还是这样,我以为小程序限制了。都直接把父组件的数据放到子组件prop中再通过slot-scope取出来的

要回复问题请先登录注册