Vue 筆記(三)- vuex, vue-router

Vuex

作用:管理多個組件或者全局共享的狀態(tài)。
將復(fù)雜的玉凯、需要共享的邏輯處理放入actions中共享。

( 為什么在store中執(zhí)行Vue.use(Vuex),而不是在main.js中屡萤?
執(zhí)行順序問題。腳手架處理文件中的 import x from './yyy' 這類語句時掸宛,不管它們位置如何死陆,相當于放在文件開頭執(zhí)行。)

1.概念

在Vue中實現(xiàn)集中式狀態(tài)(數(shù)據(jù))管理的一個Vue插件唧瘾,對vue應(yīng)用中多個組件的共享狀態(tài)進行集中式的管理(讀/寫)措译,也是一種組件間通信的方式,且適用于任意組件間通信饰序。

2.何時使用领虹?

多個組件需要共享數(shù)據(jù)時

3.搭建vuex環(huán)境

  1. 創(chuàng)建文件:src/store/index.js
//引入Vue核心庫
import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'
//應(yīng)用Vuex插件
Vue.use(Vuex)

//準備actions對象——響應(yīng)組件中用戶的動作
const actions = {}
//準備mutations對象——修改state中的數(shù)據(jù)
const mutations = {}
//準備state對象——保存具體的數(shù)據(jù)
const state = {}

//創(chuàng)建并暴露store
export default new Vuex.Store({
    actions,
    mutations,
    state
})
  1. main.js中創(chuàng)建vm時傳入store配置項
......
//引入store
import store from './store'
......

//創(chuàng)建vm
new Vue({
    el:'#app',
    render: h => h(App),
    store
})

4.基本使用

  1. 初始化數(shù)據(jù)、配置actions求豫、配置mutations塌衰,操作文件store.js
//引入Vue核心庫
import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'
//引用Vuex
Vue.use(Vuex)

const actions = {
    //響應(yīng)組件中加的動作
    jia(context,value){
        // console.log('actions中的jia被調(diào)用了',miniStore,value)
        context.commit('JIA',value)
    },
}

const mutations = {
    //執(zhí)行加
    JIA(state,value){
        // console.log('mutations中的JIA被調(diào)用了',state,value)
        state.sum += value
    }
}

//初始化數(shù)據(jù)
const state = {
   sum:0
}

//創(chuàng)建并暴露store
export default new Vuex.Store({
    actions,
    mutations,
    state,
})
  1. 組件中讀取vuex中的數(shù)據(jù):$store.state.sum
  2. 組件中修改vuex中的數(shù)據(jù):$store.dispatch('action中的方法名',數(shù)據(jù))$store.commit('mutations中的方法名',數(shù)據(jù))

備注:若沒有網(wǎng)絡(luò)請求或其他業(yè)務(wù)邏輯,組件中也可以越過actions蝠嘉,即不寫dispatch最疆,直接編寫commit

5.getters的使用

  1. 概念:當state中的數(shù)據(jù)需要經(jīng)過加工后再使用時,可以使用getters加工蚤告。(當處理過程需要復(fù)用時努酸。)
  2. store.js中追加getters配置
    ......
    
    const getters = {
     bigSum(state){
         return state.sum * 10
     }
    }
    
    //創(chuàng)建并暴露store
    export default new Vuex.Store({
     ......
     getters
    })
    
  3. 組件中讀取數(shù)據(jù):$store.getters.bigSum

6.四個map方法的使用

  1. mapState方法:用于幫助我們映射state中的數(shù)據(jù)為計算屬性(不必在模板中寫$store.state.sum.xxx,也不必在computed中自己去寫多個方法返回數(shù)據(jù))杜恰。

    computed: {
        //借助mapState生成計算屬性:sum获诈、school、subject(對象寫法)
         ...mapState({sum:'sum',school:'school',subject:'subject'}),
             
        //借助mapState生成計算屬性:sum心褐、school烙荷、subject(數(shù)組寫法)
        ...mapState(['sum','school','subject']),
    },
    
  2. mapGetters方法:用于幫助我們映射getters中的數(shù)據(jù)為計算屬性

    computed: {
        //借助mapGetters生成計算屬性:bigSum(對象寫法)
        ...mapGetters({bigSum:'bigSum'}),
    
        //借助mapGetters生成計算屬性:bigSum(數(shù)組寫法)
        ...mapGetters(['bigSum'])
    },
    
  3. mapActions方法:用于幫助我們生成與actions對話的方法,即:包含$store.dispatch(xxx)的函數(shù)

    methods:{
        //靠mapActions生成:incrementOdd檬寂、incrementWait(對象形式)
        ...mapActions({incrementOdd:'jiaOdd',incrementWait:'jiaWait'})
    
        //靠mapActions生成:incrementOdd终抽、incrementWait(數(shù)組形式)
        ...mapActions(['jiaOdd','jiaWait'])
    }
    
  4. mapMutations方法:用于幫助我們生成與mutations對話的方法,即:包含$store.commit(xxx)的函數(shù)

    methods:{
        //靠mapActions生成:increment、decrement(對象形式)
        ...mapMutations({increment:'JIA',decrement:'JIAN'}),
        
        //靠mapMutations生成:JIA昼伴、JIAN(數(shù)組形式)
        ...mapMutations(['JIA','JIAN']),
    }
    

