[Element-UI] Realize dynamic tree, data table and paging effects

1. Introduction

1 Introduction

        In modern software development, dynamic trees, data tables , and paging effects have become core requirements for many applications . As business scale and complexity increase, we often need to display a large amount of hierarchical structure data and implement highly interactive and efficient operations.

        Dynamic trees provide a clearly organized and scalable display that allows users to easily view and manipulate tree nodes. Data tables present data in tabular form, in which users can sort, filter, edit and other operations.

        The paging effect can divide a large amount of data into one page or pages of content that is easy to manage and browse. The combination of these three functions not only allows us to better handle huge data collections, but also allows users to quickly locate the required information.

        This article will introduce how to use modern front-end technology to achieve dynamic trees, data tables and paging effects, thereby bringing a better user experience to your application.

2. Purpose

The main purposes of using Element UI to achieve dynamic trees, data tables and paging effects are as follows:

  1. Provide a beautiful and easy-to-use user interface : Element UI is a set of component libraries based on Vue.js. It provides a rich set of UI components and styles, which can help developers quickly build beautiful and easy-to-use user interfaces. By using Element UI, we can provide a unified and consistent appearance and interactive experience for functions such as dynamic trees, data tables, and paging, making users feel comfortable and happy.
  2. Rapid development and customization capabilities : Element UI provides a rich variety of predefined components and styles, so that developers do not need to build these functions from scratch, but can directly use existing components to achieve dynamic trees, data tables, and paging effects. . In addition, Element UI also supports flexible customization options and theme configurations, and can carry out personalized design and style modifications according to specific project needs, saving development time and costs.
  3. Highly scalable and maintainable : Element UI's component library has been verified by a large number of actual projects. It has a stable architecture and excellent code quality, and is easy to maintain and expand. By using Element UI, we can use predefined components and APIs, combined with custom business logic, to build complex dynamic trees, data tables, and paging functions. At the same time, Element UI also provides rich documentation and community resources to facilitate developers to find problems and share experiences.

2. Dynamic tree

Create a dynamic tree effect we want based on the data in our database

1. Backend data interface definition

Under the sql of the data, that is, in the sqlxml file of the tree menu

<resultMap id="BaseResultMap" type="com.zking.ssm.model.Module" >
      <id column="id" jdbcType="INTEGER" property="id" />
      <result column="pid" jdbcType="INTEGER" property="pid" />
      <result column="text" jdbcType="VARCHAR" property="text" />
      <result column="icon" jdbcType="VARCHAR" property="icon" />
      <result column="url" jdbcType="VARCHAR" property="url" />
      <result column="sort" jdbcType="INTEGER" property="sort" />
      <collection property="modules" ofType="com.zking.ssm.model.Module"
                  column="id" select="queryChildNodeByPid"/>
</resultMap>
<sql id="Base_Column_List" >
    id, pid, text, icon, url, sort
</sql>
<!--先根据id查询菜单根级目录,再利用上次查询结果collection中column的值id作为递归查询条件,查出所有子菜单,返回结果必须为resultMap,并且值为上面构建的resultMap的id值-->
<select id="queryChildNodeByPid" resultMap="BaseResultMap" parameterType="int">
    select <include refid="Base_Column_List"/> from t_module_vue
    where pid=#{value}
</select>

Controller layer

    @RequestMapping("/queryRootNode")
    @ResponseBody
    public JsonResponseBody<List<Module>> queryRootNode(){
        try {
            List<Module> modules = moduleService.queryRootNode(-1);
            return new JsonResponseBody<>("OK",true,0,modules);
        } catch (Exception e) {
            e.printStackTrace();
            return new JsonResponseBody<>("初始化首页菜单错误",false,0,null);
        }
    }

2. Front-end navigation menu binding

2.1. Page layout

Menu structure

<!--  添加动态路由:router :default-active="$route.path"-->
  <el-menu router :default-active="$route.path" default-active="2" class="el-menu-vertical-demo"
           background-color="#334157"
           text-color="#fff" active-text-color="#ffd04b" :collapse="collapsed">
    <!-- <el-menu default-active="2" :collapse="collapsed" collapse-transition router :default-active="$route.path" unique-opened class="el-menu-vertical-demo" background-color="#334157" text-color="#fff" active-text-color="#ffd04b"> -->
    <div class="logobox">
      <img class="logoimg" src="../assets/img/logo.png" alt="">
    </div>
    <el-submenu v-for="m in menus" :index="'index_'+m.id" :key="'key_'+m.id">
      <template slot="title">
        <i :class="m.icon"></i>
        <span>{
   
   { m.text }}</span>
      </template>
      <el-menu-item v-for="m2 in m.modules" :index="m2.url" :key="'key_'+m2.id">
        <i :class="m2.icon"></i>
        <span>{
   
   { m2.text }}</span>
      </el-menu-item>
    </el-submenu>
  </el-menu>

