惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Jina AI
Jina AI
S
SegmentFault 最新的问题
D
DataBreaches.Net
H
Help Net Security
有赞技术团队
有赞技术团队
M
MIT News - Artificial intelligence
Martin Fowler
Martin Fowler
IT之家
IT之家
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
腾讯CDC
罗磊的独立博客
Y
Y Combinator Blog
阮一峰的网络日志
阮一峰的网络日志
云风的 BLOG
云风的 BLOG
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
WordPress大学
WordPress大学
Microsoft Security Blog
Microsoft Security Blog
J
Java Code Geeks
Vercel News
Vercel News
Hugging Face - Blog
Hugging Face - Blog
aimingoo的专栏
aimingoo的专栏
Stack Overflow Blog
Stack Overflow Blog
Recent Announcements
Recent Announcements
博客园 - 三生石上(FineUI控件)

时间的朋友

Windows 命令行密码重置 Anaconda安装 typescript 注解解读1 Konvajs Shape加载自定义图片 sshpass 使用 why-is-node-running webgl笔记 SharedArrayBuffer is not defined blender 常用快捷键 | 时间的朋友 vue -- v3.4commit提交记录2 vue2 升级vue3报错问题整理 着色器 expressjs 源码 hyper-V arch linux 网络配置 element input数字格式化 three 拼接货架 WebAudio笔记 Windows nginx重启bat脚本 vue -- v3.4commit提交记录 URI malformed vue3 -- Class 对象在组件中使用范例 | 时间的朋友 ruby 安装和升级 element-plus 老版本cascader使用卡死问题 vue3 内置Transition组件 | 时间的朋友 前端memo的实现 | 时间的朋友 Vue -- vue-class-component源码 | 时间的朋友 linux 优化脚本 typescript 装饰器 | 时间的朋友 microbundle 源码 | 时间的朋友 WSL2问题解决WslRegisterDistribution failed with error: 0x800701bc
vue -- 实现MenuTree组件 | 时间的朋友
2022-08-08 · via 时间的朋友

Published: · LastMod: August 09, 2022 · 1355 words

样例 🔗

image.png

具体实现 🔗

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
<template>
  <div class="Tree-content">
    <div
      v-for="(item, idx) in computedTree"
      :key="idx"
      :class="{
        'Tree-Title': true,
        'Tree-SecondLevelTitle': item.$depth > 0,
        'Tree-FirstLevelTitle': item.$depth == 0,
        active: item.id === computedValue,
      }"
    >
      <div class="Tree-Item" @click="onHandleClick(item)">
        <div class="Tree-ItemTxt">{{ item[computedFieldNames.label] }}</div>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: "menu-tree",
  model: {
    prop: "value",
    event: "change",
  },
  props: {
    options: {
      type: Array,
      default: () => [],
    },
    value: [String, Number],
    fieldNames: {
      type: Object,
    },
  },
  computed: {
    computedValue: {
      get() {
        return this.value;
      },
      set(row) {
        this.$emit("change", row.id);
      },
    },
    computedTree() {
      return this.genTree([...this.options]);
    },
    computedFieldNames() {
      return {
        children: "children",
        label: "label",
        key: "key",
        ...(this.fieldNames || {}),
      };
    },
  },
  methods: {
    onHandleClick(row) {
      this.$emit("change", row.id);
    },
    genTree(tree = []) {
      const data = [];
      if (tree.length > 0) {
        this._doLoopTreeWithDepth(tree, 0, data);
      }
      return data;
    },
    _doLoopTreeWithDepth(list, depth = 0, data = []) {
      list.forEach((el, idx) => {
        el.$depth = depth;
        if (!el.id) {
          el.id = `t-${depth}-${idx}`;
        }
        data.push(el);
        if (el[this.computedFieldNames.children]) {
          this._doLoopTreeWithDepth(
            el[this.computedFieldNames.children],
            depth + 1,
            data
          );
        }
      });
    },
  },
};
</script>

