春暖花会开,如果你曾经经历过冬天,那么你就会有春色!如果你正在付出,那么总有一天你会拥有花开满园。

之前的一篇文章已经讲解过如何实现el-tree和el-table的数据点击联动,以及右键可编辑树:【Vue入门实践】Element-UI 树形组件el-tree的组件封装 =>实现组织机构树Tree => 使用vue-content-menu定制可编辑树结构editableTree_Sabrina_cc的博客-CSDN博客

实现效果如图:


目录

一、概述实现效果

1.UI给出的页面设计样式

2.最终的前端 实现页面效果

二、实现基础资源树样式

1.el-tree和el-table实现联动

(1)el-tree和el-table调接口显示数据

(2)实现tree和table两者联动

2.添加文件前的文件夹图标 

三、实现资源树修改功能

1.实现思路

2.开发编辑情况时的前端效果

(1)实现文件资源树编辑情况

 (2)添加input的输入绑定

3.实现编辑效果

(1)区分被选中编辑的节点

(2)实现编辑的确认

4. 实现取消和删除功能

(1)取消功能的实现

(2)删除功能实现

四、其他前端效果

1.修改el-tree默认下拉图标的位置

2.名称过长缩略显示

3.部分节点有编辑删除功能

 五、类比实现el-table单元格的编辑功能


一、概述实现效果

1.UI给出的页面设计样式

2.最终的前端 实现页面效果

1. 【新增】点击文件夹后->点击新增,会在选中的文件夹下新建文件夹目录;如果选中‘全部’或者不选,则直接在全部目录下新建文件夹目录。

2.【删除】点击删除按钮,确认弹框后删除该文件夹

3.【编辑】点击对应文件夹的‘编辑’按钮后,变成input输入形式,点击对号确认后实现修改,点击‘取消’,退出编辑模式。

4.【缩略】文件夹名称过长时,显示缩略效果。

 看完效果让我们开始一步步实现吧:


二、实现基础资源树样式

1.el-tree和el-table实现联动

(1)el-tree和el-table调接口显示数据

使用到的两个接口分别是:listKnowledge, treeslect

// 查询应急知识 列表
export function listKonwledge(query) {
  return request({
    url: "/konwledge/info/list",
    method: "get",
    params: query
  });
}
// 查询文件下拉树结构
export function treeselect() {
  return request({
    url: "/knowledge/file/treeselect",
    method: "get"
  });
}

 接口返回的数据如下:

data() {
    return {
      // 应急知识 表格数据
      konwledgeList: [],
      total:'',
      //文件树
      fileOptions: undefined,
      defaultProps: {
        children: "children",
        label: "label",
      },
    }
}
created() {
    // 获取table数据
    this.getList();
    // 获取树列表
    this.getTreeselect();
},
methods: {
    // 查询列表
    getList() {
      listKonwledge(this.queryParams).then((response) => {
        this.konwledgeList = response.rows;
        this.total = response.total;
      });
    },
    // 查询树结构
    getTreeselect() {
      treeselect().then((response) => {
        this.fileOptions = response.data;
        console.log(response.data);
      });
    },
}

(2)实现tree和table两者联动

思路:对el-tree添加节点点击事件@node-click="handleNodeClick",并在该方法中获取节点的id,并作getList() 查询操作,从而实现两者联动

