使用Jsx實現一個簡單的tree視圖,目標樣式:demo
引入樣式中可能會污染已有的樣式,所以在最外層包裹了一個樣式名
使用了antdv的form組件
代碼:
const SimpleTreeView = {
name: 'SimpleTreeView',
props: {
data: {
type: Array,
default () {
return []
}
},
title: {
type: String,
default: '樹形視圖'
}
},
data () {
return {
treeForm: this.$form.createForm(this)
}
},
render (h) {
const { data, title } = this.$props
const formModelProps = {
model: this.treeForm
}
return (
<a-form class='sptv' {...{ props: formModelProps }}>
<h3 class="title">{title}</h3>
<ul class="sptree">
{this.getList(data)}
</ul>
</a-form>
)
},
methods: {
getList (dt = []) {
let item = []
if (dt.length > 0) {
item = dt.map(d => {
return (
<li>
<span>
<a-row>
<a-col span={8}>{d.title}</a-col>
<a-col span={16}>
<a-form-item>
{
this.treeForm.getFieldDecorator(`${d.key}`, {
initialValue: d.data.filter(f => f.checked).map(m => m.id)
})(
<a-checkbox-group
options={d.data.map(m => {
return {
label: m.name,
value: m.id
}
})}
/>
)
}
</a-form-item>
</a-col>
</a-row>
</span>
{d.children && d.children.length > 0
? <ul>
{this.getList(d.children)}
</ul> : null}
</li>
)
})
}
return item
}
}
}
export default SimpleTreeView
樣式類:
@border: #ddd;
@border-hover: #aaa;
@bg-hover: #eee;
@text: #888;
@text-hover: #000;
@ident: 20px;
@left: -(@ident);
.sptv {
ul {
margin-left: @ident;
}
.title {
font-weight: bold;
}
.sptree {
li {
list-style-type: none;
margin: 6px 0 6px 10px;
position: relative;
&:before {
content: "";
position: absolute;
top: -6px;
left: -20px;
border-left: 1px solid #ddd;
border-bottom: 1px solid #ddd;
width: 20px;
height: 20px;
}
&:after {
position: absolute;
content: "";
top: 5px;
left: @left;
border-left: 1px solid @border;
width: @ident;
height: 100%;
}
&:last-child:after {
display: none;
}
& > span {
display: block;
border: 1px solid @border;
padding: 2px;
color: @text;
text-decoration: none;
}
}
}
.sptree {
li {
& > span {
&:hover,
&:focus {
background: @bg-hover;
color: @text-hover;
border: 1px solid @border-hover;
& + ul {
li {
& > span {
background: @bg-hover;
color: @text-hover;
border: 1px solid @border-hover;
}
}
}
}
&:hover + ul,
&:focus + ul {
& > li {
&:after,
&:before {
border-color: @border-hover;
}
}
}
}
}
}
.ant-form-item {
margin-bottom: 0;
}
.ant-form-item-control {
line-height: normal;
}
}