備注:mapActions與mapMutations使用時匾旭,若需要傳遞參數(shù)需要:在模板中綁定事件時傳遞好參數(shù),否則參數(shù)是事件對象圃郊。

7.模塊化+命名空間

  1. 目的:讓代碼更好維護价涝,讓多種數(shù)據(jù)分類更加明確。
  2. 修改store.js
    const countAbout = {
      namespaced:true,//開啟命名空間
      state:{x:1},
      mutations: { ... },
      actions: { ... },
      getters: {
        bigSum(state){
           return state.sum * 10
        }
      }
    }
    
    const personAbout = {
      namespaced:true,//開啟命名空間
      state:{ ... },
      mutations: { ... },
      actions: { ... }
    }
    
    const store = new Vuex.Store({
      modules: {
        countAbout,
        personAbout
      }
    })
    
  3. 開啟命名空間后持舆,組件中讀取state數(shù)據(jù):
    //方式一:自己直接讀取
    this.$store.state.personAbout.list
    //方式二:借助mapState讀壬瘛:
    ...mapState('countAbout',['sum','school','subject']),
    
  4. 開啟命名空間后,組件中讀取getters數(shù)據(jù):
    //方式一:自己直接讀取
    this.$store.getters['personAbout/firstPersonName']
    //方式二:借助mapGetters讀纫菰ⅰ:
    ...mapGetters('countAbout',['bigSum'])
    
  5. 開啟命名空間后居兆,組件中調(diào)用dispatch
    //方式一:自己直接dispatch
    this.$store.dispatch('personAbout/addPersonWang',person)
    //方式二:借助mapActions:
    ...mapActions('countAbout',{incrementOdd:'jiaOdd',incrementWait:'jiaWait'})
    
  6. 開啟命名空間后,組件中調(diào)用commit
    //方式一:自己直接commit
    this.$store.commit('personAbout/ADD_PERSON',person)
    //方式二:借助mapMutations:
    ...mapMutations('countAbout',{increment:'JIA',decrement:'JIAN'}),
    

補充:
啟用module寫法竹伸,但不設(shè)置namespaced時:actions, mutations, getters 依然掛在全局泥栖,使用方式無變化。對于state:$store.state.a勋篓。
此時使用mapState吧享,兩種寫法均報錯,原因不明譬嚣。

路由

  1. 理解: 一個路由(route)就是一組映射關(guān)系(key - value)钢颂,多個路由需要路由器(router)進行管理。
  2. 前端路由:key是路徑拜银,value是組件甸陌。

1.基本使用

  1. 安裝vue-router,命令:npm i vue-router
  2. 應(yīng)用插件:Vue.use(VueRouter)
  3. 編寫router配置項:
//引入VueRouter
import VueRouter from 'vue-router'
//引入Luyou 組件
import About from '../components/About'
import Home from '../components/Home'

//創(chuàng)建router實例對象盐股,去管理一組一組的路由規(guī)則
const router = new VueRouter({
  routes:[
    {
      path:'/about',
      component:About
    },
    {
      path:'/home',
      component:Home
    }
  ]
})

//暴露router
export default router
  1. 實現(xiàn)切換(active-class可配置高亮樣式)
<router-link active-class="active" to="/about">About</router-link>
  1. 指定展示位置
<router-view></router-view>