// tree节点单击事件
    handleNodeClick(data) {
      console.log(data, "handlenodeclick获取的数据,包含id;children;label");
      this.queryParams.parentId = data.id;
      this.getList();
    },

 全部完整代码如下:

 <div class="tree-container">
        <el-col :span="6" :xs="24">
          <el-tree
            :data="fileOptions"
            :props="defaultProps"
            :expand-on-click-node="false"
            :filter-node-method="filterNode"
            ref="tree"
            node-key="id"
            default-expand-all
            highlight-current
            @node-click="handleNodeClick"
          >
            <span class="custom-tree-node" slot-scope="{ node, data }">
              <span>
                <!-- 正常情况 -->
                <span v-if="data.id != operationVis">
                  <span>
                    {{ node.label }}
                  </span>
                  <span style="margin-left: 20px">
                    <el-button type="text" size="mini">
                      <i class="el-icon-edit"></i>
                    </el-button>
                    <el-button type="text" size="mini">
                      <i class="el-icon-delete" style="color: red"></i>
                    </el-button>
                  </span>
                </span>
              </span>
            </span>
          </el-tree></el-col
        >
        <el-col :span="18" :xs="24">
          <el-table
            v-loading="loading"
            :data="konwledgeList"
            @selection-change="handleSelectionChange"
            stripe
            class="tableBox"
            height="480"
            :default-sort="{ prop: 'uploadTime', order: 'descending' }"
          >
            <el-table-column type="selection" width="55" align="center" />
            <el-table-column
              label="序号"
              align="center"
              type="index"
              width="50"
            />

            <el-table-column
              label="文件名称"
              align="center"
              prop="fileName"
              width="300"
            >
              <template slot-scope="scope">
                <span style="margin-left: 20px">
                  {{ scope.row.fileName }}
                </span>
              </template>
            </el-table-column>
            <el-table-column
              label="上传时间"
              align="center"
              prop="uploadTime"
              width="130"
            >
              <template slot-scope="scope">
                <span>{{
                  parseTime(scope.row.uploadTime, "{y}年{m}月{d}日 {h}:{i}:{s}")
                }}</span>
              </template>
            </el-table-column>
            <el-table-column
              label="上传人"
              align="center"
              prop="uploadPerson"
              width="120"
            />
            <el-table-column
              label="上一级文件夹"
              align="center"
              prop="parentName"
            />
            <el-table-column
              label="操作"
              align="center"
              class-name="small-padding fixed-width"
            >
              <template slot-scope="scope">
                <el-button size="mini" type="text" @click="rename(scope.row)"
                  >重命名</el-button
                >
                <el-button
                  size="mini"
                  type="text"
                  @click="moveToOther(scope.row)"
                  >移动</el-button
                >

                <el-button
                  size="mini"
                  type="text"
                  @click="handleDelete(scope.row)"
                  >删除</el-button
                >
              </template>
            </el-table-column>
          </el-table>
          <pagination
            v-show="total > 0"
            :total="total"
            :page.sync="queryParams.pageNum"
            :limit.sync="queryParams.pageSize"
            @pagination="getList"
            layout="total, prev, pager, next"
          />
        </el-col>
      </div>

至此的效果如下:

2.添加文件前的文件夹图标 

分析:A.最外部的全部前面有一个定位图标;全部的id=100

B.如果文件夹节点是包含子节点的,那么就是文件夹图标;

C.如果资源是叶子节点,那么就是文件图标。

只需要在el-tree的span中添加如下代码

<span
    ><i
        class="el-icon-location"
        style="margin-right: 14px"
        v-if="data.id == 100 ? true : false"
     ></i>
     <i
         class="el-icon-folder-opened"
         style="margin-right: 14px"
         v-else-if="data.children != null ? true : false"
      ></i>
      <i
         class="el-icon-folder"
          style="margin-right: 14px"
          v-else
      ></i
></span>

三、实现资源树修改功能

1.实现思路

设计思路:

前端效果分成两种情况:A.文件资源树正常情况:label展示文件树节点名称;后面有编辑和删除的图标按钮

B.文件资源树编辑情况:input展示节点并实现可编辑输入效果;后面有确定和取消的图标按钮。

2.开发编辑情况时的前端效果

(1)实现文件资源树编辑情况

注释掉之前的span 文件资源树的正常情况,

            <span>
                  <el-input
                    style="width: 120px"
                    size="mini"
                  >
                  </el-input>
                  <span
                    style="margin-left: 20px"
                  >
                    <el-button
                      type="text"
                      size="mini"
                      @click="() => sureChange(data)"
                    >
                      <i
                        class="el-icon-circle-check"
                        style="color: rgb(19, 206, 102)"
                      ></i>
                    </el-button>
                    <el-button
                      type="text"
                      size="mini"
                      @click="() => chancelChange(node, data)"
                    >
                      <i class="el-icon-circle-close" style="color: gray"></i>
                    </el-button>
                  </span>
                </span>

 (2)添加input的输入绑定

但是我们会发现这时的input是无法输入的,需要使用:value绑定,而不是使用:model

并且添加input输入的事件,从而实现输入绑定

<el-input
     style="width: 120px"
     size="mini"
     ref="inputVal"
     :value="data.label"
     @focus="focus($event)"
     @input="(a) => inp(a, data)"
    >
