级联与树形组件笔记

省市区联动组件

一. V - Distpicker 是一个简单易用的地区选择器

官网: https://distpicker.unie.fun/

安装
npm install v-distpicker --save
全局引入
import VDistpicker from 'v-distpicker'

Vue.component('v-distpicker', VDistpicker)
局部引入(建议)
import VDistpicker from 'v-distpicker'

export default {
  components: { VDistpicker }
}
开始使用
<template>
  <div>
    <v-distpicker :province="select.province" :city="select.city" :area="select.area" @selected="onSelected"></v-distpicker>
  </div>
</template>

<script>
  import VDistpicker from 'v-distpicker'

  export default {
    name: "Distpicker",
    components: {VDistpicker},
    data() {
      return {
        select: { province: '', city: '', area: '' },
      }
    },
    methods: {
      onSelected(data){
        console.log(data)
        this.select.province = data.province.value
        this.select.city = data.city.value
        this.select.area = data.area.value
      }
    },

  }
</script>

<style scoped>

</style>

效果:

在这里插入图片描述

在这里插入图片描述

二. ElementUI的Cascader 级联选择器

官网: https://element.eleme.cn/#/zh-CN/component/cascader

安装
npm i element-ui -S
全局引入(main.js)
import Vue from 'vue';
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
开始使用
  1. click触发子菜单
  • 只需为 Cascader 的options属性指定选项数组即可渲染出一个级联选择器。
  • options属性可以准备一份json数据,(属性的值可以自定义)格式如下:
