t***@163.com
t***@163.com
  • 发布:2022-09-07 21:08
  • 更新:2023-11-16 14:26
  • 阅读:338

开发tree组件自定义slot展示有问题

分类:uni-app

开发树形组件使用slot插槽后展示在小程序有问题,最后把代码改成浏览器端非uniapp组件方式运行又能正常运行,怀疑是uniapp对vue3的支持问题还是我的代码bug,麻烦大佬看下,能否告诉我是我代码没对还是需要uniapp继续对vue3的slot特性支持,同时也附上改装普通版本的tree组件。
在小程序中表现


预期效果:节点的文字不应该随着展开关闭变动,应该始终都在
放一组list变量数据

[{  
      "id": 5,  
      "content": "test",  
      "state_dict_id": 5,  
      "children": [{  
        "id": 11,  
        "content": "sub1",  
        "state_dict_id": 5,  
        "parent_id": 5,  
        "children": []  
      }, {  
        "id": 12,  
        "content": "sb2",  
        "state_dict_id": 5,  
        "parent_id": 5,  
        "children": []  
      }]  
    }, {  
      "id": 6,  
      "content": "test21",  
      "desc": "",  
      "state_dict_id": 5,  
      "parent_id": null,  
      "children": []  
    }]

uniapp版

引用.vue页面

<template>  
<rich-tree :data="list" :defaultProps="{label: 'content', children: 'children'}" @on-item-click="handleItemClick">  
            <template #prefix="{node}">{{node.content}} ---</template>  
        </rich-tree>  
</template>

rich-tree.vue页面

<template>  
    <view class="rich-tree">  
        <treeNode v-for="(item, index) in data" :key="item[defaultProps.id]"   
            :defaultProps="defaultProps"  
            :item="item" :depth="depth" :render-content="renderContent">  
            <template #prefix="{node}">  
                <slot name="prefix" :node="node"></slot>  
            </template>  
        </treeNode>  
    </view>  
</template>  

<script setup>  
    import {ref, unref, provide} from 'vue'  
    import treeNode from './tree-node.vue'  
    let depth = ref(1)  
    const props = defineProps({  
        data: {  
            type: Array,  
            default: () => {  
                return []  
            }  
        },  
        defaultProps: {  
            type: Object,  
            default: () => {  
                return {  
                    id: 'id',  
                    children: 'children',  
                    label : 'label'  
                }  
            }  
        },  
    renderContent: Function  
    })  
    provide('onItemClick', handleItemClick)  
    const emit = defineEmits(['on-collapse-click', 'on-item-click'])  
    function handleItemClick(data){  
        emit('on-item-click', data)  
    }  

</script>  

<style lang="scss">  
</style>

tree-node.vue页面

<template>  
        <view class="tree-node" :style="{paddingLeft: depth>1?'12px':null}">  
            <view class="node-item">  
                <view @click="handleItemClick({item, $event})" class="item-left">  
                    <slot name="prefix" :node="item">  
                            {{item[defaultProps.label]}}  
                    </slot>  
                </view>  
                <view v-if="item[defaultProps.children]&&item[defaultProps.children].length" @click="handleCollapseClick" class="collapse-btn">  
                    <view class="divider"></view>  
                    <uni-icons :type="node.isCollapsed?'bottom':'top'" size="15"></uni-icons>  
                </view>  
            </view>  
            <view v-if="item[defaultProps.children]&&!node.isCollapsed" class="node-children"> <!-- 加入展开时渲染 -->  
                <treeNode v-for="(item, index) in item[defaultProps.children]" :key="defaultProps.id" :item="item" :defaultProps="defaultProps"   
                :depth="depth+1" :renderContent="renderContent">  
                    <template #prefix="{node}">  
                        <slot name="prefix" :node="node"></slot>  
                    </template>  
                </treeNode>  
            </view>  
        </view>  
</template>  

<script setup>  
    import {ref, unref, inject, useSlots} from 'vue'  
    import treeNode from './tree-node.vue'  
  const slots = useSlots()  
    const props = defineProps({  
        item: {  
            type: Object,  
            default: () => {  
                return {}  
            }  
        },  
        depth: {  
            type: Number,  
        },  
        defaultProps: {  
            type: Object,  
            default: () => {  
                return {  
                    id: 'id',  
                    children: 'children',  
                    label : 'label'  
                }  
            }  
        },  
        renderContent: Function  
    })  
    console.log('slots is:', slots)  
    let node = ref({depth: props.depth, data: props.item, isCollapsed: false})  
    const emit = defineEmits(['on-collapse-click', 'on-item-click'])  
    const handleItemClick = inject('onItemClick')  
    // function handleItemClick(){  
    //  emit('on-item-click', {item})  
    // }  
    function handleCollapseClick(){  
        console.log('handleCollapseClick...', unref(node).isCollapsed)  
        node.value.isCollapsed = !unref(node).isCollapsed  
        emit('on-collapse-click', {item: props.item})  
    }  

</script>  

<style lang="scss">  
    .tree-node{  
        background-color: #fff;  
    }  
    .node-item{  
    position: relative;  
        display: flex;  
        justify-content: space-between;  
        align-items: center;  
        .item-left{  
            flex: 1;  
            display: flex;  
            padding: 12px 15px;  
        }  
        .collapse-btn{  
            position: relative;  
            padding: 12px 15px;  
            height: 100%;  
            padding-left: 12px;  
            .divider{  
                position: absolute;  
                left: 0;  
                top: 50%;  
                height: 60%;  
                margin-top: calc(-30%);  
                width: 1px;  
                border-left: 1px dashed $uni-border-color;  
            }  
        }  
    }  
</style>

以上代码为uniapp版本的tree的代码,研究半天解决不了问题,用renderContent函数使用vue3的h无法渲染成组件方式,只能渲染成字符串(暂时放弃不考虑了),再附上普通vue3版本的改装tree组件,tree-node组件上下图标用的是iview组件(简单替换即可)

2022-09-07 21:08 负责人:无 分享
已邀请:
t***@163.com

t***@163.com (作者) - 你好我好大家好

我感觉用uniapp开发vue的一些组件或页面遇到我好多bug啊。

t***@163.com

t***@163.com (作者) - 你好我好大家好

还真是没人回答,hbuilderx最新版更新修复好多vue3的bug,这个组件开发遇到的bug会是uniappp的bug吧?

2***@qq.com

2***@qq.com

我和你有一样的困惑,请问你解决了吗?

PonderNext

PonderNext - 我只是个代码搬运工(我比较大方,源码全部开源随便用)

这是我写的,你可以参考试试https://ext.dcloud.net.cn/plugin?id=12265

要回复问题请先登录注册