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

推荐订阅源

博客园 - Franky
Apple Machine Learning Research
Apple Machine Learning Research
月光博客
月光博客
Vercel News
Vercel News
Recent Announcements
Recent Announcements
B
Blog RSS Feed
Y
Y Combinator Blog
M
MIT News - Artificial intelligence
MongoDB | Blog
MongoDB | Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
雷峰网
雷峰网
D
Docker
Jina AI
Jina AI
IT之家
IT之家
人人都是产品经理
人人都是产品经理
L
LangChain Blog
G
Google Developers Blog
Google DeepMind News
Google DeepMind News
MyScale Blog
MyScale Blog
博客园 - 叶小钗
The GitHub Blog
The GitHub Blog
The Cloudflare Blog
A
About on SuperTechFans
Hugging Face - Blog
Hugging Face - Blog

时间的朋友

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”, }