The key attribute in the first-level node el-submenu is unique, the index attribute is unique, and the index attribute is used to control menu folding; the key attribute in
the second-level node el-menu-item is unique, the index attribute is unique, and the index attribute is used to control the page Jump;

The el-menu component of vue+element implements routing jump and setting of the current item

router :default-active="$route.path"
  1. To implement route jump, first add the router attribute to the el-menu tag, and then just set the URL in the index attribute of each el-menu-item tag to click el-menu-item to implement route jump.
  2. To navigate the current item, bind : default-active="$route.path" in the el-menu tag . Note that it is a binding attribute. Don't forget to add " : " when $route.path is equal to the el-menu-item tag . When the index attribute value is in, the item is the current item.
  3. The url attribute in the el-submenu tag cannot be empty and cannot be the same, otherwise it will cause the problem of multiple nodes having the same shrink/collapse effect.

2.2. Data binding

  created() {
    this.$root.Bus.$on('sjm', v => {
      this.collapsed = v;
    });
//树形菜单
    //后台访问地址
    let url = this.axios.urls.SYSTEM_MENUS;
    this.axios.get(url, {}).then(r => {
//利用数组接受后台的数据
      this.menus = r.data.rows;
    }).catch(error => {

    })

  }

2.3. Writing the routing binding page

Route binding

Jump page writing

Just do it according to your own needs

Effect

3. Data tables and paging

1. Backend data interface definition

package com.zking.ssm.controller;

import com.zking.ssm.model.Book;
import com.zking.ssm.service.IBookService;
import com.zking.ssm.util.JsonResponseBody;
import com.zking.ssm.util.PageBean;
import com.zking.ssm.vo.BookFileVo;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping("/book")
public class BookController {

    @Autowired
    private IBookService bookService;

    @RequestMapping("/queryBookPager")
    @ResponseBody
    public JsonResponseBody<List<Book>> queryBookPager(Book book, HttpServletRequest req){
        try {
            PageBean pageBean=new PageBean();
            pageBean.setRequest(req);
            List<Book> books = bookService.queryBookPager(book, pageBean);
            return new JsonResponseBody<>("OK",true,pageBean.getTotal(),books);
        } catch (Exception e) {
            e.printStackTrace();
            return new JsonResponseBody<>("分页查询书本失败",false,0,null);
        }
    }

 
}

2. Front-end

The prop attribute in the table must have the same attribute name as the back-end entity class, otherwise the data will not be displayed.

<template>
  <div class="Book" style="padding: 30px;">
    <!-- 输入框搜索 -->
    <el-form :inline="true" class="demo-form-inline">
      <el-form-item label="书籍名称 : ">
        <el-input v-model="bookname" placeholder="书籍名称"></el-input>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" plain @click="onSubmit">查询</el-button>
      </el-form-item>
    </el-form>
    <!-- 书籍的书籍表格 -->
    <el-table :data="tableData" style="width: 100%">
      <el-table-column prop="id" label="书籍ID"></el-table-column>
      <el-table-column prop="bookname" label="书籍名称"></el-table-column>
      <el-table-column prop="price" label="书籍价格"></el-table-column>
      <el-table-column prop="booktype" label="书籍类型"></el-table-column>
    </el-table>
    <!-- 分页 -->
    <div class="block" style="padding: 20px;">
      <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="page"
                     background :page-sizes="[10, 20, 30, 40]" :page-size="rows"
                     layout="total, sizes, prev, pager, next, jumper"
                     :total="total">
      </el-pagination>
    </div>
  </div>

</template>

<script>
export default {
  data() {
    return {
      bookname: '',
      tableData: [],
      rows: 10,
      total: 0,
      page: 1
    }
  },
  methods: {
    handleSizeChange(r) {
      //当页大小发生变化
      let params = {
        bookname: this.bookname,
        rows: r,
        page: this.page
      }
      this.query(params);
    },
    handleCurrentChange(p) {
      //当前页码大小发生变化
      let params = {
        bookname: this.bookname,
        rows: this.rows,
        // 分页
        page: p
      }
      // console.log(params)
      this.query(params);
    },
    query(params) {
      //获取后台请求书籍数据的地址
      let url = this.axios.urls.SYSTEM_BOOKLIST;
      this.axios.get(url, {
        params: params
      }).then(d => {
        this.tableData = d.data.rows;
        this.total = d.data.total;
      }).catch(e => {
      });
    },
    onSubmit() {
      let params = {
        bookname: this.bookname
      }
      console.log(params)
      this.query(params);
      this.bookname = ''
    }
  },
  created() {
    this.query({})
  }
}
</script>

<style>
</style>

Effect

Guess you like

Origin blog.csdn.net/weixin_74383330/article/details/133312260