前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >浅学前端:Vue篇(二)

浅学前端:Vue篇(二)

原创
作者头像
传说之下的花儿
发布2023-11-12 17:31:45
2210
发布2023-11-12 17:31:45
举报

2. Vue 进阶

1) ElementUI

ElementUI是基于vue的一套组件库,前面讲述了如何自己去创建组件,但是自己创建组件成本太高了,所以我们一般都是采用一些第三方的比较成熟的组件库,ElementUI就是其中一中,使用之后可以大大减少我们的开发成本。

安装

代码语言:javascript
复制
 npm install element-ui -S

引入组件

引入的方式有很多种,这里就介绍个最简单的,引入所有的组件

放在main.js中

代码语言:javascript
复制
 import Element from 'element-ui' // 导入ElementUI组件
 import 'element-ui/lib/theme-chalk/index.css' // 导入他的一些样式
 ​
 // 之前我们自己使用组件的时候,我们是给options对象里的components去加组件
 // 但是ElementUI里的组件太多了,个数大于有几十种,如果一个个去加,太麻烦了,
 // 所以使用了另外一个手段vue的use方法,将Element对象传入,就会把所有Element的组件加入到内部去,以后在页面里就可以直接使用相关标签了
 Vue.use(Element)

测试,在自己的组件中使用 ElementUI 的组 件

代码语言:javascript
复制
 <!-- ElementUI测试 -->
 <template>
     <div>
         <el-button>点我</el-button>
     </div>
 </template>
 <script>
     export default {}
 </script>

使用:

ElementUI用啥找啥就行,参考官网的例子。

1. 表格组件

具体属性见:https://element.eleme.cn/#/zh-CN/component/table

代码语言:javascript
复制
 <template>
     <div>
         <!-- data属性:关联表格需要展示的数据 -->
         <el-table v-bind:data="students">
             <!-- lable属性:这个列的标题 -->
             <!-- prop属性:表格内部会遍历这个学生数组,那么学生对象的哪个属性需要显示在这一列上就使用到了prop -->
             <el-table-column label="编号" prop="ID"></el-table-column>
             <el-table-column label="姓名" prop="Name"></el-table-column>
             <el-table-column label="性别" prop="Sex"></el-table-column>
             <el-table-column label="年龄" prop="Age"></el-table-column>
         </el-table>
     </div>
 </template>
 <script>
 import axios from 'axios';
 export default {
     data: function () {
         return {
             "students": []
         };
     },
     mounted: async function () {
         const resp = await axios.get("/api/students")
         this.students = resp.data.data
     }
 };
 </script>

2. 分页组件

具体使用见:https://element.eleme.cn/#/zh-CN/component/pagination

分页常用的属性:

代码语言:javascript
复制
 <template>
     <div>
         <!-- 分页常用属性:
             total属性:总条目数 
             page-size:每页显示条目个数,默认10条
             current-page:当前页数
             layout:控制分页条外观,
                 分页条可以看成由多个小的部分组成的
                 (比如:向上翻,向下翻,页码,跳转到第几页的数框,总记录数...)
                 这个layout就可以控制这些部分哪些显示,哪些不显示
                 默认是'prev, pager, next, jumper, ->, total'都显示
                 可选参数:sizes, prev, pager, next, jumper, ->, total, slot
             page-sizes:每页显示个数选择器的选项设置,默认:[10, 20, 30, 40, 50, 100]
         -->
         <el-pagination v-bind:total="50" v-bind:page-size="5" layout="prev, pager, next, sizes, ->, total"></el-pagination>
     </div>
 </template>
 <script>
 export default {};
 </script>

有人可能会好奇为什么有的属性加了v-bind,有的没有呢? 加了v-bind,就代表他的值来自于JavaScript,如果在option的data()返回的对象里找不到对应的绑定属性,就会将右侧当成表达式进行解析; 没有加:的,等号右边的值就是他的最终结果。 例子: :page-sizes="[5,10,15,20]"如果加了:会正常解析成数组,但是如果没加:,就会当做字符串,而不是解析成数组。

分页常用的事件:

示例:

