1. 程式人生 > >vue技術棧開發實戰--學習筆記2

vue技術棧開發實戰--學習筆記2

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>