javascript - 在树视图中选择和取消选择节点 - vuejs
问题描述
我是 VueJS 的新手。我一直致力于从 vuejs 文档中自定义树视图示例:示例。
在树视图中选择一个项目时,我无法理解如何取消选择,即取消设置先前选择的项目的类。我尝试过的一些方法包括
- 使用设置全局变量
Vue.prototype
,在这种情况下,计算函数甚至不会运行。 - 我知道传递的事件对象。使用它和 jQuery,删除先前选择的 div 的类会起作用,但这似乎是一个 hack。
- 在中设置所选项目的数组
data
在单击事件这也行不通。
有没有一种可行的方法,或者我不理解某些东西?
我正在处理的 codepen 链接:Codepen。要选择一个节点,只需单击该节点并尝试选择其他一些节点。前一个节点不会被清除。
谢谢!
更新:
以下答案有效,但如果单击其他地方,它将删除选定的类。我想要一个解决方案,只有当我单击其他节点时才会删除所选类。我所要做的就是创建一个事件总线并将先前选择的组件对象存储在父变量中。单击新节点时,将发出一个全局事件,主实例方法将监听该事件。在那里,它将设置一个布尔值,该值将取消设置先前的组件选择,另一个布尔值将选定的类设置为新的组件对象。我不确定是否存在更好的方法。
更新了 codepen 并进行了一些更改: CodePen 链接
解决方案
这和 VueJS 无关,我们必须通过在文件夹节点获得焦点时设置所需的 css 属性来玩 CSS。
//https://github.com/vuejs/Discussion/issues/356
// demo data
Vue.prototype.$selectedNode = []
var data = {
name: 'My Tree',
children: [{
name: 'hello'
},
{
name: 'wat'
},
{
name: 'child folder',
children: [{
name: 'child folder',
children: [{
name: 'hello'
},
{
name: 'wat'
}
]
},
{
name: 'hello'
},
{
name: 'wat'
},
{
name: 'child folder',
children: [{
name: 'hello'
},
{
name: 'wat'
}
]
}
]
}
]
}
// define the item component
Vue.component('item', {
template: '#item-template',
props: {
model: Object
},
data: function() {
return {
open: false,
selectedNode: []
}
},
computed: {
isFolder: function() {
return this.model.children &&
this.model.children.length
},
setChevronClass: function() {
return {
opened: this.isFolder && this.open,
closed: this.isFolder && !this.open,
folderChevronSpan: this.isFolder
}
},
setSelected: function() {
if (this.selectedNode.length > 0 && this.selectedNode[0].title == this.model.name)
return true;
else
return false;
}
},
methods: {
toggle: function() {
if (this.isFolder) {
this.open = !this.open
this.$refs.toggler.focus();
}
},
changeType: function() {
if (!this.isFolder) {
Vue.set(this.model, 'children', [])
this.addChild()
this.open = true
}
},
addChild: function() {
this.model.children.push({
name: 'new stuff'
})
},
selectNode: function() {
this.selectedNode = [];
this.selectedNode.push({
'title': this.model.name,
'isSelected': true
});
}
}
})
// boot up the demo
var demo = new Vue({
el: '#demo',
data: {
treeData: data
}
})
body {
font-family: Menlo, Consolas, monospace;
color: #444;
}
.item {
cursor: pointer;
}
.folderTitleSpan:hover {
font-weight: bold;
border: 1px solid darkblue;
}
.folderTitleSpan:focus,
li span:nth-child(1):focus+.folderTitleSpan {
background-color: darkblue;
color: white;
}
.node,
.add {
list-style-type: none;
padding-left: 10px !important;
}
.folderChevronSpan::before {
color: #444;
content: '\25b6';
font-size: 10px;
margin-left: -1em;
position: absolute;
transition: -webkit-transform .1s ease;
transition: transform .1s ease;
transition: transform .1s ease, -webkit-transform .1s ease;
-webkit-transition: -webkit-transform .1s ease;
}
.folderChevronSpan.opened::before {
transform: rotate(90deg);
-webkit-transform: rotate(90deg);
}
ul {
padding-left: 1em;
line-height: 1.5em;
list-style-type: dot;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17-beta.0/vue.js"></script>
<!-- item template -->
<script type="text/x-template" id="item-template">
<li>
<span :class="setChevronClass" tabindex="0" ref="toggler" @click="toggle">
</span>
<span @click="selectNode" tabindex="1" :class="{folderTitleSpan: isFolder}">
{{ model.name }}
</span>
<span v-if="isFolder">[{{ open ? '-' : '+' }}]</span>
<ul v-show="open" v-if="isFolder">
<item class="item node" v-for="(model, index) in model.children" :key="index" :model="model">
</item>
<li class="add" @click="addChild">+</li>
</ul>
</li>
</script>
<p>(You can double click on an item to turn it into a folder.)</p>
<!-- the demo root element -->
<ul id="demo">
<item class="item node" :model="treeData">
</item>
</ul>
推荐阅读
- c# - 在 C# 中检索网络共享权限的问题
- java - spring 如何使用 localhost 而不是 localhost IP?
- r - gsub 匹配后的第一个单词
- java - 如何将麦克风音频流式传输到同一设备抛出扬声器
- wso2 - 构建WSO2 EI 6.5.0的源代码
- facebook - Facebook webhook,如何从中间 id 获取对话 id
- javascript - 在片段中加载 jQuery 并将元素添加到空白页面
- c# - 无法将要分配的类实例声明为库函数的输出参数
- javascript - 2个数组中的反应对象
- mysql - 选择分配给用户的具有有限权限的所有用户的进程列表