代码语言:javascript
复制
 <template>
     <div>
         <!-- data属性:关联表格需要展示的数据 -->
         <el-table v-bind:data="students">
             <!-- lable属性:这个列的标题 -->
             <!-- prop属性:表格内部会遍历这个学生数组,那么学生对象的哪个属性需要显示在这一列上就使用到了prop -->
             <el-table-column label="编号" prop="ID"></el-table-column>
             <el-table-column label="姓名" prop="Name"></el-table-column>
             <el-table-column label="性别" prop="Sex"></el-table-column>
             <el-table-column label="年龄" prop="Age"></el-table-column>
         </el-table>
         <!-- 分页常用事件:
             事件名称                说明              回调参数
             current-change  currentPage 改变时会触发     当前页
             size-change     pageSize 改变时会触发     每页条数
         -->
         <el-pagination 
                        v-bind:total="total" 
                        v-bind:page-size="queryPage.pageSize"
                        v-bind:current-page="queryPage.currentPage" 
                        v-on:current-change="currentChange"
                        v-on:size-change="sizeChange" 
                        v-bind:page-sizes="[2,3,5,7]"
             layout='prev, pager, next, sizes,jumper, ->, total'>
         </el-pagination>
     </div>
 </template>
 <script>
 import axios from 'axios';
 export default {
     data: function () {
         return {
             total: 0,
             students: [],
             queryPage: {
                 pageSize: 5, // 页大小
                 currentPage: 1, // 页码
             },
         };
     },
     methods: {
         currentChange(page) {
             this.queryPage.currentPage = page;
             this.queryStudents()
         },
         sizeChange(size) {
             this.queryPage.pageSize = size;
             this.queryStudents()
         },
         async queryStudents() {
             const resp = await axios.get("/api/students", {
                 params: this.queryPage,
             })
             this.students = resp.data.data.students;
             this.total = resp.data.data.total;
         },
     },
     mounted: function () {
         this.queryStudents()
     }
 };
 </script>
  • 三种情况都应该触发查询
    • mounted 组件挂载完成后
    • 页号变化时
    • 页大小变化时
  • 查询传参应该根据后台需求,灵活采用不同方式
    • 本例中因为是 get 请求,无法采用请求体,只能用 params 方式传参
  • 返回响应的格式也许会很复杂,需要掌握【根据返回的响应结构,获取数据】的能力
3. 分页搜索
  1. 按姓名模糊搜索
  2. 按性别精确搜索
  3. 按年龄范围查询
代码语言:javascript
复制
 <template>
     <div>
         <!-- 输入框 -->
         <el-input placeholder="请输入姓名" v-model="queryDto.name"></el-input>
         <!-- 下拉列表 -->
         <el-select placeholder="请选择性别" v-model="queryDto.sex" clearable>
             <el-option value="男"></el-option>
             <el-option value="女"></el-option>
         </el-select>
         <!-- 下拉列表 -->
         <!-- label:展示给用户看的样子 -->
         <el-select placeholder="请选择年龄" v-model="queryDto.age" clearable>
             <el-option value="0,18" label="0到18岁"></el-option>
             <el-option value="19,30" label="19到30岁"></el-option>
             <el-option value="31,40" label="31到40岁"></el-option>
             <el-option value="41,120" label="41到120岁"></el-option>
         </el-select>
 ​
         <el-button type="primary" v-on:click="search()">搜索</el-button>
 ​
         <el-table v-bind:data="students">
             <el-table-column label="编号" prop="ID"></el-table-column>
             <el-table-column label="姓名" prop="Name"></el-table-column>
             <el-table-column label="性别" prop="Sex"></el-table-column>
             <el-table-column label="年龄" prop="Age"></el-table-column>
         </el-table>
         <el-pagination v-bind:total="total" v-bind:page-size="queryDto.pageSize"
             v-bind:current-page="queryDto.currentPage" v-on:current-change="currentChange" v-on:size-change="sizeChange"
             v-bind:page-sizes="[2,3,5,7]" layout='prev, pager, next, sizes,jumper, ->, total'>
         </el-pagination>
     </div>
 </template>
 <script>
 import axios from 'axios';
 export default {
     data: function () {
         return {
             total: 0,
             students: [],
             queryDto: {
                 pageSize: 5, // 页大小
                 currentPage: 1, // 页码
                 name: '',
                 sex: '',
                 age: ''
             },
         };
     },
     methods: {
         currentChange(page) {
             this.queryDto.currentPage = page;
             this.queryStudents()
         },
         sizeChange(size) {
             this.queryDto.pageSize = size;
             this.queryStudents()
         },
         async queryStudents() {
             const resp = await axios.get("/api/students", {
                 params: this.queryDto,
             })
             this.students = resp.data.data.students;
             this.total = resp.data.data.total;
         },
         search() {
             this.queryStudents()
         }
     },
     mounted: function () {
         this.queryStudents()
     },
 };
 </script>
