自定义一个指令解决部分组件没有scopeid的问题
Demo预览:
https://sunzsh.github.io/vue-demos/#/poper-trans
代码:
https://github.com/sunzsh/vue-el-demo/blob/master/src/main.js
https://github.com/sunzsh/vue-el-demo/blob/master/src/views/poper-trans.vue
上期视频最后的这个问题啊
这个小伙伴猜对了
我们先来回顾一下问题啊
就是我们写好了这个动画效果
但是如果我们放在这个scoped里面
我们来看一下
这个动画就没有了
我们先来看一下原因啊
首先呢这个popover展开的这个层啊
它被挂在的是body底下
而且呢它没有这个scopeid
但是呢我们生成的这个样式
大家看一下我再搜一下
最终他生成的这个样式类名啊
他是包含这个属性选择器的
要求你必须有这个scopeid的这个属性
所以呢他永远也命中不到这个div
有同学还说
我们能不能给他加一个穿透
我们加一个试试啊
v-deep然后呢给后边这个也加一个
我们先加两个
我们来看一下它最终生成的样式
它是这样的
要求前面这个元素
必须有这个scopeid的属性
然后呢它的子元素
如果是这样的话呢
就要求因为我们放在body底下了吗
就要求body必须有这个属性
所以这个也是不现实的
所以这种方法也是不可取的
还有的小伙伴说呢
给这个popover加一个appendtobody
等于false
但是呢
我们来看它官方的组件属性里边
对于popover组件
是没办法设置这个append-to-body
它不像dialog组件儿
它是有这个append-to-body属性的
在这里
所以呢这个方法也不行
那怎么来处理呢
我们再回到这个小伙伴提的方案哈
其实呢我们在页面上可以通过
this.$options.scopeId
来拿到当前这个页面的这个scopeId
我们来看一下
大家看,所以呢我们是可以通过
给它加一个ref
ref等于
popover
然后呢我们在下边通过this.$refs
popover
然后再找到popover里的$refs的pop
这是那个组件的HTML元素
然后给它设置attribute
把这scopeid强制给它设上去
我们来看一下结果
然后呢展开,大家看动画已经有了
我们再来看这个div
大家看这个div
已经有了这个scopeid这个属性了
所以呢我们写的那个样式
是可以命中到这个div的
但是呢这样写的话呢又不是很优雅
所以呢我又想了另外一个办法
我们先把它注释掉
怎么写呢
这个也不用了
我们直接在这写一个指令叫v-scoped
等于this
然后这个自定义的指令怎么写呢
大家看这里
我们在这首先接收两个参数
一个element和一个binding
我们通过binding.value
就能拿到他传的这个this
所以呢
this.$options.scobeId就能拿到scopeid
如果没有scopeid返回,然后呢
我们下边这我先给它注释掉
先来打印一下这个element
打开这element的是span
我们需要给这个span里边的这个tooltip
也就是这个el-popper给这个元素设置scopeid
其实我们一行代码就能解决,这样
element.children[0].setAttribiute(scopedId, "")
大家看,这样就可以了
但是呢
毕竟我们写的是一个公用的指令
这样写的话呢
它就不是很公用只适用于popover
所以呢我们可以这样
我们呀先通过这个方式
拿到它的一个TagName
这个是组件的一个名称哈
我们来看一下它的值是什么
大概是这样的
所以呢我们可以根据它的规则
来去做一些适配
首先呢准备一个target数组
专门用来存放需要添加scoped元素
然后呢我们去对它进行判断
如果它是包含了ELPopover哈
我们就按照el-poper的这个
层级结构去处理
否则的话呢
我们就把element当做需要添加
scopeId的元素
然后最后呢
再通过循环
挨个的给这个他
给它里面的元素设置上scopeId
这样的话呢以后再用的时候
直接在这写一个 v-scoped="this" 就行了
然后如果其他组件需要适配
直接在这个地方写else-if就行了
最后更新于
这有帮助吗?