前端开发笔记,持续更新中!!!
程序员文章站
2022-05-11 11:06:18
...
# reduce 函数
// 求和
var numbers=[65,44,12,4];
function getSum(total,num){
retuen total+num
}
function MyFun(item){
var numrs=numbers.reduce(getSum)
}
#Object.keys()方法
//获得对象中所有的键或者其他方法使用
//PS:IE11包括IE11不支持
var person = {
name:"张三",
age:18,
66:"55"
};
Object.keys(person);//["66","name","age"]
Object.values(person);//["55","张三",18];
/*
* 如果属性名的类型是Number,那么Object.keys返回值是按照key从小到大的顺序排列
* 如果属性名的类型是String,那么Object.keys返回值是按照树形被创建的时间升序排列
* 如果属性名的类型是Symbol,那么逻辑和String的逻辑相同
*/
# vue 的router.addRoutes 方法
router.addRoutes -----函数签名
router.addRoutes(routes:Array) — 动态添加路由规则,参数必须是符合routes选项要求的数组
-
基本使用
//现在有一个非常普通的路由 const routes = [ { path:"/", name:"Home", component:Home }, { path:"PageA", name:"PageA", conponent:PageA } ] const router = new VueRouter({ routes }) export default router;
那么使用router.addRoutes改造上面的配置,实现动态添加PageA,如下
const router = new VueRouter({ { path:"/", name:"Home", component:Home } }); let route = [ { path:"PageA", name:"PageA", component:PageA } ]; router.addRoutes(route); export default router; // 把原来的routes配置照搬到一个新的数组中,就可以作为addRoutes的参数使用,经验证实,通过addRoutes动态配置和普通配置一样
2.路由的权限验证
如果网页有[管理员,普通用户,其他管理]等多种角色,不同的角色看见的页面页是不同的,比如普通用户不应该看见管理员的控制台,那么这个时候,动态路由就非常有用了,
let PageA,pageB,pageC;
let route = [
{
path:"/PageA",
name:"PageA",
component:PageA
},
{
path:"/PageB",
name:"PageB",
component:PageB
},
{
path:"/PageC",
name:"PageC",
component:PageC
}
];
let commOnUser=["PageA","PageB"];
let commInUserRoute=route.filter(function(page){
return commOnUser.includes(page.name)
})
console.log(commInUserRoute);
router.addRoues(commInUserRoutes);
//结果
/*
* (2) [{...},{...}]
* 0:{path:"/PageA",name:"PageA",component:PageA},
* 1:{path:"/PageB",name:"PageB",component:PageB},
* length:2
*/
//这样就可以完成权限验证,当前如果权限在前台验证会有一定的安全隐患,最好的还是在后台来进行限制访问
PS:router.addRoutes 之后的next() 可能会失效,因为可能next() 的时候路由并没有完全add完成
解决办法:**通过next(to)**解决,这行代码重新进入router.beforeEach这个钩子,这是后再通过 **next()**来释放钩子,这能确保所有的路由都已经挂载完成了
#封装请求和vuex && 路由守卫
1.封装axios请求,设置请求拦截器和响应拦截器
import axios from "axios"; //引入页面上方的进度条 import Nprogress from "nprogress";//需要自己去npm安装环境 import "nprogress/nprogress.css"; const Axios=axios.create({ baseUrl:""; withCredentials:fasle,//请求头需要携带cookies的话,需要设置为true、否则false或者不写 timeout:5000//请求超时的时间(毫秒),服务器在该时间没有响应会直接超时,执行自己设置超时的事件 }) //请求拦截器,所有的请求都会触发该事件 Axios.interceptors.request.use( config => { Nprogress.start(); if (sessionStorage.getItem("token")) { config.headers.token=sessionStorage.getItem("token") } retuen config }, error => { Promise.reject(error) } ); //响应拦截器,所有请求回来的数据都会触发该事件 Axios.interceptors.response.use( res => { Nprogress.done(); return res }, error => { Nprogress.done(); //如果请求超时了,对请求超时的处理 if (error.message,includes("timeout")) { console.error("请求超时") } } ) export default Axios;//将自己定义的Axios抛出去,方便其他事件引用
2.开始封装xaios请求
在src下创建一个api的文件夹,在里面创建对应的事件
import axios from "@/neteork/axiosUtil";//自己封装axios请求的位置 //登录的封装请求 export function login (data) { return axios({ url:"/api/login",//自己需要请求的地址 method:"post",//请求的方式, data//原来是data:data,可以简写为data }) } //登出的请求 export function loginOut () { return axios({ url:"/api/loginOut", method:"post" }) } //获取侧拉菜单 export function getmenu (userCode) { return axios({ url:"/api/menu", method:"get", params:{userCode} }) }
3.登录和登出基本是靠着token去控制的,所以用到好多,封装下token
//我将所有封装事件在src下创建了一个util文件夹,将所有的封装事件封装在里面 //token.js const tokenKey=sessionStorage.getItem("token") || undefined; export function setToken (token) { return sessionStorage.setItem("token",token); } export function getToken () { return sessionStorage.getItem("token") } export function removeToken () { return sessionStorage.removeItem("token") }
4.在vuex中封装请求
/* * 在store的文件下创建一个modules文件夹 * 创建user.js文件 */ //引入封装好的请求 import {login, loginOut, getmenu} from "@/api/user"; //引入关于token的封装 import {getToken, setToken, removeToken} from "@/utils/auth"; const state = { token: getToken,//登录够需要存储的token name: "",//登录人的用户名 menus: [], userCode: "",//当前登录人的标识码(登录的账号) loginF: false,//双层控制是否登录,true代表登录了,false代表没登录 }; const mutations = { setToken (state,token) { state.token = token; }, setName (state,name) { state.name = name; }, setMenu (state,menu) { state.menus = menu; }, setUserCode (state,userCode) { state.userCode = userCode; }, setLoginF (state,loginF) { state.loginF = loginF; } }; const actions = {//所有的ajax请求或者异步事件都在这里面处理 //用户登录触发的事件 login ({commit}, menu) {//userInfo事件传递过来的参数 const { userCode, password} = userInfo; return new Promise ((resolve,reject) => { login({userCode,password}) .then(res => { const {data} = res; commit("setToken",data.token); commit("setLoginF",true); setToken(data.token); resolve(); }) .catch(err => { reject(err) }) }) }, //登录成功后请求侧拉菜单的事件 getmenu ({commit}, state) { retuen new Promise((resolve,reject) => { getmenu(state.userCode) .then(res => { const {data} =res; commit("setMenu", data); resolve(); }) .catch(err => { rejece(err) }) }) }, //登出的事件 loginOut ({commit,state}) { return new Promise((resolve,reject) => { loginOut(state.userCode) .then(res => { commit("setToken",""); commit("setMenu",[]); commit("setLoginF",false); removeToken(); resolve(); }) .catch(err => { reject(err) }) }) }, //移除token和菜单和session resetToken ({commit}) { return new Promise(resolve => { commit("setToken",""); commit("setMenu",[]); commit("setLoginF",fasle); removeToken(); resolve(); }) } }; export default { namespaced: true, state, mutataions, actions };
5.在store根文件下创建一个getters.js
//该文件主要让用户直接获取数据用 const getters = { token: (state) => { state.user.token }, name: (state) => { state.user.name }, menus: (state) => { state.user.menus }, userCode: (state) => { state.user.userCode }, loginF: (state) => { state.user.loginF } }; export default getters;
6.在主文件store.js里面处理事件
import Vue from "vue"; import Vuex from "vuex"; import getters frm "./getters";//引入刚才创建的getters文件 Vue.use(Vuex); const modulesFiles = require.context("./modules", true, /\.js$/); //不需要将mudules里面封装的vuex在本文件挨着import进来了 //通过本事件处理 const modules = modulesFiles.keys().reduce((modules,modulePath) => { //设置将 xx.js 文件设置为 "xx“ const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/,"$1"); const value = modulesFiles(modulePath); modules[moduleName] = value.default; return modules },{}); const store = new Vuex.Store({ modules, getters }) export default store; //---------------------------------------------------------------- //另外一种写法,挨着把文件引入 import Vue from "vue"; import Vuex from "vuex"; import getters frm "./getters";//引入刚才创建的getters文件 import user from "./modules/user"; Vue.use(Vuex); export default new Vuex.Store({ modules:{ user, getters } })
7.随后配置路由守卫
//在src文件夹下创建perminnion.js文件 import router from "./router";//router是router配置的文件夹 import store from "./store"; import {Message} from "element-ui";//引入elemen-ui的message组件,可以进行相应的提示 import Npogress from "nprogress"; import "nprogress/nprogress.css"; import {getToken} from "@/utils/auth"; Npogress.configure({showSpinner: false}); router.beforeEach(async (to,from,next) => { Npogress.start(); document.title=to.meta.title;//每个路由都配置的title //如果跳转的页面没有,就跳转404页面 if(to.matched.length === 0) { next("/404");//自己定义的404页面 } //校验是否登录,防止部登录,直接进入其他页面 const HasToken = getToken();//获取token const HasLoginF = store.getters.loginF;//获取是否登录 if(HasToken && HasLoginF){ if (to.path === "/login") { next({path:"/home"});//项目设置的首页 Npogress.done(); }else if (to.meta.requireAuth) { next() }else{ next({ path: "/login", query: { redirect: to.fullPath } }) } }else { next({ path:"/login", query: { redirect: to.fullPath } }) } })
8.登录触发的事件
//因为登录页面可能是从别的页面打回来的,所以在登录页面加一个watch监视路由 watch: { $route: { handler: function (route) { const query=route.query; if (query) { this.redirect = query.redirect } }, immediate: true } }; //PS:记得在data中定义redirect:undefinde //在登录界面点击登录的时候触发封装的事件 this.$store.dispatch("user/login",this.regForm) .then(res => { this.$store.dispatch("user/getmenu",this.regForm.userCode) .then(res => { this.$router.push({ path:this.redirect || "/home" }) }) .catch(err => { Promise.reject(err); }) })
9.注销触发的事件
logOut () { this.$store.dispatch("user/logOut") this.$router.push(`/login?redirect=${this.$route.fullPath}`) }
# watch 初始化不会触发事件问题
//可以添加immediate 属性,这样初始化的时候也同样会触发
watch: {
searchText: {
handler: function (newValue, oldValue) {
//newValue是新数据,oldValue是老数据
console.log(newValue,oldValue);
},
immediate: true//第一次刷新页面的时候就会执行
}
}
# vue报错Do not use built-in or reserved HTML elements as component id
// 一版情况是因为组件命名和引入的不知道导致的
export default {
name:"header"
}
//在组件引入上方组件的时候,将引入的名字需要和name名称保持一致
import header from "./header" //名称保持一致
/*
* 还有一种情况是名称哟两个大写的英文单词书写造成的
import TestPage from "./TestPage"
*/
//使用的时候
// <div>
// <testpage></textpage>
// </div>
//改使用标签即可
// <div>
// <test-page></text-page>
// </div>
# 在vue中用v-for给src动态绑定图片不显示问题
//用v-for给图片的img动态绑定本地的src属性
<div
class="img_carousel"
v-for="(items, indexs) in item.carousel"
:key="indexs"
>
<img :src="imgSrc(items)" alt="加载失败" />
</div>
//设置imgSrc事件,将当前本地的图片名字传入,通过事件将图片路径完整的返回
//然后在methods中设置imgSrc事件
methods:{
imgSrc(item){
//拼接路径,将路径return出去
return require(`../assets/carousel/${item}`)
}
}
# el的日期组件
//element ui 的日期组件,选择区间日期和具体时间
<el-date-picker
v-model="userDeatil.Time"
type="datetimerange"
start-placeholder="开始时间"
end-placeholder="结束时间"
:default-time="['12:00:00', '08:00:00']"
size="small"
value-format="yyyy-MM-dd HH:mm:ss"
></el-date-picker>
// 注意,把选择的去掉一次后,绑定的参数值直接为null
# webpack打包vue项目后,head里面有特别多的link(ref=prefetch和ref=preload)
这种加载影响了加载速度,加载了太多不需要的东西,所以需要优化
// 通过配置wenpack去掉这一种行为 module.export = { chainWebpack(config) { config.plugins.delete("prefetch"); config.plugins.delete("preload"); } }
然后再次运行项目,就会发现,多余的都去掉了
上一篇: 曹植斗不过曹丕的真正原因是什么呢?
下一篇: 你去的地方我指给你看就行了
推荐阅读
-
.Net WInform开发笔记(二)Winform程序运行结构图及TCP协议在Winform中的应用
-
C++ 编程技巧笔记记录(持续更新)
-
iOS应用开发中实现页面跳转的简单方法笔记
-
android开发教程之子线程中更新界面
-
JavaScript设计模式精华摘抄(持续更新...)-考拉阅读前端团队-SegmentFault思否
-
Javascript之常见算法整理(持续更新)-柠檬味的前端-SegmentFault思否
-
三大升级脱胎换骨 华为MateBook 14 2020款笔记本持续热卖中
-
PHP开发中的错误收集,不定期更新。
-
[3]尝试用Unity3d制作一个王者荣耀(持续更新)->选择英雄-(中)
-
webpack4.x笔记-配置基本的前端开发环境(一)