Open jiangmaniu opened 2 years ago
在 uniapp 的 v3.x 的文档中,注明 APP 端不支持 $slots
$slots
意味着整个UI库的 $slots.xxx 的判断都无法生效,就会导致在 APP 端,使用自定义插槽时,组件内无法判断。
$slots.xxx
例如在 u-cell 组件中使用自定义插槽 right-icon 时,组件由于拿不到 $slots 的值,无法通过 v-if 判断显示 https://github.com/umicro/uView2.0/blob/5fd2933dd788a58c21b12aa91590de66e299821c/uni_modules/uview-ui/components/u-cell/u-cell.vue#L28
u-cell
right-icon
v-if
以上只是其中一个例子,整个库中有多个地方都有使用到 $slots.xxx,可能都会有该问题
我在自己写组件的时候也有遇到这个问题,我目前想到两种方案
继续上个例子举例,在 props 中添加 customRightIcon 属性,在模板中替换掉 $slots.xxx 的判断
customRightIcon
props: { customRightIcon: { type: Boolean, default: false } }
<view class="u-cell__right-icon-wrap" v-if="customRightIcon || isLink"> ... </view>
该方案的好处在于:已知的兼容性好,全平台都可兼容 该方案的坏处在于:每个需要 v-if 判断的自定义的插槽都需要定义 props,使用者每次都需要写上自定义插槽的同时,添加对应的判断 props 属性,增加使用者的心智负担,并且会使不需要兼容 APP 的开发者也需要添加自定义属性。
兼容性好
props
props 定义的判断属性,不在替换代替 $slot.xxx,而是在原有 v-if 的判断条件上添加 props 属性
$slot.xxx
<view class="u-cell__right-icon-wrap" v-if="$slots['right-icon'] || isLink || customRightIcon "> ... </view>
需要兼容 APP 的开发者,在写插槽的同时添加上插槽对应的自定义 props 属性,否则直接写上插槽即可
vm.$scopedSlots
根据上面 v3.x 的介绍可得,v3.x 是兼容 $scopedSlots,并且在 APP 中粗略测试后,发现在不指定 slot-scope 的情况下也能获取到传入的插槽
v3.x
$scopedSlots
APP
slot-scope
<!-- 业务 --> <u-cell> <view>这是 default 插槽</view> <template #right-icon> <view>这是 right-icon 插槽</view> </template> </u-cell> <!-- u-cell --> mounted() { console.log(this.$scopedSlots) }
由此可在原有 v-if 判断条件基础添加 $scopedSlots.xxxx 条件,即可兼容 APP 端
$scopedSlots.xxxx
该方案的问题在于:只是简单的看了一下 $scopedSlots api 拥有传入 slot,没有完整测试跨平台的兼容性。
以上思路的可行性如被通过,我很乐意为此方案提交 PR!如果有更好的实现思路,欢迎留言一起探讨学习。
感谢建议,我们内部会探讨一下
关于第二种方法,我在iPhone 6 Plus 和 Redni K40 Gaming 两款机型上测试:把原有的 vm.$slots 方法去除, 添加 vm.$scopedSlots 方法,在app都可以很好的实现具名插槽的判断。在不影响原有的组件使用和条件判断可以使用Uniapp的条件编译来兼容app
问题描述
在 uniapp 的 v3.x 的文档中,注明 APP 端不支持
$slots
意味着整个UI库的
$slots.xxx
的判断都无法生效,就会导致在 APP 端,使用自定义插槽时,组件内无法判断。例如在
u-cell
组件中使用自定义插槽right-icon
时,组件由于拿不到$slots
的值,无法通过v-if
判断显示 https://github.com/umicro/uView2.0/blob/5fd2933dd788a58c21b12aa91590de66e299821c/uni_modules/uview-ui/components/u-cell/u-cell.vue#L28以上只是其中一个例子,整个库中有多个地方都有使用到
$slots.xxx
,可能都会有该问题解决思路
我在自己写组件的时候也有遇到这个问题,我目前想到两种方案
1. 添加 props 属性来注明是否使用自定义插槽
继续上个例子举例,在 props 中添加
customRightIcon
属性,在模板中替换掉$slots.xxx
的判断该方案的好处在于:已知的
兼容性好
,全平台都可兼容 该方案的坏处在于:每个需要v-if
判断的自定义的插槽都需要定义props
,使用者每次都需要写上自定义插槽的同时,添加对应的判断props
属性,增加使用者的心智负担,并且会使不需要兼容 APP 的开发者也需要添加自定义属性。针对不需要兼容 APP 的方案
props
定义的判断属性,不在替换代替$slot.xxx
,而是在原有v-if
的判断条件上添加props
属性需要兼容 APP 的开发者,在写插槽的同时添加上插槽对应的自定义
props
属性,否则直接写上插槽即可2. 通过
vm.$scopedSlots
判断是否使用根据上面 v3.x 的介绍可得,
v3.x
是兼容$scopedSlots
,并且在APP
中粗略测试后,发现在不指定slot-scope
的情况下也能获取到传入的插槽由此可在原有
v-if
判断条件基础添加$scopedSlots.xxxx
条件,即可兼容 APP 端该方案的问题在于:只是简单的看了一下
$scopedSlots
api 拥有传入 slot,没有完整测试跨平台的兼容性。最后
以上思路的可行性如被通过,我很乐意为此方案提交 PR!如果有更好的实现思路,欢迎留言一起探讨学习。