+ Import
+
+import Tree from 'primevue/tree';
+
+
+ Getting Started
+ Tree component requires an array of TreeNode objects as its value.
+
+ TreeNode API
+
+
+
+
+ Name |
+ Type |
+ Default |
+ Description |
+
+
+
+
+ key |
+ any |
+ null |
+ Mandatory unique key of the node. |
+
+
+ label |
+ string |
+ null |
+ Label of the node. |
+
+
+ data |
+ any |
+ null |
+ Data represented by the node. |
+
+
+ type |
+ string |
+ null |
+ Type of the node to match a template. |
+
+
+ icon |
+ string |
+ null |
+ Icon of the node to display next to content. |
+
+
+ children |
+ TreeNode[] |
+ null |
+ An array of treenodes as children. |
+
+
+ style |
+ string |
+ null |
+ Inline style of the node. |
+
+
+ styleClass |
+ string |
+ null |
+ Style class of the node. |
+
+
+ selectable |
+ boolean |
+ null |
+ Whether the node is selectable when selection mode is enabled. |
+
+
+ leaf |
+ boolean |
+ null |
+ Specifies if the node has children. Used in lazy loading. |
+
+
+
+
+
+ Example below loads the tree nodes from a remote datasource via a service called NodeService.
+
+
+<Tree :value="nodes"></Tree>
+
+
+
+
+import NodeService from '../../service/NodeService';
+
+export default {
+ data() {
+ return {
+ nodes: null
+ }
+ },
+ nodeService: null,
+ created() {
+ this.nodeService = new NodeService();
+ },
+ mounted() {
+ this.nodeService.getTreeNodes().then(data => this.nodes = data);
+ }
+}
+
+
+
+import axios from 'axios';
+
+export default class NodeService {
+
+ getTreeNodes() {
+ return axios.get('demo/data/treenodes.json').then(res => res.data.root);
+ }
+
+}
+
+
+ The json response sample would be as following.
+
+{
+ "root": [
+ {
+ "key": "0",
+ "label": "Documents",
+ "data": "Documents Folder",
+ "icon": "pi pi-fw pi-inbox",
+ "children": [{
+ "key": "0-0",
+ "label": "Work",
+ "data": "Work Folder",
+ "icon": "pi pi-fw pi-cog",
+ "children": [{ "key": "0-0-0", "label": "Expenses.doc", "icon": "pi pi-fw pi-file", "data": "Expenses Document" }, { "key": "0-0-1", "label": "Resume.doc", "icon": "pi pi-fw pi-file", "data": "Resume Document" }]
+ },
+ {
+ "key": "0-1",
+ "label": "Home",
+ "data": "Home Folder",
+ "icon": "pi pi-fw pi-home",
+ "children": [{ "key": "0-1-0", "label": "Invoices.txt", "icon": "pi pi-fw pi-file", "data": "Invoices for this month" }]
+ }]
+ },
+ {
+ "key": "1",
+ "label": "Events",
+ "data": "Events Folder",
+ "icon": "pi pi-fw pi-calendar",
+ "children": [
+ { "key": "1-0", "label": "Meeting", "icon": "pi pi-fw pi-calendar-plus", "data": "Meeting" },
+ { "key": "1-1", "label": "Product Launch", "icon": "pi pi-fw pi-calendar-plus", "data": "Product Launch" },
+ { "key": "1-2", "label": "Report Review", "icon": "pi pi-fw pi-calendar-plus", "data": "Report Review" }]
+ },
+ {
+ "key": "2",
+ "label": "Movies",
+ "data": "Movies Folder",
+ "icon": "pi pi-fw pi-star",
+ "children": [{
+ "key": "2-0",
+ "icon": "pi pi-fw pi-star",
+ "label": "Al Pacino",
+ "data": "Pacino Movies",
+ "children": [{ "key": "2-0-0", "label": "Scarface", "icon": "pi pi-fw pi-video", "data": "Scarface Movie" }, { "key": "2-0-1", "label": "Serpico", "icon": "pi pi-fw pi-video", "data": "Serpico Movie" }]
+ },
+ {
+ "key": "2-1",
+ "label": "Robert De Niro",
+ "icon": "pi pi-fw pi-star",
+ "data": "De Niro Movies",
+ "children": [{ "key": "2-1-0", "label": "Goodfellas", "icon": "pi pi-fw pi-video", "data": "Goodfellas Movie" }, { "key": "2-1-1", "label": "Untouchables", "icon": "pi pi-fw pi-video", "data": "Untouchables Movie" }]
+ }]
+ }
+ ]
+}
+
+
+ Programmatic Control
+ Tree state can be controlled programmatically with the expandedKeys property that defines the keys
+ that are expanded. This property is a Map instance whose key is the key of a node and value is a boolean. Note that expandedKeys also supports two-way binding with the sync modifier.
+
+
+ Example below expands and collapses all nodes with buttons.
+
+
+<div>
+ <Button type="button" icon="pi pi-plus" label="Expand All" @click="expandAll" />
+ <Button type="button" icon="pi pi-minus" label="Collapse All" @click="collapseAll" />
+</div>
+<Tree :value="nodes" :expandedKeys="expandedKeys"></Tree>
+
+
+
+
+import NodeService from '../../service/NodeService';
+
+export default {
+ data() {
+ return {
+ nodes: null,
+ expandedKeys: {}
+ }
+ },
+ nodeService: null,
+ created() {
+ this.nodeService = new NodeService();
+ },
+ mounted() {
+ this.nodeService.getTreeNodes().then(data => this.nodes = data);
+ },
+ methods: {
+ expandAll() {
+ for (let node of this.nodes) {
+ this.expandNode(node);
+ }
+
+ this.expandedKeys = {...this.expandedKeys};
+ },
+ collapseAll() {
+ this.expandedKeys = {};
+ },
+ expandNode(node) {
+ this.expandedKeys[node.key] = true;
+ if (node.children && node.children.length) {
+ for (let child of node.children) {
+ this.expandNode(child);
+ }
+ }
+ }
+ }
+}
+
+
+ To display some nodes as expanded by default, simply add their keys to the map.
+
+import NodeService from '../../service/NodeService';
+
+export default {
+ data() {
+ return {
+ nodes: null,
+ expandedKeys: {}
+ }
+ },
+ nodeService: null,
+ created() {
+ this.nodeService = new NodeService();
+ },
+ mounted() {
+ this.nodeService.getTreeNodes().then(data => {
+ this.nodes = data;
+ this.expandedKeys[this.nodes[0].key] = true;
+ this.expandedKeys[this.nodes[1].key] = true;
+ });
+ }
+}
+
+
+ Selection
+ Tree supports single, multiple and checkbox selection modes. Define the selectionKeys with the sync operator and the selectionMode properties to enable the selection.
+ By default in multiple selection mode, metaKey is necessary to add to existing selections however this can be configured with metaKeySelection property. Note that
+ in touch enabled devices, Tree does not require metaKey. In addition selection on a particular node can be disabled if the selectable is false on the node instance.
+
+ Similarly to the expandedKeys, selectionKeys is a Map instance whose key is the key of a node and value is a boolean in "single" and "multiple" cases. On the other hand
+ in "checkbox" mode, instead of a boolean, value should be an object that has "checked" and "partialChecked" properties to represent the checked state of a node.
+
+
+<h3>Single Selection</h3>
+<Tree :value="nodes" selectionMode="single" :selectionKeys.sync="selectedKey1"></Tree>
+
+<h3>Multiple Selection with MetaKey</h3>
+<Tree :value="nodes" selectionMode="multiple" :selectionKeys.sync="selectedKeys1"></Tree>
+
+<h3>Multiple Selection without MetaKey</h3>
+<Tree :value="nodes" selectionMode="multiple" :selectionKeys.sync="selectedKeys2" :metaKeySelection="false"></Tree>
+
+<h3>Checkbox Selection</h3>
+<Tree :value="nodes" selectionMode="checkbox" :selectionKeys.sync="selectedKeys3"></Tree>
+
+<h3>Events</h3>
+<Tree :value="nodes" selectionMode="single" :selectionKeys.sync="selectedKey2" :metaKeySelection="false"
+ @node-select="onNodeSelect" @node-unselect="onNodeUnselect"></Tree>
+
+
+
+
+import NodeService from '../../service/NodeService';
+
+export default {
+ data() {
+ return {
+ selectedKey1: null,
+ selectedKey2: null,
+ selectedKeys1: null,
+ selectedKeys2: null,
+ selectedKeys3: null,
+ nodes: null
+ }
+ },
+ nodeService: null,
+ created() {
+ this.nodeService = new NodeService();
+ },
+ mounted() {
+ this.nodeService.getTreeNodes().then(data => this.nodes = data);
+ },
+ methods: {
+ onNodeSelect(node) {
+ this.$toast.add({severity:'success', summary: 'Node Selected', detail: node.label, life: 3000});
+ },
+ onNodeUnselect(node) {
+ this.$toast.add({severity:'success', summary: 'Node Unselected', detail: node.label, life: 3000});
+ }
+ }
+}
+
+
+ To display some nodes as selected by default, simply add their keys to the map.
+
+import NodeService from '../../service/NodeService';
+
+export default {
+ data() {
+ return {
+ selectedKey1: null,
+ selectedKey2: null,
+ selectedKeys1: null,
+ selectedKeys2: null,
+ selectedKeys3: null,
+ nodes: null
+ }
+ },
+ nodeService: null,
+ created() {
+ this.nodeService = new NodeService();
+ },
+ mounted() {
+ this.nodeService.getTreeNodes().then(data => {
+ this.nodes = data;
+
+ //single preselection
+ this.selectedKey1[this.nodes[0].key] = true;
+
+ //multiple preselection
+ this.selectedKeys2[this.nodes[0].key] = true;
+ this.selectedKeys2[this.nodes[1].key] = true;
+
+ //checkbox preselection
+ this.selectedKeys2[this.nodes[1].key] = {checked: true};
+ });
+ }
+}
+
+
+ Lazy
+ Lazy Loading is handy to deal with huge datasets. Idea is instead of loading the whole tree, load child nodes on demand
+ using expand expand. The important part is setting leaf to true on a node instance so that even without children,
+ tree would render an expand icon. Example below uses an in memory collection to mimic a lazy loading scenario with timeouts.
+
+
+
+
+<Tree :value="nodes" @node-expand="onNodeExpand" :loading="loading"></Tree>
+
+
+
+
+import NodeService from '../../service/NodeService';
+
+export default {
+ data() {
+ return {
+ loading: false,
+ nodes: null
+ }
+ },
+ nodeService: null,
+ created() {
+ this.nodeService = new NodeService();
+ },
+ mounted() {
+ this.loading = true;
+
+ setTimeout(() => {
+ this.nodes = this.initateNodes();
+ this.loading = false;
+ }, 2000);
+ },
+ methods: {
+ onNodeExpand(node) {
+ if (!node.children) {
+ this.loading = true;
+
+ setTimeout(() => {
+ let _node = {...node};
+ _node.children = [];
+
+ for (let i = 0; i < 3; i++) {
+ _node.children.push({
+ key: node.key + '-' + i,
+ label: 'Lazy ' + node.label + '-' + i
+ });
+ }
+
+ let _nodes = {...this.nodes}
+ _nodes[parseInt(node.key, 10)] = _node;
+
+ this.nodes = _nodes;
+ this.loading = false;
+ }, 500);
+ }
+ },
+ initateNodes() {
+ return [{
+ key: '0',
+ label: 'Node 0',
+ leaf: false
+ },
+ {
+ key: '1',
+ label: 'Node 1',
+ leaf: false
+ },
+ {
+ key: '2',
+ label: 'Node 2',
+ leaf: false
+ }];
+ }
+ }
+}
+
+
+ Templating
+ The type property of a TreeNode is used to map a template to a node to create the node label. If it is undefined and no default template is available,
+ label of the node is used.
+
+
+<Tree :value="nodes">
+ <template #default="slotProps">
+ <b>{{slotProps.node.label}}</b>
+ </template>
+ <template #url="slotProps">
+ <a :href="slotProps.node.data">{{slotProps.node.label}}</a>
+ </template>
+</Tree>
+
+
+
+
+export default {
+ data() {
+ return {
+ nodes: [
+ {
+ key: '0',
+ label: 'Introduction',
+ children: [
+ {key: '0-0', label: 'What is Vue.js?', data:'https://vuejs.org/v2/guide/#What-is-Vue-js', type: 'url'},
+ {key: '0-1', label: 'Getting Started', data: 'https://vuejs.org/v2/guide/#Getting-Started', type: 'url'},
+ {key: '0-2', label: 'Declarative Rendering', data:'https://vuejs.org/v2/guide/#Declarative-Rendering', type: 'url'},
+ {key: '0-3', label: 'Conditionals and Loops', data: 'https://vuejs.org/v2/guide/#Conditionals-and-Loops', type: 'url'}
+ ]
+ },
+ {
+ key: '1',
+ label: 'Components In-Depth',
+ children: [
+ {key: '1-0', label: 'Component Registration', data: 'https://vuejs.org/v2/guide/components-registration.html', type: 'url'},
+ {key: '1-1', llabel: 'Props', data: 'https://vuejs.org/v2/guide/components-props.html', type: 'url'},
+ {key: '1-2', llabel: 'Custom Events', data: 'https://vuejs.org/v2/guide/components-custom-events.html', type: 'url'},
+ {key: '1-3', llabel: 'Slots', data: 'https://vuejs.org/v2/guide/components-slots.html', type: 'url'}
+ ]
+ }
+ ]
+ }
+ }
+}
+
+
+ Filtering
+ Filtering is enabled by setting the filter property to true, by default label property of a node
+ is used to compare against the value in the text field, in order to customize which field(s) should be used during search, define the filterBy property as a comma separated list.
+
+ In addition filterMode specifies the filtering strategy. In lenient mode when the query matches a node, children of the node are not searched further as all descendants of the node are included. On the other hand,
+ in strict mode when the query matches a node, filtering continues on all descendants.
+
+
+
+<h3>Lenient Filter</h3>
+<Tree :value="nodes" :filter="true" filterMode="lenient"></Tree>
+
+<h3>Strict Filter</h3>
+<Tree :value="nodes" :filter="true" filterMode="strict"></Tree>
+
+
+
+
+import NodeService from '../../service/NodeService';
+
+export default {
+ data() {
+ return {
+ nodes: null,
+ expandedKeys: {}
+ }
+ },
+ nodeService: null,
+ created() {
+ this.nodeService = new NodeService();
+ },
+ mounted() {
+ this.nodeService.getTreeNodes().then(data => this.nodes = data);
+ },
+ methods: {
+ expandAll() {
+ for (let node of this.nodes) {
+ this.expandNode(node);
+ }
+
+ this.expandedKeys = {...this.expandedKeys};
+ },
+ collapseAll() {
+ this.expandedKeys = {};
+ },
+ expandNode(node) {
+ this.expandedKeys[node.key] = true;
+ if (node.children << node.children.length) {
+ for (let child of node.children) {
+ this.expandNode(child);
+ }
+ }
+ }
+ }
+}
+
+
+ Properties
+ Any valid attribute such as name and autofocus are passed to the underlying input element. Following is the additional property to configure the component.
+
+
+
+
+ Name |
+ Type |
+ Default |
+ Description |
+
+
+
+
+ value |
+ array |
+ null |
+ An array of treenodes. |
+
+
+ expandedKeys |
+ array |
+ null |
+ A map of keys to represent the state of the tree expansion state in controlled mode. |
+
+
+ selectionMode |
+ string |
+ null |
+ Defines the selection mode, valid values "single", "multiple", and "checkbox". |
+
+
+ selectionKeys |
+ any |
+ null |
+ A map of keys to control the selection state. |
+
+
+ metaKeySelection |
+ boolean |
+ true |
+ Defines how multiple items can be selected, when true metaKey needs to be pressed to select or unselect an item and when set to false selection of each item
+ can be toggled individually. On touch enabled devices, metaKeySelection is turned off automatically. |
+
+
+ loading |
+ boolean |
+ false |
+ Whether to display loading indicator. |
+
+
+ loadingIcon |
+ string |
+ pi pi-spin |
+ Icon to display when tree is loading. |
+
+
+ filter |
+ boolean |
+ false |
+ When specified, displays an input field to filter the items. |
+
+
+ filterBy |
+ string |
+ label |
+ When filtering is enabled, filterBy decides which field or fields (comma separated) to search against. |
+
+
+ filterMode |
+ string |
+ lenient |
+ Mode for filtering valid values are "lenient" and "strict". Default is lenient. |
+
+
+ filterPlaceholder |
+ string |
+ null |
+ Placeholder text to show when filter input is empty. |
+
+
+
+
+
+ Events
+
+
+
+
+ Name |
+ Parameters |
+ Description |
+
+
+
+
+ node-select |
+ node: Node instance |
+ Callback to invoke when a node is selected. |
+
+
+ node-unselect |
+ node: Node instance |
+ Callback to invoke when a node is unselected. |
+
+
+ node-expand |
+ node: Node instance |
+ Callback to invoke when a node is expanded. |
+
+
+ node-collapse |
+ node: Node instance |
+ Callback to invoke when a node is collapsed. |
+
+
+
+
+
+ Styling
+ Following is the list of structural style classes, for theming classes visit theming page.
+
+
+
+
+ Name |
+ Element |
+
+
+
+
+ p-tree |
+ Main container element |
+
+
+ p-tree-horizontal |
+ Main container element in horizontal mode |
+
+
+ p-tree-container |
+ Container of nodes |
+
+
+ p-treenode |
+ A treenode element |
+
+
+ p-treenode-content |
+ Content of a treenode |
+
+
+ p-treenode-toggler |
+ Toggle element |
+
+
+ p-treenode-toggler-icon |
+ Toggle icon |
+
+
+ p-treenode-icon |
+ Icon of a treenode |
+
+
+ p-treenode-label |
+ Label of a treenode |
+
+
+ p-treenode-children |
+ Container element for node children |
+
+
+
+
+
+ Dependencies
+ None.
+
+
+