资讯专栏INFORMATION COLUMN

Vue & Bootstrap 结合学习笔记(二)

Shonim / 3367人阅读

摘要:具名插槽适用于具有一定结构且有多处不固定内容的组件此时在定义组件时其实就是预留了多个空缺位置且分别命名如果只有一个当然也可以采用具名插槽,但肯定不如默认插槽,只会徒增配置成本。然后在使用时将内容分成多块分别命名成预留空缺位置的名字。

本文主要描述不才在学习Vue和Bootstrap中遇到的关于插槽的问题及解决方案
插槽理解

vue官网和很多热心朋友又很多关于默认插槽,具名插槽,插槽作用域相关的解释,我就不重复搬过来占用篇幅了,这里简单的谈谈我个人的浅见。

插槽就是预留位置
插槽其实就是定义组件时预留的一些位置,将使用组件时组件内额外的一些标签写入到对应的预留位置就是插槽的作用了。

插槽适用于不固定内容的组件
正是因为无法预见组件内部所有可能的标签或内容,所以干脆留一个空缺,全权交给使用者,想填啥就用啥。

具名插槽适用于具有一定结构且有多处不固定内容的组件
此时在定义组件时其实就是预留了多个空缺位置且分别命名(如果只有一个当然也可以采用具名插槽,但肯定不如默认插槽,只会徒增配置成本)。然后在使用时将内容分成多块分别命名成预留空缺位置的名字。

组件理解

为什么要定义组件?
答:定义组件是一种封装的形式,使用最简单的标签及属性配置表达一大段比较丰富的结构效果及一些数据和事件。

Bootstrap组件-Collapse(Accordion example) 官网HTML代码
Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. 3 wolf moon officia aute, non cupidatat skateboard dolor brunch. Food truck quinoa nesciunt laborum eiusmod. Brunch 3 wolf moon tempor, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably haven"t heard of them accusamus labore sustainable VHS.
Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. 3 wolf moon officia aute, non cupidatat skateboard dolor brunch. Food truck quinoa nesciunt laborum eiusmod. Brunch 3 wolf moon tempor, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably haven"t heard of them accusamus labore sustainable VHS.
Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. 3 wolf moon officia aute, non cupidatat skateboard dolor brunch. Food truck quinoa nesciunt laborum eiusmod. Brunch 3 wolf moon tempor, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably haven"t heard of them accusamus labore sustainable VHS.

该示例代码比较长

结构是很有规律的,很容易发现几个共同的结构:card, card-header, card-body...

文案是具体的展示信息,也是我们希望组件能够配置的

最精简的组件配置

    
Anim pariatur ...
Anim pariatur ...
Anim pariatur ...

header一般文本就够用了,所以直接配置在标签属性上

content, 如"Anim pariatur ..."我们预想其可能是其他的一个或多个组件甚至大段html(会有标签),此时放到属性内就不合适了,配置起来超级麻烦

组件封装

获取header简单。遍历$children从其attrs对象中可以读取到,放到data中的一个数组里,采用v-for指令即可很容易渲染出来

获取content不容易。$children都是虚拟DOM,反向变成html的API没找到;再者就算找到了,同header一样遍历渲染出来,也只是当成字符串渲染出来,加上v-html指令,标准的HTML标签倒是确实渲染出来了,可已定义的组件标签未能正确解析渲染(不知道vue有没有相应的API方法解决)。

插槽刚好可以解决内容中的标签解析问题,但它会将所有的内容(上例中3个div)都解析到一起无法拆分

具名插槽可以解决内容无法拆分的问题。那我们就把内容中的每一个都标一个name, name取值要满足内容个数不定的条件,所以最好采用和序号有关的,刚好可以在v-for指令中匹配到。

问题解决!

组件定义
Vue.component("widget-collapse", {
    template: `
`, data() { let children = this.$slots, items = []; for (let i in children) { let node = children[i][0]; if (node.tag) { items[i] = ({ header: VTool.attr(node, "header") || ("Item " + items.length), }) } } return { vitems: items } } })
组件使用

    
Anim pariatur ...
Anim pariatur ...
Anim pariatur ...
组件优化

使用时每个节点都写一个slot太累赘,容易写错,删除某个节点或调整节点顺序后更改麻烦,能否程序动态帮忙添加该slot属性?
答:未找到对应API,但对比默认与具名插槽的$slots数据对象发现key分别为default和具名name

