2路由基础
<router-link> <a>
<router-view/> 渲染组件
路由对象
path
component/components
children:[
{子集}
]
name 命名 :to="{ name: ‘about‘ }"
alias 别名
redirect: to => ‘/‘ 重定向
path: ‘/argu/:name‘ $route.params.name
this.$router
.back() / .go(-1)
.push({
name: `argu`,
params: {
name: ‘lison‘
})
.push({
path: `/argu/$(name)`
})
.replace()
3路由进阶
props: true 把值传到组件里面
props: {
food: ‘banana‘
},
/?food=xxxx
props: route => ({
food: route.query.food
}),
* 1. 导航被触发
* 2. 在失活的组件(即将离开的页面组件)里调用离开守卫 beforeRouteLeave
* 3. 调用全局的前置守卫 beforeEach
* 4. 在重用的组件里调用 beforeRouteUpdate
* 5. 调用路由独享的守卫 beforeEnter
* 6. 解析异步路由组件
* 7. 在被激活的组件(即将进入的页面组件)里调用 beforeRouteEnter
* 8. 调用全局的解析守卫 beforeResolve
* 9. 导航被确认
* 10. 调用全局的后置守卫 afterEach
* 11. 触发DOM更新
* 12. 用创建好的实例调用beforeRouterEnter守卫里传给next的回调函数
meta: {
title: ‘元信息‘
}
router.beforeEach((to, from, next) => {
to.meta && setTitle(to.meta.title)
})
to 对象 即将跳转
from 对象 离开的页面
next 函数 跳转
5 vuex-state_getter
this.$store.state.user.userName
const getters = {
appNameWithVersion: (state) => {
return `${state.appName}v2.0`
}
}
import { mapState, mapGetters } from ‘vuex‘ // 未开启命名空间
computed:{
...mapState(‘展开一个对象‘), // 等于 userName: state => state.user.userName
...mapGetters([
‘appNameWithVersion‘,
]),
}
6 vuex-mutation_action_module
import { mapMutations, mapActions } from ‘vuex‘
const mutations = {
SET_APP_NAME (state, params) {
state.appName = params
},
}
async updateAppName ({ commit }) {
try {
const { info: { appName } } = await getAppName()
commit(‘SET_APP_NAME‘, appName)
} catch (err) {
console.log(err)
}
}
methods: {
...mapMutations([ //同步
‘SET_APP_NAME‘
]),
...mapActions([ //异步
‘updateAppName‘
]),
handleChangeAppName () {
this.$store.commit({
type: ‘SET_APP_NAME‘,
appName: ‘newAppName‘
}),
this.SET_APP_NAME({
appName: ‘newAppName‘
}),
this.$store.dispatch(‘updateAppName‘, ‘123‘)
}
}
vue.set(state, ‘appVersion‘, ‘v2.0‘) // 如果state 初始化没有 变量,需要用set,才会增加 set,get方法
7 vuex_插件_持久化存储
export default store => {
if (localStorage.state) store.replaceState(JSON.parse(localStorage.state))
store.subscribe((mutation, state) => {
localStorage.state = JSON.stringify(state)
})
}
plugins: [ saveInLocal ] // 启用
严格模式 // 开启后,直接修改state,会报错
strict: process.env.NODE_ENV === ‘development‘,
<a-input v-model="stateValue"/> // 绑定是值 是 store里面的 双向绑定
stateValue: {
get () {
return this.$store.state.stateValue
},
set (val) {
this.SET_STATE_VALUE(val)
}
},
8 ajax_跨域_封装axios_请求
后端解决跨域
export const getUserInfo = ({ userId }) => {
return axios.request({
url: ‘/getUserInfo‘,
method: ‘post‘,
data: {
userId
}
})
}
getInfo () {
getUserInfo({ userId: 21 }).then(res => {
console.log(‘res: ‘, res)
})
}
14 登录、登出 、JWT认证
handleSubmit () {
this.login({
userName: this.userName,
password: this.password
}).then(() => {
console.log(‘success!!‘)
this.$router.push({
name: ‘home‘
})
}).catch(error => {
console.log(error)
})
}
15 响应式布局
iview-loader
* Layout:布局容器,其下可嵌套 HeaderSiderContentFooter或 Layout 本身,可以放在任何父容器中。
* Header:顶部布局,自带默认样式,其下可嵌套任何元素,只能放在 Layout 中。
* Sider:侧边栏,自带默认样式及基本功能,其下可嵌套任何元素,只能放在 Layout 中。
* Content:内容部分,自带默认样式,其下可嵌套任何元素,只能放在 Layout 中。
* Footer:底部布局,自带默认样式,其下可嵌套任何元素,只能放在 Layout 中。
* 使用row在水平方向创建一行
* 将一组col插入在row中
* 在每个col中,键入自己的内容
* 通过设置col的span参数,指定跨越的范围,其范围是1到24
* 每个row中的col总和应该为24
21 form表单
普通表单
动态表单
22 权限控制
路由控制
data: {
token: ‘xxx‘,
rules: {
page: {
home: true // 页面
},
component: {
edit_button: true,
publish_button: false
}
}
}
export const routes = [
{
path: ‘/login‘,
name: ‘login‘,
component: () => import(‘@/views/login.vue‘)
},
{
path: ‘*‘,
component: () => import(‘@/views/error_404.vue‘)
}
]
----------------------------------------------------------------
import { login, authorization } from ‘@/api/user‘
import { setToken } from ‘@/lib/util‘
const state = {
userName: ‘Lison‘,
rules: {} // 组件基本权限 存储
}
const mutations = {
SET_RULES (state, rules) {
state.rules = rules
}
}
const actions = {
authorization ({ commit }, token) {
return new Promise((resolve, reject) => {
authorization().then(res => {
if (parseInt(res.code) === 401) {
reject(new Error(‘token error‘))
} else {
setToken(res.data.token)
resolve(res.data.rules.page)
commit(‘SET_RULES‘, res.data.rules.component)
}
}).catch(error => {
reject(error)
})
})
}
}
-------------------------------------------------------------------
import { routes, routerMap } from ‘@/router/router‘
const state = {
routers: routes,
hasGetRules: false
}
const mutations = {
CONCAT_ROUTES (state, routerList) {
state.routers = routerList.concat(routes) // 合并路由
state.hasGetRules = true // 已经获取到 路由权限
}
}
const getAccesRouterList = (routes, rules) => {
return routes.filter(item => {
if (rules[item.name]) {
if (item.children) item.children = getAccesRouterList(item.children, rules)
return true
} else return false
})
}
const actions = {
concatRoutes ({ commit }, rules) {
return new Promise((resolve, reject) => {
try {
let routerList = []
if (Object.entries(rules).every(item => item[1])) {
routerList = routerMap
} else {
routerList = getAccesRouterList(routerMap, rules) // 可以访问的路由列表
}
commit(‘CONCAT_ROUTES‘, routerList) // 设置路由
resolve(routerList)
} catch (err) {
reject(err)
}
})
}
}
---------------------------------------------------
if (!store.state.router.hasGetRules) {
store.dispatch(‘authorization‘).then(rules => {
store.dispatch(‘concatRoutes‘, rules).then(routers => {
router.addRoutes(clonedeep(routers))
next({ ...to, replace: true })
}).catch(() => {
next({ name: ‘login‘ })
})
})
}
--------------------------------------------------
组件基本判断
<Button v-if="rules.edit_button">编辑</Button>
原文:http://blog.51cto.com/hequan/2318253