.sync修饰符
.sync修饰符可以实现子组件与父组件的双向绑定,并且可以实现子组件同步修改父组件的值。
一般情况下,想要实现父子组件间值的传递,通常使用的是 props 和自定义事件 $emit 。
其中,父组件通过 props 将值传给子组件,子组件再通过 $emit 将值传给父组件,父组件通过事件监听获取子组件传过来的值。
如果想要简化这里的代码,可以使用.sync修饰符,实际上就是一个语法糖。
//子组件怎么来修改父组件传过来的值,而不会报错
//父组件
<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/components/lang.vue
<template>
<el-dropdown trigger="click" @command="changeLanguage">
<!-- 这里必须加一个div -->
<div>
<svg-icon style="color:#fff;font-size:20px" icon-class="language" />
</div>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item command="zh" :disabled="'zh'=== $i18n.locale ">中文</el-dropdown-item>
<el-dropdown-item command="en" :disabled="'en'=== $i18n.locale ">en</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</template>
<script>
export default {
methods: {
changeLanguage(lang) {
this.$i18n.locale = lang // 设置给本地的i18n插件
this.$message.success('切换多语言成功')
}
}
}
</script>
/*mian.js引入
import lang from './components/lang.vue'
注册全局组件
Vue.component('lang', lang)
*/
<template>
<div>
<button @click="lang='en'">英文</button>
<button @click="lang='zh'">中文</button>
<p>{{ t('hello') }}</p>
</div>
</template>
<script>
export default {
data() {
return {
lang: 'en', // zh表示中文,en表示英文
// 中英文对照表
message: {
zh: {
hello: '你好'
},
en: {
hello: 'Hello'
}
}
}
},
methods: {
// 根据当前的语音标识符找到对应的语言的字典表
t(str) {
const curLang = this.message[this.lang]
// 根据函数传入的标识符查找对应的文字并返回
// 如果找不到对应的标识符就直接返回原数据
return curLang[str] || str
}
}
}
</script>
<style>
</style>
导航守卫
//src/permission.js
// 导航守卫
import router from './router/index'
import store from './store/index'
// import { asyncRoutes } from './router/index'
router.beforeEach(async(to, from, next) => {
// to:跳转的目标路由对象
// from:跳转之前的路由对象
// 取出token
if (store.getters.token) {
// 登录后不能进入登录页面
if (to.path === '/login') {
next('/')
} else {
await store.dispatch('user/getUserInfo')
// 获取路由权限数组,把筛选处理的数组合并到原来的路由规则中
const routes = await store.dispatch('permiss/filterRoutes', store.state.user.userInfo.roles.menus)
// 获取到了具有权限的路由对象,合并到原来的路由规则中
// router.addRoutes(动态路由规则数组):合并动态路由
// 解决刷新后跳转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