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://www.bubuko.com/infodetail-2850647.html