elementUI-day01----elementUI的使用、elementUI配置项、SliderTabBar.vue渲染、SliderTabBar.vue默认选中、路由切换、项目登录-mock数据模拟后台登录接口
### 项目搭建
vue create my_cms Babel Router Vuex CSS Use history mode for router? n Sass/SCSS (with dart-sass) In package.json Save this as a preset for future projects? n
### 安装插件
npm i element-ui axios js-cookie mockjs
npm install babel-plugin-component -D ----按需引入
### elementUI的使用
①安装插件:
npm i element-ui
npm install babel-plugin-component -D
②配置babel.config.js(按需加载,修改完要重启):
"plugins": [ [ "component", { "libraryName": "element-ui", "styleLibraryName": "theme-chalk" } ] ]
③src下新建common/components/index.js,完整组件列表和引入方式(实际工作中按需引入):
import Vue from 'vue'; import { Pagination, Dialog, Autocomplete, Dropdown, DropdownMenu, DropdownItem, Menu, Submenu, MenuItem, MenuItemGroup, Input, InputNumber, Radio, RadioGroup, RadioButton, Checkbox, CheckboxButton, CheckboxGroup, Switch, Select, Option, OptionGroup, Button, ButtonGroup, Table, TableColumn, DatePicker, TimeSelect, TimePicker, Popover, Tooltip, Breadcrumb, BreadcrumbItem, Form, FormItem, Tabs, TabPane, Tag, Tree, Alert, Slider, Icon, Row, Col, Upload, Progress, Spinner, Badge, Card, Rate, Steps, Step, Carousel, CarouselItem, Collapse, CollapseItem, Cascader, ColorPicker, Transfer, Container, Header, Aside, Main, Footer, Timeline, TimelineItem, Link, Divider, Image, Calendar, Backtop, PageHeader, CascaderPanel, Loading, MessageBox, Message, Notification } from 'element-ui'; Vue.use(Pagination); Vue.use(Dialog); Vue.use(Autocomplete); Vue.use(Dropdown); Vue.use(DropdownMenu); Vue.use(DropdownItem); Vue.use(Menu); Vue.use(Submenu); Vue.use(MenuItem); Vue.use(MenuItemGroup); Vue.use(Input); Vue.use(InputNumber); Vue.use(Radio); Vue.use(RadioGroup); Vue.use(RadioButton); Vue.use(Checkbox); Vue.use(CheckboxButton); Vue.use(CheckboxGroup); Vue.use(Switch); Vue.use(Select); Vue.use(Option); Vue.use(OptionGroup); Vue.use(Button); Vue.use(ButtonGroup); Vue.use(Table); Vue.use(TableColumn); Vue.use(DatePicker); Vue.use(TimeSelect); Vue.use(TimePicker); Vue.use(Popover); Vue.use(Tooltip); Vue.use(Breadcrumb); Vue.use(BreadcrumbItem); Vue.use(Form); Vue.use(FormItem); Vue.use(Tabs); Vue.use(TabPane); Vue.use(Tag); Vue.use(Tree); Vue.use(Alert); Vue.use(Slider); Vue.use(Icon); Vue.use(Row); Vue.use(Col); Vue.use(Upload); Vue.use(Progress); Vue.use(Spinner); Vue.use(Badge); Vue.use(Card); Vue.use(Rate); Vue.use(Steps); Vue.use(Step); Vue.use(Carousel); Vue.use(CarouselItem); Vue.use(Collapse); Vue.use(CollapseItem); Vue.use(Cascader); Vue.use(ColorPicker); Vue.use(Transfer); Vue.use(Container); Vue.use(Header); Vue.use(Aside); Vue.use(Main); Vue.use(Footer); Vue.use(Timeline); Vue.use(TimelineItem); Vue.use(Link); Vue.use(Divider); Vue.use(Image); Vue.use(Calendar); Vue.use(Backtop); Vue.use(PageHeader); Vue.use(CascaderPanel); Vue.use(Loading.directive); Vue.prototype.$loading = Loading.service; Vue.prototype.$msgbox = MessageBox; Vue.prototype.$alert = MessageBox.alert; Vue.prototype.$confirm = MessageBox.confirm; Vue.prototype.$prompt = MessageBox.prompt; Vue.prototype.$notify = Notification; Vue.prototype.$message = Message;
④main.js中引入:
import "@common/components/index.js";
⑤pages/Layout/index.vue中可以直接用elementUI的组件:
<el-container> <el-aside width="200px"> <SliderTabBar /> </el-aside> <el-container> <el-header>Header</el-header> <el-main> <Container /> </el-main> </el-container> </el-container>
### elementUI配置项
<el-menu default-active="2" class="el-menu-vertical-demo" @open="handleOpen" @close="handleClose" background-color="#545c64" text-color="#fff" active-text-color="#ffd04b" > <!-- 二级路由 --> <el-submenu index="1"> <template slot="title"> <i class="el-icon-location"></i> <span>导航一</span> </template> <el-menu-item index="1-4-1">选项1</el-menu-item> <el-menu-item index="1-4-2">选项1</el-menu-item> <el-menu-item index="1-4-3">选项1</el-menu-item> </el-submenu> <!-- 没有子标题 --> <el-menu-item index="2"> <i class="el-icon-menu"></i> <span slot="title">导航二</span> </el-menu-item> </el-menu>
注解:
1、el-menu标签:包裹菜单栏
2、el-submenu标签:包裹二级路由
3、el-menu-item标签:只有自己,没有子级
4、template标签:二级路由的标题
配置项:
default-active="2" 默认选中的index项
@open="handleOpen" 打开的时候触发的函数
@close="handleClose" 关闭的时候触发的函数
active-text-color="#ffd04b" 选中文字的颜色
### SliderTabBar.vue渲染
<template v-for="item in sliders"> <!-- 二级路由 --> <el-submenu :index="item.path" :key="item.path" v-if="item.children&&item.children.length>0"> <template slot="title"> <i class="el-icon-location"></i> <span>导航一</span> </template> <el-menu-item index="1-4-1">选项1</el-menu-item> <el-menu-item index="1-4-2">选项1</el-menu-item> <el-menu-item index="1-4-3">选项1</el-menu-item> </el-submenu> <!-- 没有子标题 --> <el-menu-item :index="item.path" :key="item.path" v-else> <i class="el-icon-menu"></i> <span slot="title">导航二</span> </el-menu-item> </template>
注意:
1、导航的配置项一般是后端返回的,不是前端写死的。
2、***因为有的导航带子级路由,有的导航不带,在遍历的时候需要区分开来,可以用v-if搭配v-else使用,而v-if的优先级低于v-for,它俩不能一起用,所以在外层嵌套一层template标签用于做遍历。
3、index是唯一标识,相当于key值。
4、如果要使用字体图标就在前面加上i标签:<i :class="item.icon"></i>
### SliderTabBar.vue默认选中
①data中定义defaultActive变量为 /home:
defaultActive:"/home",
②设置default-active的默认值为defaultActive:
:default-active="defaultActive"
③*watch监听路由跳转对象:
watch: { "$route":{ handler(newValue,oldValue){ this.defaultActive=newValue.path; }, immediate:true } }
### 路由切换
SliderTabBar.vue页面,在el-menu-item标签中添加点击事件,用编程式导航跳转路由。
①如果有子级路由则添加 @click="handlePush(child.path)"
如果没有子级路由则添加 @click="handlePush(item.path)"
②事件函数:
methods: { handlePush(path){ this.$router.push(path); } }
### 项目登录-mock数据模拟后台登录接口
①utils下新建utils.js,导出quertObject()方法,用于将url地址栏参数转成对象格式:
export const quertObject=(url)=>{ let queryString=url.split("?")[1]; let obj={}; let arr=queryString.split("&"); for(let i=0;i<arr.length;i++){ let key=arr[i].split("=")[0]; let value=arr[i].split("=")[1]; obj[key]=value; } return obj; }
②src下新建mock/index.js,模拟后端接口,定义url、请求方式为get,判断username和password是否正确:
import Mock from "mockjs";
import {quertObject} from "@utils/utils.js";
/* 登录接口 */ Mock.mock(/\/user\/login/,"get",(options)=>{ let obj=quertObject(options.url); if(obj.username=="admin"&&obj.password=="admin"){ return { code:200, data:{ authToken:"adfadfasf" } } }else{ return{ code:500, data:{ info:"用户名或密码不正确" } } } })
③定义完mock数据后一定要在main.js中引入mock:
import "@mock/index.js";
④utils下新建request.js,进行axios拦截:
import axios from "axios"; // import loading from "@plugins/Loading/index.js"; import Vue from 'vue'; // import loading from "" console.log(Vue) const http=axios.create({ timeout:5000, withCredentials:true,// 允许携带token // baseUrl:"" }); http.interceptors.request.use(config=>{ if(config.method=="get"){ config.params={...config.data}; } // config.headers["authToken"]=store.token; // 开启loading // loading.show(); return config; },(err)=>{ return Promise.reject(err); }); http.interceptors.response.use(config=>{ if(config.status==200){ // 关闭loading // loading.hide(); return config.data; } },(err)=>{ return Promise.reject(err); }); export default http;
⑤api下新建request.js,定义loginApi方法请求mock中的地址,请求方式为mock中定义的格式get,导出loginApi方法:
import http from "@utils/request.js"; export const loginApi=(loginModel)=>{ return http({ method:"get", url:"/user/login", data:loginModel }) }
⑥Login/index.vue中引入loginApi方法,点击登录按钮时,进行数据请求,将当前填写的username和password带过去,判断返回值,如果code为200,则提示登录成功,并且保存authToken和进行路由的跳转:
import { loginApi } from "@api/request.js"; methods: { async handleLogin() { let data = await loginApi(this.login_model); if (data.code == 200) { this.$message({ message: "登录成功", type: "success", onClose:()=>{ // 保存authToken this.$store.commit("handleAuthToken",data.data.authToken); this.$router.push("/home"); } }); }else{ this.$message.error(data.data.info); } } }
⑦store/index.js中,保存token(借助js-cookie插件):
import Cookies from "js-cookie";
state:{ authToken:Cookies.get("token")||"" }, mutations:{ handleAuthToken(state,params){ state.authToken=params; Cookies.set("token",state.authToken); } }
分类:
vue
, element-ui
« 上一篇: vue-day16----拿到登录的token、登录的逻辑、加入购物车、购物车图标上的数量-count、加入购物车的逻辑判断-Dialog对话框(优化)、Cart/index.vue购物车页面数据渲染、Cart/index.vue购物车页面加减法的接口调用、详情页 商品-详情-评价 切换动画、nginx打包
» 下一篇: elementUI-day02----elementUI中涉及到组件嵌套的时候如何进行传值-slot插槽作用域、商家列表(shoplist、table表格固定列和表头、tag标签、分页、对话框-删除当前数据、对话框-编辑当前数据、对话框-推荐菜品 tag标签-动态编辑标签、搜索)、用户列表(userlist、分页、全选和非全选、steps步骤条)
» 下一篇: elementUI-day02----elementUI中涉及到组件嵌套的时候如何进行传值-slot插槽作用域、商家列表(shoplist、table表格固定列和表头、tag标签、分页、对话框-删除当前数据、对话框-编辑当前数据、对话框-推荐菜品 tag标签-动态编辑标签、搜索)、用户列表(userlist、分页、全选和非全选、steps步骤条)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 提示词工程——AI应用必不可少的技术
· 字符编码:从基础到乱码解决
· 地球OL攻略 —— 某应届生求职总结