2.幾個注意點

  1. 路由組件通常存放在pages文件夾钱豁,一般組件通常存放在components文件夾。
  2. 通過切換疯汁,“隱藏”了的路由組件牲尺,默認是被銷毀掉的,需要的時候再去掛載幌蚊。
  3. 每個組件都有自己的$route屬性谤碳,里面存儲著自己的路由信息。
  4. 整個應(yīng)用只有一個router溢豆,可以通過組件的$router屬性獲取到蜒简。

3.多級路由(嵌套路由)

  1. 配置路由規(guī)則,使用children配置項:
routes:[
  {
    path:'/about',
    component:About,
  },
  {
    path:'/home',
    component:Home,
    children:[ //通過children配置子級路由
      {
        path:'news', //此處一定不要寫:/news
        component:News
      },
      {
        path:'message',//此處一定不要寫:/message
        component:Message
      }
    ]
  }
]
  1. 跳轉(zhuǎn)(要寫完整路徑):
<router-link to="/home/news">News</router-link>

4.路由的query參數(shù)

  1. 傳遞參數(shù)
<!-- 跳轉(zhuǎn)并攜帶query參數(shù)漩仙,to的字符串寫法 -->
<router-link :to="/home/message/detail?id=666&title=你好">跳轉(zhuǎn)</router-link>
        
<!-- 跳轉(zhuǎn)并攜帶query參數(shù)搓茬,to的對象寫法 -->
<router-link 
  :to="{
    path:'/home/message/detail',
    query:{
       id:666,
       title:'你好'
    }
  }"
>跳轉(zhuǎn)</router-link>
  1. 接收參數(shù):
$route.query.id
$route.query.title

5.命名路由

1.作用:可以簡化路由的跳轉(zhuǎn)犹赖。
2.如何使用
(1).給路由命名:

{
  path:'/demo',
  component:Demo,
  children:[
    {
      path:'test',
      component:Test,
      children:[
        {
          name:'hello', //給路由命名
          path:'welcome',
          component:Hello,
        }
      ]
    }
  ]
}

(2).簡化跳轉(zhuǎn):

<!--簡化前,需要寫完整的路徑 -->
<router-link to="/demo/test/welcome">跳轉(zhuǎn)</router-link>

<!--簡化后卷仑,直接通過名字跳轉(zhuǎn) -->
<router-link :to="{name:'hello'}">跳轉(zhuǎn)</router-link>

<!--簡化寫法配合傳遞參數(shù) -->
<router-link 
  :to="{
    name:'hello',
    query:{
       id:666,
      title:'你好'
    }
  }"
>跳轉(zhuǎn)</router-link>

6.路由的params參數(shù)

  1. 配置路由峻村,聲明接收params參數(shù)
{
    path:'/home',
    component:Home,
    children:[
        {
            path:'news',
            component:News
        },
        {
            component:Message,
            children:[
                {
                    name:'xiangqing',
                    path:'detail/:id/:title', //使用占位符聲明接收params參數(shù)
                    component:Detail
                }
            ]
        }
    ]
}
  1. 傳遞參數(shù)
<!-- 跳轉(zhuǎn)并攜帶params參數(shù),to的字符串寫法 -->
<router-link :to="/home/message/detail/666/你好">跳轉(zhuǎn)</router-link>
                
<!-- 跳轉(zhuǎn)并攜帶params參數(shù)锡凝,to的對象寫法 -->
<router-link 
  :to="{
    name:'xiangqing',
    params:{
      id:666,
      title:'你好'
    }
  }"
>跳轉(zhuǎn)</router-link>

特別注意:路由攜帶params參數(shù)時粘昨,若使用to的對象寫法,則不能使用path配置項窜锯,必須使用name配置张肾!(為什么?)

  1. 接收參數(shù):
$route.params.id
$route.params.title

7.路由的props配置

作用:讓路由組件更方便的收到參數(shù)锚扎,直接從props中拿到xxx吞瞪,而不必寫$route.query.xxx (路由組件指作為頁面的組件)。

{
    name:'xiangqing',
    path:'detail/:id',
    component:Detail,

    //第一種寫法:props值為對象工秩,該對象中所有的key-value的組合最終都會通過props傳給Detail組件
    // props:{a:900}

    //第二種寫法:props值為布爾值,布爾值為true进统,則把路由收到的所有params參數(shù)通過props傳給Detail組件
    // props:true
    
    //第三種寫法:props值為函數(shù)助币,該函數(shù)返回的對象中每一組key-value都會通過props傳給Detail組件
    props(route){
        return {
            id:route.query.id,
            title:route.query.title
        }
    }
}