[{
  "value": "110000",
  "label": "北京市",
  "children": [{
    "value": "110100",
    "label": "北京城区",
    "children": [{
      "value": "110101",
      "label": "东城区"
    }, {
      "value": "110102",
      "label": "西城区"
    }
    ...
  }]
  • 完整代码
<template>
    <div class="block">
        <el-cascader
                v-model="value"
                :options="options"
                @change="handleChange"></el-cascader>
    </div>
</template>

<script>
    export default {
        name: "ClickCas", //这里换成自己组件的名称
        data() {
            return {
                value: [],
                options: require('../../assets/json/province-city-area.json')
            };
        },
        methods: {
            //当选中节点变化时触发
            handleChange(value) { // value: 选中节点的值
                console.log(value);
            }
        }
    };
</script>
  1. hover触发子菜单
  • 通过props.expandTrigger可以定义展开子级菜单的触发方式。
  • 准备的json数据和上方一样
  • 完整代码
<template>
    <div class="block">
        <el-cascader
                v-model="value"
                :options="options"
                :props="{ expandTrigger: 'hover' }"
                @change="handleChange"></el-cascader>
    </div>
</template>

<script>
    export default {
        name: "HoverCas", //这里换成自己组件的名称
        data() {
            return {
                value: [],
                options: require('../../assets/json/province-city-area.json')
            };
        },
        methods: {
            handleChange(value) {
                console.log(value);
            }
        }
    };
</script>

树形组件

一. iView

官网: https://www.iviewui.com/components/tree

安装
npm install view-design --save
全局引入(main.js)
import ViewUI from 'view-design';
import 'view-design/dist/styles/iview.css';

Vue.use(ViewUI);
开始使用
基本用法
<template>
    <Tree :data="data1" @on-select-change="selectChange"></Tree>
</template>
<script>
    export default {
        name: 'BaseTree',//这里换成自己组件的名称
        data () {
            return {
                data1: [
                    {
                        title: 'parent 1',
                        expand: true,
                        children: [
                            {
                                title: 'parent 1-1',
                                expand: true,
                                children: [
                                    {
                                        title: 'leaf 1-1-1'
                                    },
                                    {
                                        title: 'leaf 1-1-2'
                                    }
                                ]
                            },
                            {
                                title: 'parent 1-2',
                                expand: true,
                                children: [
                                    {
                                        title: 'leaf 1-2-1'
                                    },
                                    {
                                        title: 'leaf 1-2-2'
                                    }
                                ]
                            }
                        ]
                    }
                ]
            }
        },
        methods:{
            //点击数节点时触发
            selectChange(data,node){ // data:当前已选中的节点数组  node:当前项

                this.$message.info("当前选中了"+node.title)
            }
        }
    }
</script>
可勾选

设置属性 show-checkbox 可以对节点进行勾选。

<template>
    <Tree :data="data2" show-checkbox @on-check-change="checkChange"></Tree>
</template>
<script>
    export default {
        name: 'CheckBoxTree', //这里换成自己组件的名称
        data () {
            return {
                data2: [
                    {
                        title: 'parent 1',
                        expand: true,
                        children: [
                            {
                                title: 'parent 1-1',
                                expand: true,
                                children: [
                                    {
                                        title: 'leaf 1-1-1'
                                    },
                                    {
                                        title: 'leaf 1-1-2'
                                    }
                                ]
                            },
                            {
                                title: 'parent 1-2',
                                expand: true,
                                children: [
                                    {
                                        title: 'leaf 1-2-1'
                                    },
                                    {
                                        title: 'leaf 1-2-2'
                                    }
                                ]
                            }
                        ]
                    }
                ]
            }
        },
        methods: {
            //点击复选框时触发
            checkChange(nodes, node){ //nodes: 当前已勾选节点的数组 node: 当前节点
                for( var i of nodes){
                    console.log(i.title) //控制台打印选择的
                }
                this.$message.info("当前节点为:"+node.title + "选中状态: "+ node.checked)
            }
        }
    }
</script>
点击标题展开/收起节点

设置属性 expand-node即可

<Tree :data="data1" expand-node></Tree>
默认展开、选中、勾选和禁用

给节点设置 expandselectedcheckeddisabled 可以将节点设置为展开、选中、勾选和禁用。

设置属性 multiple 可进行多选。

<template>
    <Tree :data="data4" show-checkbox multiple></Tree>
</template>
<script>
    export default {
        name:'StatusTree',//这里换成自己组件的名称
        data () {
            return {
                data4: [
                    {
                        title: 'parent 1',
                        expand: true,
                        selected: true,
                        children: [
                            {
                                title: 'parent 1-1',
                                expand: true,
                                children: [
                                    {
                                        title: 'leaf 1-1-1',
                                        disabled: true
                                    },
                                    {
                                        title: 'leaf 1-1-2'
                                    }
                                ]
                            },
                            {
                                title: 'parent 1-2',
                                expand: true,
                                children: [
                                    {
                                        title: 'leaf 1-2-1',
                                        checked: true
                                    },
                                    {
                                        title: 'leaf 1-2-1'
                                    }
                                ]
                            }
                        ]
                    }
                ]
            }
        }
    }
</script>
自定义节点内容

使用强大的 Render 函数可以自定义节点显示内容和交互,比如添加图标按钮, 标题颜色等。

Render 函数的第二个参数,包含三个字段:

  • root :树的根节点
  • node :当前节点
  • data :当前节点的数据

Render 函数分两种,一种是给当前树的每个节点都设置同样的渲染内容,此 render 通过 Tree 组件的属性 render 传递;另一种是单独给某个节点设置,在该节点的 render 字段内设置;同时设置时,会优先使用当前节点的 Render 函数。

<template>
    <div>
        <Tree :data="data5" :render="renderContent" class="demo-tree-render"></Tree>

        <Modal
                v-model="model"
                title="添加节点"
                width="400px"
                @on-ok="ok"
                @on-cancel="cancel">
            <Input v-model="nodeTitle" icon="ios-leaf" placeholder="输入节点名称" style="width: 180px"/>

            标题颜色:&nbsp;<ColorPicker v-model="color"/>
        </Modal>
    </div>


</template>
<script>
    export default {
        name: 'CustomizeTree',  //这里换成自己组件的名称
        data() {
            return {
                color: 'black',
                data: null,
                model: false,
                nodeTitle: '',
                data5: [
                    {
                        title: 'parent 1',
                        icon: 'ios-folder',
                        expand: true,
                        render: (h, {root, node, data}) => {
                            return h('span', {
                                style: {
                                    display: 'inline-block',
                                    width: '100%'
                                }
                            }, [
                                h('span', [
                                    h('Icon', {
                                        props: {
                                            type: data.icon
                                        },
                                        style: {
                                            marginRight: '8px'
                                        }
                                    }),
                                    h('span', data.title)
                                ]),
                                h('span', {
                                    style: {
                                        display: 'inline-block',
                                        float: 'right',
                                        marginRight: '32px'
                                    }
                                }, [
                                    h('Button', {
                                        props: Object.assign({}, this.buttonProps, {
                                            icon: 'ios-add',
                                            type: 'primary'
                                        }),
                                        style: {
                                            width: '64px'
                                        },
                                        on: {
                                            click: () => {
                                                this.append(data)
                                            }
                                        }
                                    })
                                ])
                            ]);
                        },
                        children: [
                            {
                                title: 'child 1-1',
                                expand: true,
                                icon: 'ios-ionitron',
                                children: [
                                    {
                                        title: 'leaf 1-1-1',
                                        expand: true,
                                        icon: 'ios-jet',
                                    },
                                    {
                                        title: 'leaf 1-1-2',
                                        expand: true,
                                        icon: 'ios-leaf',  //扩展图标
                                        color: 'yellow'    //扩展标题颜色
                                    }
                                ]
                            },
                            {
                                title: 'child 1-2',
                                expand: true,
                                children: [
                                    {
                                        title: 'leaf 1-2-1',
                                        expand: true,
                                        icon: 'ios-mail',
                                        color: 'green'
                                    },
                                    {
                                        title: 'leaf 1-2-1',
                                        expand: true,
                                        icon: 'ios-lock',
                                        color: 'red'
                                    }
                                ]
                            }
                        ]
                    }
                ],
                buttonProps: {
                    type: 'default',
                    size: 'small',
                }
            }
        },
        methods: {
            renderContent(h, {root, node, data}) {
                return h('span', {
                    style: {
                        display: 'inline-block',
                        width: '100%'
                    }
                }, [
                    h('span', [
                        h('Icon', {
                            props: {
                                type: data.icon  //设置图标
                            },
                            style: {
                                marginRight: '8px',
                            }
                        }),
                        h('span', {
                            style: {
                                color: data.color  //设置标题颜色
                            }
                        }, data.title)
                    ]),
                    h('span', {
                        style: {
                            display: 'inline-block',
                            float: 'right',
                            marginRight: '32px'
                        }
                    }, [
                        h('Button', {
                            props: Object.assign({}, this.buttonProps, {
                                icon: 'ios-add'
                            }),
                            style: {
                                marginRight: '8px'
                            },
                            on: {
                                click: () => {
                                    this.append(data)
                                }
                            }
                        }),
                        h('Button', {
                            props: Object.assign({}, this.buttonProps, {
                                icon: 'ios-remove'
                            }),
                            on: {
                                click: () => {
                                    this.remove(root, node, data)
                                }
                            }
                        })
                    ])
                ]);
            },
            append(data) {
                this.model = true  //打开对话框
                this.nodeTitle = ''//清空输入
                this.color = 'black' //恢复默认颜色
                this.data = data  //获得节点数据
            },
            remove(root, node, data) {
                const parentKey = root.find(el => el === node).parent;
                const parent = root.find(el => el.nodeKey === parentKey).node;
                const index = parent.children.indexOf(data);
                parent.children.splice(index, 1);
            },
            ok() { //对话框点击确定触发事件
                var data = this.data
                if (this.nodeTitle == '') {
                    this.$Message.info("输入不能为空")
                } else {
                    const children = data.children || [];
                    children.push({
                        title: this.nodeTitle,
                        expand: true,
                        icon: 'ios-leaf',
                        color: this.color
                    });
                    this.$set(data, 'children', children);
                }

            },
            cancel() { //对话框点击取消触发事件
                this.model = false  //关闭对话框
            }
        }
    }
</script>
<style>
    .demo-tree-render .ivu-tree-title {
        width: 100%;
    }
</style>
右键菜单

节点数据开启字段 contextmenu,可以配合 slot contextMenu 实现点击右键弹出菜单。

on-contextmenu当前节点点击右键时触发

<template>
    <Tree :data="data6" @on-contextmenu="handleContextMenu">
        <template slot="contextMenu">
            <DropdownItem @click.native="handleContextMenuEdit">编辑</DropdownItem>
            <DropdownItem @click.native="handleContextMenuDelete" style="color: #ed4014">删除</DropdownItem>
        </template>
    </Tree>
</template>
<script>
    export default {
        name: 'MenuTree', //这里换成自己组件的名称
        data () {
            return {
                data6: [
                    {
                        title: 'parent 1',
                        expand: true,
                        contextmenu: true,
                        children: [
                            {
                                title: 'parent 1-1',
                                expand: true,
                                contextmenu: true,
                                children: [
                                    {
                                        title: 'leaf 1-1-1',
                                        contextmenu: true
                                    },
                                    {
                                        title: 'leaf 1-1-2',
                                        contextmenu: true
                                    }
                                ]
                            },
                            {
                                title: 'parent 1-2',
                                expand: true,
                                contextmenu: true,
                                children: [
                                    {
                                        title: 'leaf 1-2-1',
                                        contextmenu: true
                                    },
                                    {
                                        title: 'leaf 1-2-2',
                                        contextmenu: true
                                    }
                                ]
                            }
                        ]
                    }
                ],
                contextData: null
            }
        },
        methods: {
            handleContextMenu (data) {
                this.contextData = data;
                console.log(data)
            },
            handleContextMenuEdit () {
                this.$Message.info('Click edit of' + this.contextData.title);
            },
            handleContextMenuDelete () {
                this.$Message.info('Click delete of' + this.contextData.title);
            }
        }
    }
</script>
rue
                                    }
                                ]
                            }
                        ]
                    }
                ],
                contextData: null
            }
        },
        methods: {
            handleContextMenu (data) {
                this.contextData = data;
                console.log(data)
            },
            handleContextMenuEdit () {
                this.$Message.info('Click edit of' + this.contextData.title);
            },
            handleContextMenuDelete () {
                this.$Message.info('Click delete of' + this.contextData.title);
            }
        }
    }
</script>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值