4. Cascader 级联选择器

级联选择器中选项的数据结构为:

代码语言:javascript
复制
 <!-- 多级菜单 -->
 <template>
     <div>
         <el-cascader v-bind:options="ops"></el-cascader>
     </div>
 </template>
 <script>
     export default {
         data:function(){
             return {
                 // 多级菜单的数据
                 ops:[
                     {value:100,label:'主页',children:[
                         {value:101,label:'菜单1',children:[
                             {value:105,label:'子项1'},
                             {value:106,label:'子项2'},
                         ]},
                         { value: 102, label: '菜单2', children: [
                             {value:107,label:'子项3'},
                             {value:108,label:'子项4'},
                             {value:109,label:'子项5'},
                         ]},
                         { value: 103, label: '菜单3', children: [
                             {value:110,label:'子项6'},
                             {value:111,label:'子项7'},
                         ] },
                         {value:104,label:'菜单4'},
                     ]}
                 ],
             };
         },
     };
 </script>

上面将选项数据写死在了javaScipt里,更合理的做法应该来自后端服务器:

数据准备:

代码语言:javascript
复制
 CREATE TABLE `menu`(
     id INT,
     name VARCHAR(10),
     icon VARCHAR(30),
     path VARCHAR(30),
     pid INT,
     PRIMARY KEY (id)
 ) COMMENT '菜单表';
 ​
 INSERT INTO menu (id, name, icon, path, pid) values
     (100,'主页','el-icon-menu','/',0),
         (101,'菜单1','el-icon-menu','/menu1',100),
             (105,'子项1','el-icon-menu','/menu1/c1',101),
             (106,'子项2','el-icon-menu','/menu1/c2',101),
         (102,'菜单2','el-icon-menu','/menu2',100),
             (107,'子项3','el-icon-menu','/menu2/c3',102),
             (108,'子项4','el-icon-menu','/menu2/c4',102),
             (109,'子项5','el-icon-menu','/menu2/c5',102),
         (103,'菜单3','el-icon-menu','/menu3',100),
             (110,'子项6','el-icon-menu','/menu3/c6',103),
             (111,'子项7','el-icon-menu','/menu3/c7',103),
         (104,'菜单4','el-icon-menu','/menu4',100);

后端代码自己写,表里的数据是一维的,没有层级关系的,后端的人可以直接返给你有层级的关系的数据,但是如果他们不想写,而是给你返回一维的这种数组,那么前端就需要自己将这个一维的数组转换成这种树状的数据(这也是个基本功)。

下面的例子是将后端返回的一维数组【树化】

代码语言:javascript
复制
 <!-- 多级菜单 -->
 <template>
     <div>
         <el-cascader v-bind:options="ops"></el-cascader>
     </div>
 </template>
 <script>
 import axios from 'axios';
 export default {
     data: function () {
         return {
             // 多级菜单的数据
             // cascade级联选择器只需要最顶层的对象,就会从children里遍历子对象(所有只需要将最顶层的对象给他就行)。
             ops: [],
         };
     },
     mounted: async function () {
         const resp = await axios.get("/api/menu");
         const menus = resp.data.data;
         // 1. 将所有数据存入map集合(为了接下来查找效率)
         const map = new Map(); // set get
         for (const { Id, Name, Pid } of menus) {
             map.set(Id, { value: Id, label: Name, pid: Pid });
         }
 ​
         // 2. 建立父子关系
         const top = [];
         for (const obj of map.values()) {
             if (obj.pid !== 0) {
                 const parent = map.get(obj.pid)
                 // 如果父节点还没定义子数组,就创建一个空的数组
                 if (parent.children === undefined) {
                     parent.children = [];
                 }
                 parent.children.push(obj);
             } else {
                 // 3. 找到顶层对象,本例中顶层对象只有一个,但是实际上可能不止,所以使用数组
                 // cascade级联选择器只需要最顶层的对象,就会从children里遍历子对象(所有只需要将最顶层的对象给他就行)。
                 // 这个时候的top顶层对象是与所有子对象建立完联系了的
                 top.push(obj);
             }
         }
         this.ops = top;
     },
 };
 </script>

我正在参与2023腾讯技术创作特训营第三期有奖征文,组队打卡瓜分大奖!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 2. Vue 进阶
    • 1) ElementUI
      • 1. 表格组件
      • 2. 分页组件
      • 3. 分页搜索
      • 4. Cascader 级联选择器
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档