8.<router-link>的replace屬性

  1. 作用:控制路由跳轉(zhuǎn)時操作瀏覽器歷史記錄的模式
  2. 瀏覽器的歷史記錄有兩種寫入方式:分別為pushreplacepush是追加歷史記錄螟碎,replace是替換當前記錄眉菱。路由跳轉(zhuǎn)時候默認為push
  3. 如何開啟replace模式:<router-link replace .......>News</router-link>

9.編程式路由導(dǎo)航

  1. 作用:不借助<router-link>實現(xiàn)路由跳轉(zhuǎn),讓路由跳轉(zhuǎn)更加靈活
  2. 具體編碼:
//$router的兩個API
this.$router.push({
  name:'xiangqing',
  params:{
    id:xxx,
    title:xxx
  }
})

this.$router.replace({
  name:'xiangqing',
  params:{
    id:xxx,
    title:xxx
  }
})
this.$router.forward() //前進
this.$router.back() //后退
this.$router.go() //可前進也可后退掉分,傳入數(shù)字

10.緩存路由組件

  1. 作用:讓不展示的路由組件保持掛載俭缓,不被銷毀川慌。(include屬性傳組件名躏结,即組件配置項中的name)
  2. 具體編碼:
<keep-alive include="News"> 
    <router-view></router-view>
</keep-alive>

11.兩個新的生命周期鉤子

  1. 作用:路由組件所獨有的兩個鉤子嘉裤,用于捕獲路由組件的激活狀態(tài)播急。(路由切換至當前組件時激活挣饥,切換至其它組件時失活)
  2. 具體名字:
    1. activated路由組件被激活時觸發(fā)马昨。
    2. deactivated路由組件失活時觸發(fā)把曼。

12.路由守衛(wèi)

  1. 作用:對路由進行權(quán)限控制
  2. 分類:全局守衛(wèi)胡岔、獨享守衛(wèi)椿息、組件內(nèi)守衛(wèi)
  3. 全局守衛(wèi):
//全局前置守衛(wèi):初始化時執(zhí)行歹袁、每次路由切換前執(zhí)行
router.beforeEach((to,from,next)=>{
    console.log('beforeEach',to,from)
    if(to.meta.isAuth){ //判斷當前路由是否需要進行權(quán)限控制
        if(localStorage.getItem('school') === 'atguigu'){ //權(quán)限控制的具體規(guī)則
            next() //放行
        }else{
            alert('暫無權(quán)限查看')
            // next({name:'guanyu'})
        }
    }else{
        next() //放行
    }
})

//全局后置守衛(wèi):初始化時執(zhí)行、每次路由切換后執(zhí)行
router.afterEach((to,from)=>{
    console.log('afterEach',to,from)
    if(to.meta.title){ 
        document.title = to.meta.title //修改網(wǎng)頁的title
    }else{
        document.title = 'vue_test'
    }
})

($route的meta項中可以放一些關(guān)于路由的自定義信息)

  1. 獨享守衛(wèi):
beforeEnter(to,from,next){
    console.log('beforeEnter',to,from)
    if(to.meta.isAuth){ //判斷當前路由是否需要進行權(quán)限控制
        if(localStorage.getItem('school') === 'atguigu'){
            next()
        }else{
            alert('暫無權(quán)限查看')
            // next({name:'guanyu'})
        }
    }else{
        next()
    }
}
  1. 組件內(nèi)守衛(wèi):
//進入守衛(wèi):通過路由規(guī)則寝优,進入該組件時被調(diào)用
beforeRouteEnter (to, from, next) {
  //  
},
//離開守衛(wèi):通過路由規(guī)則条舔,離開該組件時被調(diào)用
beforeRouteLeave (to, from, next) {
}

(路由文件中的beforeEnter和組件內(nèi)的beforeRouteEnter區(qū)別之一是后者可以操作組件內(nèi)的data和methods等。
導(dǎo)航解析流程:先在路由配置里調(diào)用 beforeEnter乏矾,再在被激活的組件里調(diào)用 beforeRouteEnter孟抗,若前者未通過迁杨,則后者不會被調(diào)用)

