npm install less vue-router element-plus -s
elementplus
路由引入组件第二种写法:
使用动态的import( )语法(推荐使用)(路由懒加载)
component:()=>import('路径')component:()=>import('@/views/Main.vue')
打包之后的文件将会异常的大,需要加载的内容过多时间过长,出现长时间的白屏,不利于用户体验,运用懒加载就可以将页面进行划分,需要的时候加载页面,可以有效的分担首页所承担的加载压力,减少首页加载用时。
filter函数
filter用于对数组进行过滤。
filter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。
const hasChildren=computed(()=>list.filter(item=>item.children));
过滤掉没有children的数组元素
v-if和v-for
vue2中v-for优先;vue3中v-if优先
is
component组件是一个动态组件,跟随:is里的变量动态显示加载组件
使用场景:适用于组件会动态变化的场景,如新闻类型可能是视频、图片、文字,在遍历渲染新闻列表时,根据新闻类型的不同,渲染不同的组件。
<component class="icons" :is="item.icon"></component>
new URL()
mokejs
生成随机数据,拦截 Ajax 请求
mokejs官网
getCurrentInstance()
在Vue3中,getCurrentInstance()可以用来获取当前组件实例
let { proxy } = getCurrentInstance();
getCurrentInstance只能在setup或生命周期钩子中使用。
1.在onMunted生命周期中打印getCurrentInstance
2.定义一个test方法,通过click事件触发方法
封装axios
- 拦截器
api/request.js
import axios from "axios";
import {} from 'element-plus';
const server=axios.create();
// 添加请求拦截器
server.interceptors.request.use(function (config) {// 在发送请求之前做些什么return config;}, function (error) {// 对请求错误做些什么return Promise.reject(error);});// 添加响应拦截器
server.interceptors.response.use((res)=>{const {code,data,msg}=res.data;if(code===200){return data;}else{const NETWORK_ERROR="网络错误,请稍后重试";ElMessage.error(msg|| NETWORK_ERROR);return Promise.reject(new Error(msg|| NETWORK_ERROR));}}
);function request(options){options.method=options.method||"get";return server(options);
}
export default request;
- 统一管理axios
api/api.js
// 整个项目api的统一管理import request from "./request";
export default {// 获取首页左侧的表格数据getTableData(){return request({url:"/api/home/getTableData",method:"get"})},};
- main.ts配置全局api
import api from './api/api';
// 全局api
app.config.globalProperties.$api = api;
- 使用
import {unMounted,getCurrentInstance} from 'vue'
const {proxy} = getCurrentInstance();
const getTableData=()=>{const data = proxy.$api.getTableData();tableData.value=data.tableData;
}
echarts
生成图表
安装: npm install echarts -D
文档
Object.keys()
- 遍历对象(必须包含属性和方法的对象);
- 返回对象中每一项key的数组(遍历一个对象,返回一个全是key的数组)
用法:1.如果对象是一个对象,会返回对象的属性名组成的数组;
Object.keys()
let obj={a:1, b:2, c:3}
Object.keys(obj) // ['a', 'b', 'c']
2.如果对象是一个数组或字符串,则返回索引组成的数组
Object.values()和Object.keys() 相反
map
map用法详解
返回值错误:
返回的是{}里面的的值,不是[{},{},{}];
2.正确写法:
监听图表页面
const observer=ref();// 监听页面的变化observer.value=new ResizeObserver(()=>{oneEchart.resize();twoEchart.resize();threeEchart.resize();});if(proxy.$refs.echart){observer.value.observe(proxy.$refs.echart);}
resizeobserve
搜索功能
搜索
分页
前后端分页
scope.row
理解Element的scope.row
vue插槽的scope.row
confirm、alert、prompt
confirm、alert、prompt区别
element plus
官网
nextTick
问题:点击编辑后,再点击添加用户后表单里的信息变成了编辑用户的信息(本来是没有值的)
原因:
// 编辑
const handleEdit=(val)=>{dialogFormVisible.value = true;action.value=1;// 赋值(表单的值设置为当前行的值)// 当dialogFormVisible.value = true后弹出对话框表单才会出现,(表单在对话框里)// 异步非常快,会把Object.assign(form,{...val,addr:val.address})当成初始值//导致关闭对话框再次打开后显示Object.assign(form,{...val,addr:val.address})的值Object.assign(form,{...val,addr:val.address})
}
nextTick详解
解决方式1:nextTick(()=>{//不要忘记先引入nextTickObject.assign(form,{...val,addr:val.address})})解决方式2:setTimeout(()=>{Object.assign(form,{...val,addr:val.address})},100)
useRouter和useRoute
两者区别
区别
router.push
vue3跳转路由5中方式
json.stringfy和json.parmars
相关文章1
相关文章2
vite的glob
动态生成路由
// 动态生成路由function addMenu(router){const menuList=state.value.menuList;//根据登陆身份拿到对应的菜单列表const module=import.meta.glob("../views/**/*.vue");//批量const routeArr=[];menuList.forEach(item=>{if(item.children){item.children.forEach(val=>{let url=`../views/${val.url}.vue`;val.component=module[url];routeArr.push(val);});}else{let url=`../views/${item.url}.vue`;item.component=module[url];routeArr.push(item);}})routeArr.forEach(item=>{state.value.routerList.push(router.addRoute("main",item));});};
glob
vite:glob批量引入文件
多账号登陆问题
不是管理员账号,但能访问到mall页面
// 动态生成路由function addMenu(router){const menuList=state.value.menuList;//根据登陆身份拿到对应的菜单列表const module=import.meta.glob("../views/**/*.vue");//批量const routeArr=[];menuList.forEach(item=>{if(item.children){item.children.forEach(val=>{let url=`../views/${val.url}.vue`;val.component=module[url];routeArr.push(val);});}else{let url=`../views/${item.url}.vue`;item.component=module[url];routeArr.push(item);}});// 解决多种账号登陆bugstate.value.routerList=[];let routes=router.getRoutes();//拿到所有路由routes.forEach(val=>{if(val.name==='main'||val.name==='login'){return //不做处理}else{router.removeRoute(val.name);}});routeArr.forEach(item=>{state.value.routerList.push(router.addRoute("main",item));});};
解决登录后刷新页面消失的路由问题
对pinia的stores/index.js下的state进行持续化存储
// state持久化存储watch(state,(newObj)=>{if(!newObj.token) return ;localStorage.setItem("store",JSON.stringify(newObj));},{deep:true})
main.js
import router from './router/index';
import { useAllDataStore } from './stores';
const store = useAllDataStore();//放到app.use(pinia)后
store.addMenu(router,"refresh")//传递路由并传类别//这一步要在使用路由前
app.use(router)
退出登录
const handleLoginOut=()=>{store.clean()router.push('/login');
}
stores/index.js
export const useAllDataStore = defineStore("allData",()=>{/****/function clean(){state.value.routerList.forEach(item=>{if(item) item();//删除(console.log(item)后得到是一个removeRoute删除路由)});// 重置state.value=initState();// 删除本地缓存localStorage.removeItem("store");}/*****/return {state,updateMenuList,addMenu,clean}
})
路由守卫
相关文章1
相关文章2
// 路由守卫
function isRoute(to){let res=router.getRoutes();let resFil=res.filter(item=>item.path===to.path);//拿到要去往的路由return resFil.length>0;//判断是否在路由列表中
}
router.beforeEach((to,from)=>{if(to.path!=='/login'&&!store.state.token){// next('/login');return {name:'login'}}if(!isRoute(to)){// next('/404');return {name:'404'}}
})