</el-input>
focus(event) {},
inp(value, data) {
    data.label = value;
},

 至此,我们实现了这样的效果,可以在input中修改

3.实现编辑效果

(1)区分被选中编辑的节点

我们这一步需要结合两种情况,实现点击编辑按钮,对应的节点变成可编辑情况,但是未选中的节点不变

A. 如何区分哪个节点是选中的呢??

方法:记录点击选中的节点的id,对于每个节点data.id都与此记录的临时operationVis做对比即可。

B. 在何处记录这个选中的节点??

在点击编辑按钮事件editFile时,记录选中节点     this.operationVis = data.id;

// 编辑按钮
    editFile(data) {
      this.operationVis = data.id;
    },

C. 如何区分一般情况和可编辑情况?

在点击编辑时添加标记data.id != operationVis,并在取消或者确认修改之后 this.operationVis = "";

<!-- 正常情况 -->
<span v-if="data.id != operationVis">
                  .....
</span>
</span>
<!-- 编辑情况 -->
<span v-else>
                ....
 </span>

  el-tree的完整代码如下:

<el-tree
            :data="fileOptions"
            :props="defaultProps"
            :expand-on-click-node="false"
            :filter-node-method="filterNode"
            ref="tree"
            node-key="id"
            default-expand-all
            highlight-current
            @node-click="handleNodeClick"
          >
            <span class="custom-tree-node" slot-scope="{ node, data }">
              <span>
                <span
                  ><i
                    class="el-icon-location"
                    style="margin-right: 14px"
                    v-if="data.id == 100 ? true : false"
                  ></i>
                  <i
                    class="el-icon-folder-opened"
                    style="margin-right: 14px"
                    v-else-if="data.children != null ? true : false"
                  ></i>
                  <i
                    class="el-icon-folder"
                    style="margin-right: 14px"
                    v-else
                  ></i
                ></span>
                <!-- 正常情况 -->
                <span v-if="data.id != operationVis">
                  <span>
                    {{ node.label }}
                  </span>
                  <span style="margin-left: 20px">
                    <el-button
                      type="text"
                      size="mini"
                      @click="() => editFile(data)"
                    >
                      <i class="el-icon-edit"></i>
                    </el-button>
                    <el-button
                      type="text"
                      size="mini"
                      @click="() => remove(node, data)"
                    >
                      <i class="el-icon-delete" style="color: red"></i>
                    </el-button>
                  </span>
                </span>
                <!-- 编辑情况 -->
                <!--  -->
                <span v-else>
                  <el-input
                    style="width: 120px"
                    size="mini"
                    ref="inputVal"
                    :value="data.label"
                    @focus="focus($event)"
                    @input="(a) => inp(a, data)"
                  >
                  </el-input>
                  <span
                    style="margin-left: 20px"
                    v-if="data.id != 100 ? true : false"
                  >
                    <el-button
                      type="text"
                      size="mini"
                      @click="() => sureChange(data)"
                    >
                      <i
                        class="el-icon-circle-check"
                        style="color: rgb(19, 206, 102)"
                      ></i>
                    </el-button>
                    <el-button
                      type="text"
                      size="mini"
                      @click="() => chancelChange(node, data)"
                    >
                      <i class="el-icon-circle-close" style="color: gray"></i>
                    </el-button>
                  </span>
                </span>
              </span>
            </span> </el-tree
        >

(2)实现编辑的确认

接口:

// 更新文件夹名称
export function updateKonwledgeFile(data) {
  return request({
    url: "/knowledge/file",
    method: "put",
    data: data
  });
}
 sureChange(data) {
      console.log(data, "点击确认修改");
      const params = {
        fileName: data.label,
        fileId: data.id,
      };
      debugger;
      updateKonwledgeFile(params).then((response) => {
        if (response.code == 200) {
          this.msgSuccess("修改成功");
          this.operationVis = "";
          this.getTreeselect();
        }
        this.folderFlag = false;
      });
    },

  

至此实现了编辑功能,效果如下:

4. 实现取消和删除功能

(1)取消功能的实现

<el-button
      type="text"
      size="mini"
       @click="() => chancelChange(node, data)"
       >
       <i class="el-icon-circle-close" style="color: gray"></i>
