vue jsx tree 簡單組件

使用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;
  }

}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章