vue技術棧開發實戰--學習筆記2
阿新 • • 發佈:2018-11-17
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>