</el-button>
// 取消修改按钮
    chancelChange() {
      this.operationVis = false;
    },

(2)删除功能实现

<el-button
    type="text"
    size="mini"
    @click="() => remove(node, data)"
>
     <i class="el-icon-delete" style="color: red"></i>
</el-button>
// 文件夹节点删除
    remove(node, data) {
      this.formFolder.parentId = data.id;
      console.log(data, node, "remove节点获取到的信息");
      this.handleFolderDelete(data.id, data.label);
    },

四、其他前端效果

1.修改el-tree默认下拉图标的位置

一般下拉框是在左侧,如果实在想要修改位置,可以使用如下代码。个人觉得并不好看,哈哈

// 修改下拉图标的位置
::v-deep .el-tree-node__expand-icon {
  position: absolute;
  right: 2%;
}
::v-deep .el-tree-node__label {
  padding-left: 15px;
}

2.名称过长缩略显示

对于正常情况需要分情况:A.字符串长度短:正常显示

B.字符串长度过长,使用el-popover 并截取前十个字符显示

3.部分节点有编辑删除功能

其实‘全部’节点不可编辑,因此也需要使用v-if判断是否为‘全部’节点v-if="data.id != 100 ? true : false"

<!-- 正常情况 -->
<span v-if="data.id != operationVis">
                  <el-popover
                    placement="top-start"
                    trigger="hover"
                    v-if="node.label.length > 8"
                  >
                    <div>{{ node.label }}</div>
                    <span slot="reference">
                      <a>{{ node.label.substr(0, 7) + "..." }}</a></span
                    >
                  </el-popover>
                  <span v-else>
                    {{ node.label }}
                  </span>
                  <span
                    style="margin-left: 20px"
                    v-if="data.id != 100 ? true : false"
                  >
                    <el-button
                      type="text"
                      size="mini"
                      @click="() => editFile(data)"
                    >
                      <i class="el-icon-edit"></i>
                    </el-button>
                    <el-button
                      type="text"
                      size="mini"
                      @click="() => remove(node, data)"
                    >
                      <i class="el-icon-delete" style="color: red"></i>
                    </el-button>
                  </span>
                </span>

 五、类比实现el-table单元格的编辑功能

点击重命名按钮触发修改模式

实现原理一致,附代码,大家可以自行学习。

<el-table-column
            label="文件名称"
            align="center"
            prop="fileName"
            width="300"
          >
            <!-- show-overflow-tooltip="true" -->
            <template slot-scope="scope">
              <span style="margin-left: 20px">
                <!-- 未编辑情况 -->
                <el-popover
                  placement="top-start"
                  trigger="hover"
                  v-show="
                    scope.row.id != renameId && scope.row.fileName.length > 15
                  "
                >
                  <div>{{ scope.row.fileName }}</div>
                  <span slot="reference" @click="handleDownload(scope.row)">
                    <a style="color: rgb(24, 144, 255)">{{
                      scope.row.fileName.substr(0, 14) + "..."
                    }}</a></span
                  >
                </el-popover>
                <span
                  v-show="
                    scope.row.id != renameId && scope.row.fileName.length < 15
                  "
                >
                  <el-button type="text" @click="handleDownload(scope.row)">{{
                    scope.row.fileName
                  }}</el-button>
                </span>
                <!-- 修改情况 -->
                <span v-show="scope.row.id == renameId"
                  ><el-input
                    v-model="scope.row.fileName"
                    @input="(a) => inpFile(a, scope.row)"
                    style="width: 210px"
                    type="small"
                  ></el-input>
                  <el-button
                    type="text"
                    size="mini"
                    style="margin-left: 8px"
                    @click="() => changeFile(scope.row)"
                  >
                    <i
                      class="el-icon-circle-check"
                      style="color: rgb(19, 206, 102)"
                    ></i>
                  </el-button>
                  <el-button type="text" size="mini">
                    <i
                      class="el-icon-circle-close"
                      style="color: gray"
                      @click="() => cancelFile(scope.row)"
                    ></i> </el-button
                ></span>
              </span>
            </template>
          </el-table-column>

对应资源源码下载:可编辑el-tree样式功能修改:修改icon、可编辑input、修改下拉展开icon位置-Javascript文档类资源-CSDN下载 

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