<style lang="scss" scoped>
@mixin dot {
  content: " ";
  position: absolute;
  background-color: rgb(133, 144, 166);
  display: inline-block;
  border-radius: 50%;
  top: 12px;
  margin-right: 12px;
}
.Tree {
  &-content {
    box-sizing: border-box;
    margin: 0px;
    min-width: 0px;
    flex-direction: column;
    font-size: 12px;
    display: flex;
  }

  &-Title {
    box-sizing: border-box;
    margin: 0px;
    min-width: 0px;
    flex-shrink: 0;
    display: flex;
    -webkit-box-align: center;
    align-items: center;
    color: rgb(133, 144, 166);
    font-size: 12px;
    padding-left: 30px;
    font-weight: 500;
    position: relative;
    height: 30px;
    line-height: 30px;
  }

  &-FirstLevelTitle::before {
    @include dot;
    left: 16px;
    width: 6px;
    height: 6px;
  }
  &-SecondLevelTitle::before {
    @include dot;
    left: 17px;
    width: 4px;
    height: 4px;
  }
  &-FirstLevelTitle,
  &-SecondLevelTitle {
    &::after {
      content: " ";
      display: block;
      position: absolute;
      left: 19px;
      top: 0px;
      transform: translateX(-50%);
      width: 2px;
      height: 40px;
      margin-top: 12px;
      background: rgba(133, 144, 166, 0.12);
    }
    &.active {
      color: rgb(0, 102, 255);
    }
    &.active::before {
      background-color: rgb(0, 102, 255);
    }
  }
  &-Title:last-child::after {
    height: 0px;
  }
  &-Item {
    box-sizing: border-box;
    margin: 0px;
    min-width: 0px;
    padding-left: 10px;
    padding-right: 10px;
    display: flex;
    cursor: pointer;
    -webkit-box-align: center;
    align-items: center;
    width: 100%;

    &:hover {
      color: rgb(0, 102, 255);
      background: rgb(235, 235, 235);
      border-radius: 4px;
    }
  }

  &-ItemTxt {
    box-sizing: border-box;
    margin: 0px;
    min-width: 0px;
    display: -webkit-box;
    text-overflow: ellipsis;
    overflow: hidden;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 1;
    pointer-events: none;
    word-break: break-all;
    width: calc(100% - 22px);
  }
}
</style>

使用方法 🔗

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
<template>
  <div class="css-box">
    <side-tree v-model="value" :options="tree" @change="onClick"></side-tree>
  </div>
</template>

<script>
import SideTree from "./side-tree.vue";
export default {
  components: {
    SideTree,
  },
  data() {
    return {
      value: 't-1-2',
      tree: [
        {
          label: "零、基础知识",
        },
        {
          label: "一、安装VScode编辑器和MinGW编译器",
          children: [
            {
              label: "1.VScode编辑器",
            },
            {
              label: "1.2.安装VScode扩展插件",
            },
            {
              label: "2.MinGW编译器编译器",
            },
            {
              label: "2.1.下载编译器",
            },
            {
              label: "2.2.安装编译器",
            },
            {
              label: "2.3.编译器验证",
            },
          ],
        },
        {
          label: "二、程序文件的架构",
          children: [
            {
              label: "1.语言学习环境",
            },
            {
              label: "1.1单文件编译运行调试",
            },
            {
              label: "1.2简单多文件编译运行调试",
            },
            {
              label: "2.实际项目开发环境",
            },
          ],
        },
        {
          label: "三、配置一个新项目",
          children: [
            {
              label: "1.创建配置c_cpp_properties.json文件",
            },
            {
              label: "2.创建配置tasks.json文件",
            },
            {
              label: "3.创建配置launch.json文件",
            },
          ],
        },
        {
          label: "四、一些小tips",
          children: [
            {
              label: "1.多文件编译",
            },
            {
              label: "2.中文乱码",
            },
          ],
        },
      ],
    };
  },
  methods: {
    onClick(row) {
      console.log(row);
    },
  },
};
</script>

<style  lang="scss" scoped>
.css-box {
  width: 250px;
  box-sizing: border-box;
  margin: 20px 0px 0px;
  min-width: 0px;
  height: 600px;
  overflow: scroll;
}
</style>

prop 🔗

参数说明类型
v-model值双向绑定string|number
value当前值string|number
options需要展示的树形数据
fieldNames绑定数据的属性值object| {children: “children”,label: “label”,key: “key”, }