.sync修饰符
.sync修饰符可以实现子组件与父组件的双向绑定,并且可以实现子组件同步修改父组件的值,解决因为修改props值带来的报错问题
//子组件怎么来修改父组件传过来的值,而不会报错
//父组件
<button @click='isShow=!isShow'>点我传值</button>
<!-- 使用注册好的子组件 -->
<child :show.sync='isShow'/>
//定义变量
//注册子组件
components:{child}
data(){
return{
isShow:false
} }
//子组件
<div @click='changeShow'>接收父组件的值</div>
//接收数据
props:{
show:{
type:Boolean,
}
},
methods:{
//点击改变show的值
changeShow(){
//子组件直接修改父组件的值
//语法:this.$emit('update:要改变的值',变成什么样)
this.$emit('update:show',false)
}
}
导航守卫
//src/permission.js文件
// 路由权限文件
import router from '@/router/index'
import store from '@/store/index'
// 利用导航守卫完成
router.beforeEach(async(to, from, next) => {
// 如果登录了则可以直接进入首页,否则不可以进入
const token = store.getters.token
if (token) { // 存在
// 一般情况,用户登录了网站,那么就不允许用户进入登录页面
if (to.path === '/login') {
next('/')
} else {
// 当vuex中没有用户详情数据的时候才需要重新请求数据
if (!store.state.user.userInfo.id) {
await store.dispatch('user/getUserInfo')
// 这里我们能够保证获取到路由权限数组menus,因此我们需要在这里来获取
// 获取筛选处理的路由对象,把筛选处理的数据合并到原来的路由规则中
const routes = await store.dispatch(
'permission/filterRoutes',
store.state.user.userInfo.roles.menus
)
// 方法addroutes,语法:router.addRoutes(动态路由)
// 恢复了浏览器中URL的页面访问权限,解决刷新浏览器跳转到404页面问题,只需要把404路由对象添加到路由规则的最后面
router.addRoutes([...routes, { path: '*', redirect: '/404', hidden: true }])
// 解决刷新空白问题
next(to.path)
}
next() // 直接跳转
}
} else {
// 登录页面和404页面不需要登录,也能直接进入
const arr = ['/login', '/404']
if (arr.indexOf(to.path) !== -1) {
next()
} else {
next('/login')
}
}
})
Vuex +js-cookie存放token
//在src/utils/auth.js
//引入
import Cookies from 'js-cookie'
const TokenKey = 'hr-token'
//获取token
export function getToken() {
return Cookies.get(TokenKey)
}
//设置token
export function setToken(token) {
return Cookies.set(TokenKey, token)
}
//移除token
export function removeToken() {
return Cookies.remove(TokenKey)
}
//在src/store/modules/user.js
//引入
import { login, getUserInfo, detailedInfo } from '@/api/user.js'//接口
import { getToken, removeToken, setToken } from '@/utils/auth.js'
export default {
namespaced: true, // 命名空间锁
state: {
// 获取token
token: getToken(),
userInfo: {}
},
mutations: {
// 设置token
setToken(state, data) {
state.token = data
setToken(data)
},
// 移除token
removeToken(state) {
state.token = null
removeToken()
},
// 获取用户信息
setUserInfo(state, data) {
state.userInfo = data
},
removeUserInfo(state) {
state.userInfo = {}
}
},
actions: {
async login(context, data) {
// 调用登录接口
const res = await login(data)
// console.log(21, res)
// 调用mutations中保存token方法
// 此时res就是token值
context.commit('setToken', res)
// console.log(32, res.data.data)
// 保存登录时的时间戳
localStorage.setItem('loginTime', Date.now())
},
async getUserInfo(context) {
// 获取用户基本信息
const res = await getUserInfo()
// 获取用户头像
const userId = await detailedInfo(res.userId)
// console.log(41, userId)
// 利用展开运算符合并两个数据
context.commit('setUserInfo', { ...res, ...userId })
},
// 退出登录,实现清除token和用户信息
logout(store) {
store.commit('removeToken')
store.commit('removeUserInfo')
}
//在登录页面调用 vuex中的登录函数
//语法:this.$store.dispath('模块名/方法名',参数) this.$store.dispath('user/login',this.loginForm)
//--------------------------------------------------
//在src/store/index.js中4
import Vue from 'vue'
// 引入库
import Vuex from 'vuex'
// 注册
Vue.use(Vuex)
// 创建实例
const store = new Vuex.Store({
modules: {
user,
},
})
// 导出
export default store