动态增加$slots属性值
Vue.component("widget-collapse", {
    template: `
`, data() { let children = this.$slots.default, items = []; for (let i = 0, len = children.length; i < len; i++) { let node = children[i]; if (node.tag) { let id = VTool.random(); this.$slots[id] = node; items.push({ id: id, header: VTool.attr(node, "header") || ("Item " + items.length), }) } } return { vitems: items } } })
删除使用时的插槽命名

    
Anim pariatur ...
Anim pariatur ...
Anim pariatur ...
同步更新

以上设置基本初始化是没有任何问题了,但在vue对象更新时会更改$slots对象
(经跟踪代码查找到updateChildComponent方法内在更新下层组件时执行了vm.$slots = resolveSlots(renderChildren, parentVnode.context);覆盖了之前缩处理过的$slots,且会在vm._render方法中重新渲染,且在此之前没有公布任何事件,那就暴力覆盖重写了)

Vue.component("widget-collapse", {
    ...
    created() {
        let _render = this._render;
        this._render = function() {
            let $slots = this.$slots;
            for (let name in $slots) {
                if (name !== "default") {
                    return _render.apply(this, arguments);
                }
            }
            // 此时肯定是重新new的$slots, 重写对应关系
            let children = this.$slots.default, items = [];
            for (let i = 0, len = children.length; i < len; i++) {
                let node = children[i];
                if (node.tag) {
                    let id = VTool.random();
                    this.$slots[id] = node;
                    items.push({
                        id: id,
                        header: VTool.attr(node, "header") || ("Item " + items.length),
                    })
                }
            }
            this.vitems = items;
            return _render.apply(this, arguments);
        }
    },
    ...
})
本文对于vue插槽的处理办法略显暴力,但的确解决了我遇到的问题,各位大拿有更好的经验还请不吝赐教,拜谢!

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/95602.html

相关文章

  • Vue &amp; Bootstrap 结合学习笔记

    摘要:具名插槽适用于具有一定结构且有多处不固定内容的组件此时在定义组件时其实就是预留了多个空缺位置且分别命名如果只有一个当然也可以采用具名插槽,但肯定不如默认插槽,只会徒增配置成本。然后在使用时将内容分成多块分别命名成预留空缺位置的名字。 本文主要描述不才在学习Vue和Bootstrap中遇到的关于插槽的问题及解决方案 插槽理解 vue官网和很多热心朋友又很多关于默认插槽,具名插槽,插槽作用...

    Karrdy 评论0 收藏0
  • Vue &amp; Bootstrap 结合学习笔记(一)

    摘要:项目介绍旨在通过项目的形式同时学习和,实现一个在线配置页面的功能。通过封装好的组件样式提供界面需要的组件,通过实现组件状态更改及页面渲染。 本文是不才在学习Vue和Bootstrap过程中遇到问题解决的一些思路,主要描述了项目搭建,组件封装、获取、编辑、更新的一步步实现,一些解决方案也没找到正确的官方API,还请大拿们多多提点。 项目介绍 旨在通过项目的形式同时学习Vue和Bootst...

    hyuan 评论0 收藏0
  • Vue &amp; Bootstrap 结合学习笔记(一)

    摘要:项目介绍旨在通过项目的形式同时学习和,实现一个在线配置页面的功能。通过封装好的组件样式提供界面需要的组件,通过实现组件状态更改及页面渲染。 本文是不才在学习Vue和Bootstrap过程中遇到问题解决的一些思路,主要描述了项目搭建,组件封装、获取、编辑、更新的一步步实现,一些解决方案也没找到正确的官方API,还请大拿们多多提点。 项目介绍 旨在通过项目的形式同时学习Vue和Bootst...

    魏宪会 评论0 收藏0
  • 前端资源系列(4)-前端学习资源分享&amp;前端面试资源汇总

    摘要:特意对前端学习资源做一个汇总,方便自己学习查阅参考,和好友们共同进步。 特意对前端学习资源做一个汇总,方便自己学习查阅参考,和好友们共同进步。 本以为自己收藏的站点多,可以很快搞定,没想到一入汇总深似海。还有很多不足&遗漏的地方,欢迎补充。有错误的地方,还请斧正... 托管: welcome to git,欢迎交流,感谢star 有好友反应和斧正,会及时更新,平时业务工作时也会不定期更...

    princekin 评论0 收藏0
  • Vue.js资源分享

    摘要:中文官网英文官网组织发出一个问题之后,不要暂时的离开电脑,如果没有把握先不要提问。珍惜每一次提问,感恩每一次反馈,每个人工作还是业余之外抽出的时间有限,充分准备好应有的资源之后再发问,有利于问题能够高效质量地得到解决。 Vue.js资源分享 更多资源请Star:https://github.com/maidishike... 文章转自:https://github.com/maid...

    vpants 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<