内容
axios
1.安装axios
(c)npm i(nstall) axios
2.引入axios
import axios from 'axios'
3.使用
axios.get('url',{
params:{
//参数
key:val
}
})
.then(
//回调成功
function (response) {
//成功回调函数
console.log(response);
},function(es){
//失败回调函数
}
)
post
headers: { 'content-type': 'application/x-www-form-urlencoded' },
axios.post("url",{
//键值对
}).then(
//回调成功
function (response) {
//成功回调函数
console.log(response);
},function(es){
//失败回调函数
}
)
axios({
method: 'post',
url: '/user/12345',
data: {
firstName: 'Fred',
lastName: 'Flintstone'
}
}) .then(function (response) {
//response.data.pipe(fs.createWriteStream('ada_lovelace.jpg'))
});
注册全局的axios
在main.js中写入以下代码
import axios from 'axios'
Vue.prototype.$axios=axios
默认的配置:
本地存储localStorage
对浏览器来说,使用 Web Storage 存储键值对比存储 Cookie 方式更直观,而且容量更大,它包含两种:localStorage 和 sessionStorage
- sessionStorage(临时存储) :为每一个数据源维持一个存储区域,在浏览器打开期间存在,包括页面重新加载
- localStorage(长期存储) :与 sessionStorage 一样,但是浏览器关闭后,数据依然会一直存在
注意:sessionStorage 和 localStorage 的用法基本一致,引用类型的值要转换成JSON
保存
const info = { name: 'hou', age: 24, id: '001' };
//字符串
const str="haha";
localStorage.setItem('hou', JSON.stringify(info));
localStorage.setItem('zheng', str);
获取
var data1 = JSON.parse(localStorage.getItem('hou'));
var data2 = localStorage.getItem('zheng');
删除
// 清除某一个元素 removeItem(key的值)
localStorage.removeItem('hou');
//删除所有
localStorage.clear();
查看
<template>
<div>
<el-form :model="ruleForm" status-icon ref="ruleForm" label-width="100px" class="demo-ruleForm">
<el-form-item label="密码" prop="password">
<el-input type="password" v-model="ruleForm.password" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="用户名" prop="name">
<el-input v-model.number="ruleForm.name"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitForm('ruleForm')">提交</el-button>
<el-button @click="resetForm('ruleForm')">重置</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
export default {
name: "login",
data() {
return {
ruleForm: {
password: '',
name: ''
}
};
},
methods: {
submitForm(formName) {
alert(JSON.stringify(this.ruleForm));
//
this.$axios.post(`login?name=${this.ruleForm.name}&&password=${this.ruleForm.password}`).then((r)=>{
alert(JSON.stringify(r.data));
if(r.data.code==0){
//登录成功,将信息保存
localStorage.setItem("user",JSON.stringify(r.data));
localStorage.setItem("roles",JSON.stringify(r.data.roles));
this.$router.push("/main");
}else{
//登录失败
alert("登录失败!!!");
}
})
//强制更改路由
// this.$router.push("/main");
/*alert("tiaozhaun")*/
},
resetForm(formName) {
this.$refs[formName].resetFields();
}
}
}
</script>
<style scoped>
</style>
对应的后台登录
axios的定义
main.js
Vue在发起跨域请求时,后端已经开启CORS,前端需要也携带cookie,此时需要在前端请求头加上withCredentials: true,表示请求可以携带cookie
import axios from 'axios'
const instance = axios.create({
baseURL: 'http://localhost:8888/',
withCredentials:true
// headers:{'Content-Type':'application/x-www-form-urlencoded'}
});
//vue Z全局变量是$axios
Vue.prototype.$axios=instance;
拦截器:
请求拦截器
响应拦截器
instance.interceptors.response.use(
response => {
if (response.data.code == 1) {
//返回的code是1 的时候直接 跳转到login里面
router.push({
path:"/login"
})
}
return response; // 返回请求回来的数据
},
err => {
alert("错误的信息"+err);
console.log(err)
}
);
路由守卫
https://v3.router.vuejs.org/guide/advanced/navigation-guards.html#the-full-navigation-resolution-flow
如果路由在使用的时候需要登录之后才能使用的话就需要使用拦截器
在main.js里面配置即可
router.beforeEach((to,from,next)=>{
//如果直接访问的是 /login或者是缓存里面有user 就直接放行 否则就跳//转到login路由
if(to.path=='/login' || localStorage.getItem('user')){
next();
}else{
alert('请重新登录');
next('/login');
}
});
to: Route: 即将要进入的目标 路由对象
from: Route: 当前导航正要离开的路由
next: Function: 一定要调用该方法来 resolve 这个钩子。执行效果依赖 next 方法的调用参数。
next(): 进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 confirmed (确认的)。
next(false): 中断当前的导航。如果浏览器的 URL 改变了(可能是用户手动或者浏览器后退按钮),那么 URL 地址会重置到 from 路由对应的地址。
next(‘/’) 或者 next({ path: ‘/’ }): 跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。
在路由配置的时候需要添加一个meta的属性
简介meta
meta字段(元数据)
直接在路由配置的时候,给每个路由添加一个自定义的meta对象,在meta对象中可以设置一些状态,来进行一些操作。用它来做登录校验比较合适
router/index.js
import Vue from 'vue'
//引入了路由
import Router from 'vue-router'
import app from '@/App.vue'
//@ src
import HelloWorld from '@/components/HelloWorld'
//Vue用路由
Vue.use(Router)
//export 暴露出去
export default new Router({
//路由的规则
routes: [
/*登录路由*/
{
path:"/",
redirect:"/login"
},
{
path:"/login",
name:"login",
component:()=>import("@/components/login.vue")
},
{
path:"/main",
name:"main",
component:()=>import("@/components/main.vue")
,children:[
{
//子路由以/ 为开头 直接将这个子路由放到对应的父路由下面
//
path:"/table"
,name:"table",
component:()=>import("@/components/table.vue"),
meta: { title: 'table', requireAuth: true }
}
]
},
{
path: '/hello',
name: 'HelloWorld',
//指向的组件时是什么
component: HelloWorld
},{
path:"/index"
,name:"index"
//箭头函数
,component:()=>import("@/components/index.vue")
},{
path:"*",
component:()=>import("@/components/404.vue")
}
]
})
自定义指令实现细粒度的按钮显示等控制(例:如果我们想控制某个角色或者拥有某项权限才能看到编辑按钮)
自定义的指令
除了核心功能默认内置的指令 (v-model
和 v-show
),Vue 也允许注册自定义指令。注意,在 Vue2.0 中,代码复用和抽象的主要形式是组件。然而,有的情况下,你仍然需要对普通 DOM 元素进行底层操作,这时候就会用到自定义指令。
一个指令定义对象可以提供如下几个钩子函数 (均为可选):
bind
:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。inserted
:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。update
:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)。componentUpdated
:指令所在组件的 VNode 及其子 VNode 全部更新后调用。unbind
:只调用一次,指令与元素解绑时调用。
接下来我们来看一下钩子函数的参数 (即 el
、binding
、vnode
和 oldVnode
)。
钩子函数参数
指令钩子函数会被传入以下参数:
el
:指令所绑定的元素,可以用来直接操作 DOM。
binding
:一个对象,包含以下 property:
-
name
:指令名,不包括v-
前缀。value
:指令的绑定值,例如:v-my-directive="1 + 1"
中,绑定值为2
。oldValue
:指令绑定的前一个值,仅在update
和componentUpdated
钩子中可用。无论值是否改变都可用。expression
:字符串形式的指令表达式。例如v-my-directive="1 + 1"
中,表达式为"1 + 1"
。arg
:传给指令的参数,可选。例如v-my-directive:foo
中,参数为"foo"
。modifiers
:一个包含修饰符的对象。例如:v-my-directive.foo.bar
中,修饰符对象为{ foo: true, bar: true }
。
vnode
:Vue 编译生成的虚拟节点。移步 VNode API 来了解更多详情。oldVnode
:上一个虚拟节点,仅在update
和componentUpdated
钩子中可用。
除了 el
之外,其它参数都应该是只读的,切勿进行修改。如果需要在钩子之间共享数据,建议通过元素的 dataset
来进行。
// 注册一个全局自定义指令 `v-hasAuthorization`
Vue.directive('hasAuthorization', {
// 初始化设置。
bind: function (el) {
//具体的自己的业务逻辑
const roles = localStorage.getItem('roles');
if(!(localStorage.getItem('roles').indexOf('test') > -1)){
el.setAttribute('style','display:none')
}
})
在需要使用的页面定义即可
js代码:
import Vue from "vue"
Vue.directive('hasAuthorization',{
bind: (el) => {
let user=localStorage.getItem("user");
const roles = localStorage.getItem('roles');
if(!(localStorage.getItem('roles').indexOf('test') > -1)){
el.setAttribute('style','display:none')
}
}
})
页面代码
<el-button type="text" icon="el-icon-edit" v-hasAuthorization >编辑</el-button>
写的灵活一点
Vue.directive('has', {
inserted: function (el, binding) {
if (!Vue.prototype.$_has(binding.value)) {
el.parentNode.removeChild(el);
}
}
});
//权限检查方法
Vue.prototype.$_has = function (value) {
let isExist = false;
let user = sessionStorage.getItem("user");
console.log("admin" === user)
if ("admin" === user) {
return true;
}
let premissionsStr = sessionStorage.getItem("roles");
if (premissionsStr == undefined || premissionsStr == null) {
return false;
}
if (premissionsStr.indexOf(value) > -1) {
isExist = true;
}
return isExist;
};
总结:
1.withCredentils:true
后台 允许携带cookie
crosFilter
1-1:存值 sessionStorge localStorge
2.路由拦截器:
路由登录认证 需要
3.自定义指令
全局指令