13.路由器的兩種工作模式

  1. 對于一個url來說,什么是hash值夸浅?—— #及其后面的內(nèi)容就是hash值仑最。
  2. hash值不會包含在 HTTP 請求中,即:hash值不會帶給服務(wù)器帆喇。
  3. hash模式:
    1. 地址中永遠帶著#號警医,不美觀 。
    2. 若以后將地址通過第三方手機app分享坯钦,若app校驗嚴格预皇,則地址會被標記為不合法。
    3. 兼容性較好婉刀。
  4. history模式:
    1. 地址干凈吟温,美觀 。
    2. 兼容性和hash模式相比略差突颊。
    3. 應(yīng)用部署上線時需要后端人員支持鲁豪,解決刷新頁面服務(wù)端404的問題。(將所有對頁面的請求都返回index.html)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末律秃,一起剝皮案震驚了整個濱河市爬橡,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌棒动,老刑警劉巖糙申,帶你破解...
    沈念sama閱讀 212,294評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異船惨,居然都是意外死亡柜裸,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,493評論 3 385
  • 文/潘曉璐 我一進店門粱锐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來疙挺,“玉大人,你說我怎么就攤上這事怜浅∠瓮常” “怎么了?”我有些...
    開封第一講書人閱讀 157,790評論 0 348
  • 文/不壞的土叔 我叫張陵海雪,是天一觀的道長锦爵。 經(jīng)常有香客問我,道長奥裸,這世上最難降的妖魔是什么险掀? 我笑而不...
    開封第一講書人閱讀 56,595評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮湾宙,結(jié)果婚禮上樟氢,老公的妹妹穿的比我還像新娘冈绊。我一直安慰自己,他們只是感情好埠啃,可當我...
    茶點故事閱讀 65,718評論 6 386
  • 文/花漫 我一把揭開白布死宣。 她就那樣靜靜地躺著,像睡著了一般碴开。 火紅的嫁衣襯著肌膚如雪毅该。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,906評論 1 290
  • 那天潦牛,我揣著相機與錄音眶掌,去河邊找鬼。 笑死巴碗,一個胖子當著我的面吹牛朴爬,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播橡淆,決...
    沈念sama閱讀 39,053評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼召噩,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了逸爵?” 一聲冷哼從身側(cè)響起具滴,我...
    開封第一講書人閱讀 37,797評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎痊银,沒想到半個月后抵蚊,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體施绎,經(jīng)...
    沈念sama閱讀 44,250評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡溯革,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,570評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了谷醉。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片致稀。...
    茶點故事閱讀 38,711評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖俱尼,靈堂內(nèi)的尸體忽然破棺而出抖单,到底是詐尸還是另有隱情,我是刑警寧澤遇八,帶...
    沈念sama閱讀 34,388評論 4 332
  • 正文 年R本政府宣布矛绘,位于F島的核電站,受9級特大地震影響刃永,放射性物質(zhì)發(fā)生泄漏货矮。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 40,018評論 3 316
  • 文/蒙蒙 一斯够、第九天 我趴在偏房一處隱蔽的房頂上張望囚玫。 院中可真熱鬧喧锦,春花似錦、人聲如沸抓督。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,796評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽铃在。三九已至阵具,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間涌穆,已是汗流浹背怔昨。 一陣腳步聲響...
    開封第一講書人閱讀 32,023評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留宿稀,地道東北人趁舀。 一個月前我還...
    沈念sama閱讀 46,461評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像祝沸,于是被迫代替她去往敵國和親矮烹。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,595評論 2 350

推薦閱讀更多精彩內(nèi)容

  • 除了在組件式方面vue和react有異曲同工之妙之外罩锐,vuex和redux也非常像奉狈,vue進入2.0版本,還得到了...
    brandonxiang閱讀 1,813評論 0 1
  • #vue2筆記 ##腳手架文件結(jié)構(gòu) ├──node_modules ├──public │├──favicon.i...
    Daydream_許多閱讀 426評論 0 0
  • 筆記 腳手架文件結(jié)構(gòu) 關(guān)于不同版本的Vue vue.js與vue.runtime.xxx.js的區(qū)別:vue.js...
    jjbnxy閱讀 152評論 0 0
  • 由于Vuex的官方文檔在各個模塊之間缺乏一些過渡涩惑,另外新概念很多仁期,使得初讀時總有些云里霧里的感覺。于是本文在官方文...
    一郭鮮閱讀 352評論 0 1
  • 系列文章:Vue 2.0 升(cai)級(keng)之旅Vuex — The core of Vue applic...
    6ed7563919d4閱讀 4,544評論 2 58