手挽手帶你學VUE:四檔 Vue-cli3 Vuex Vue-router

Mr.奇淼發表於2019-01-03

視訊教程

由於掘金不支援視訊連結,視訊請移步 www.henrongyi.top

你能學到什麼

在這一期的學習進度中,我們會開始學習在我們工作開發中真正要使用的開發模式,vue-cli3腳手架的運用以及Vue-router和狀態管理倉Vuex

Vue-cli3搭建前置

安裝node環境

因為Vue-cli3也是基於webpack搭建的,所以我們還是必須要用到node,如果你的電腦還沒有安裝node的話,可以到node官網自行下載安裝,nodejs.org/zh-cn/ 推薦大家下載10.14.0版本。 安裝過後 到命令列執行 node -v 檢查版本,如果彈出版本 v10.14.0的話 恭喜你 安裝成功,我們開始進行下面的步驟了。

全域性安裝vue-cli3 Vue CLI 的包名稱由 vue-cli 改成了 @vue/cli。 如果你已經全域性安裝了舊版本的 vue-cli (1.x 或 2.x),你需要先通過 npm uninstall vue-cli -g 解除安裝它。

官方要求安裝的node版本是大於8.9的,我們安裝的node為10.14.0,如果你本身的版本低於8.9 那麼可以用nvm進行升級

然後我們到命令列執行

npm install -g @vue/cli
複製程式碼

等待執行完畢,我們命令列執行

vue --version
複製程式碼

如果版本在3.0以上,恭喜你安裝成功了

接下來我們在命令列執行

vue create hello-world
複製程式碼

這時候它會提醒我們來選擇需要安裝的選項

Vue CLI v3.1.3
┌───────────────────────────┐
│  Update available: 3.2.1  │
└───────────────────────────┘
? Please pick a preset: (Use arrow keys)
> my (vue-router, vuex, less, babel, eslint)
  default (babel, eslint)
  Manually select features
複製程式碼

第一個是我已經儲存過的了,我們初次搭建,選擇 Manually select features

Vue CLI v3.1.3
┌───────────────────────────┐
│  Update available: 3.2.1  │
└───────────────────────────┘
? Please pick a preset: Manually select features
? Check the features needed for your project: (Press <space> to select, <a> to toggle all, <i> to invert selection)
>( ) Babel
 ( ) TypeScript
 ( ) Progressive Web App (PWA) Support
 ( ) Router
 ( ) Vuex
 ( ) CSS Pre-processors
 ( ) Linter / Formatter
 ( ) Unit Testing
 ( ) E2E Testing
複製程式碼

我們看到如上介面以後,選擇 Babel Router Vuex CSS Pre-processors (使用空格鍵選中) 進行下一步

Vue CLI v3.1.3
┌───────────────────────────┐
│  Update available: 3.2.1  │
└───────────────────────────┘
? Please pick a preset: Manually select features
? Check the features needed for your project: Babel, Router, Vuex, CSS Pre-processors
? Use history mode for router? (Requires proper server setup for index fallback in production) Yes
? Pick a CSS pre-processor (PostCSS, Autoprefixer and CSS Modules are supported by default): Sass/SCSS
? Where do you prefer placing config for Babel, PostCSS, ESLint, etc.? In package.json
? Save this as a preset for future projects? Yes
? Save preset as: MyTest
複製程式碼

接下來大家按照如上配置,基本可以完成專案搭建。等待安裝完畢後執行


cd helloworld
npm run serve

複製程式碼

進入瀏覽器 開啟 localhost:8080 如果看到Vue的歡迎介面,恭喜你,我們已經邁出成功第一步了

ui圖形化配置介面

在Vue-cli3 中 為大家提供了圖形化配置介面 執行


vue ui 

複製程式碼

會開到提示在 localhost:8000開啟了UI配置介面,由於個人感覺圖形化配置還是不靈活的,這裡就先不給大家做太多演示了,要想做好一個VUE專案,需要做太多的搭配,我這裡會配置一套基本可以使用的VUE框架放到個人github供大家使用。

.vue檔案的基本結構

<template>
  <!-- 這裡面寫html -->
</template>

<script>
// 如果要引入外部的檔案 請在 export default外面引入
// 例如  // @ is an alias to /src
import HelloWorld from '@/components/HelloWorld.vue'  //這裡引入了 HelloWorld元件

export default {
  name: 'home',
  components: {
    HelloWorld  //使用元件
  }
}
export default {
  name:'vue', //這裡面就寫VUE元件內的屬性即可
}

</script>

<style>
/* 這裡寫css 當然你也可以寫 lass scss 需要babel支援並且在 style上新增 lang屬性 例如   <style lang="scss"> */
</style>
複製程式碼

Vue-Router

我們使用VUE一般是用來開發單頁程式,那麼在單頁程式內的跳轉就要用到路由的形式,由於這裡課程是要帶大家快速熟悉VUE並且使用VUE,所以原理這裡暫且跳過,直接告訴大家使用方法。 我們在開始選擇框架要用到的東西的時候已經選擇了Vue-Router,這裡我們直接上程式碼使用即可。我們這裡就搭配著Vue-Cli3的腳手架來講解,這裡順便為大家講解一下Vue-cli3腳手架為我們建立的目錄結構

│ .gitignore git遮蔽提交檔案 │ babel.config.js 自定義babel的地方 │ package.json 你的所有依賴啥的 │ README.md 不介紹 │ yarn.lock yarn 如果你是 npm 就是 package-lock.json │
├─public 通過執行 npm run build 產生 │ favicon.ico │ index.html │
└─src 主要我們要修改的地方 │ App.vue App主元件 │ main.js 入口JS │ router.js 路由檔案 │ store.js vueX store 檔案 │
├─assets 靜態檔案存放處 │ logo.png │
├─components 我們自己寫的元件 │ HelloWorld.vue │
└─views VUE頁面,這麼安排為了方便區分是元件還是用於路由跳轉的頁面 About.vue Home.vue

我們直接看到入口檔案

// main.js

import Vue from 'vue'
import App from './App.vue'
import router from './router'   //在入口檔案引用了router 並且 在newVue的時候 把router掛在到了router屬性上
import store from './store'

Vue.config.productionTip = false

new Vue({
  router,   // 掛載
  store,
  render: h => h(App)
}).$mount('#app')

複製程式碼

接著我們看到 router.js檔案

//router.js

import Vue from 'vue'
import Router from 'vue-router'  //這裡引用了vue-router 並且用Vue.use來使用Router
import Home from './views/Home.vue'

Vue.use(Router)

// Router的內建屬性
export default new Router({
  mode: 'history',  //要使用hash模式還是 history模式 我們一般情況下還是用 hash模式 history在後臺支援的情況下可以開啟
  base: process.env.BASE_URL,  // 應用的基路徑。例如,如果整個單頁應用服務在 /app/ 下,然後 base 就應該設為 "/app/"
  routes: [              //這就是真正寫路由的地方了 
    {
      path: '/',        //  當路由是/的時候 我們匹配哪個元件(這裡是Home.vue)
      name: 'home',
      component: Home
    },
    {
      path: '/about',   //  當路由是/about的時候 我們匹配哪個元件(About.vue)
      name: 'about',
      // route level code-splitting
      // this generates a separate chunk (about.[hash].js) for this route
      // which is lazy-loaded when the route is visited.
      component: () => import(/* webpackChunkName: "about" */ './views/About.vue')   //路遊懶載入,推薦使用這種模式,不過我們需要改寫一下
    }
  ]
})

複製程式碼

稍微做一下懶載入模式的改寫

//router.js

import Vue from 'vue'
import Router from 'vue-router'  //這裡引用了vue-router 並且用Vue.use來使用Router

Vue.use(Router)

const Home = ()=> import('./views/Home.vue')   //使用常量模式 提前宣告 並且在component中使用 這樣我們就完成了一個可以簡單實用的路由了
const About = ()=> import('./views/About.vue')


// Router的內建屬性
export default new Router({
  mode: 'history',  //要使用hash模式還是 history模式 我們一般情況下還是用 hash模式 history在後臺支援的情況下可以開啟
  base: process.env.BASE_URL,  // 應用的基路徑。例如,如果整個單頁應用服務在 /app/ 下,然後 base 就應該設為 "/app/"
  routes: [              //這就是真正寫路由的地方了 
    {
      path: '/',        //  當路由是/的時候 我們匹配哪個元件(這裡是Home.vue)
      name: 'home',
      component: Home
    },
    {
      path: '/about',   //  當路由是/about的時候 我們匹配哪個元件(About.vue)
      name: 'about',
      // route level code-splitting
      // this generates a separate chunk (about.[hash].js) for this route
      // which is lazy-loaded when the route is visited.
      component: About
    }
  ]
})

複製程式碼

那麼 這些路由元件怎麼展示呢?在哪裡展示呢? 這裡我們要看到 App.vue檔案


<template>
  <div id="app">
    <div id="nav">
      <router-link to="/">Home</router-link> 
       <!-- 使用router-link標籤 新增 to屬性決定我們要路由到什麼地方 -->
      <router-link to="/about">About</router-link>
      
    </div>
    <router-view/>    
    <!-- router-view 就是我們要展示路由的地方  -->
  </div>
</template>

<style>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}
#nav {
  padding: 30px;
}

#nav a {
  font-weight: bold;
  color: #2c3e50;
}

#nav a.router-link-exact-active {
  color: #42b983;
}
</style>
複製程式碼

到這裡 我們一個簡單的基礎的路由已經寫好了 可以使用了

vue-router的子路由

如何建立子路由呢?其實也是相當簡單的

//router.js

import Vue from 'vue'
import Router from 'vue-router'  //這裡引用了vue-router 並且用Vue.use來使用Router

Vue.use(Router)

const Home = ()=> import('./views/Home.vue')   //使用常量模式 提前宣告 並且在component中使用 這樣我們就完成了一個可以簡單實用的路由了
const About = ()=> import('./views/About.vue')
const Children = ()=> import('./views/Children.vue')  //我們引入這個頁面 頁面內容

// Router的內建屬性
export default new Router({
  // mode: 'history',  
  base: process.env.BASE_URL,  
  routes: [
    {
      path: '/',       
      name: 'home',
      component: Home,
      children:[
        {
          path: 'about',  
          name: 'about',
          component: About,
        },
        {
          path:'children',
          name:'children',
          component:Children
        },  //這時候我們訪問 訪問about 實際上是home的子路由了
        // 它是home的子路由,所以我們需要在home裡面再書寫一個路由顯示的元件  <router-view/>   子路由的內容就會顯示在其 router-view下面
      ]
    }
  ]
})

複製程式碼

這裡我把改進後的 app.vue 和 about.vue 等程式碼貼出。

<!-- app -->
<template>
  <div id="app">
    <router-view/>
  </div>
</template>

<style>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}
#nav {
  padding: 30px;
}

#nav a {
  font-weight: bold;
  color: #2c3e50;
}

#nav a.router-link-exact-active {
  color: #42b983;
}
</style>

複製程式碼
<!-- about -->
<template>
  <div class="about">
    <h1>This is an about page</h1>
  </div>
</template>

複製程式碼
<template>
<!-- children -->
  <div class="children">
    <h1>This is an children page</h1>
  </div>
</template>
複製程式碼
<!-- home -->
<template>
  <div class="home">
    <img alt="Vue logo" src="../assets/logo.png">
    <div>
      <!-- <router-link to="/">Home</router-link> | -->
      <router-link to="/about">About</router-link> |
      <router-link to="/children">children</router-link>
    </div>

      <router-view></router-view>
  </div>
</template>

<script>
// @ is an alias to /src
import HelloWorld from '@/components/HelloWorld.vue'

export default {
  name: 'home',
  components: {
    HelloWorld
  }
}
</script>

複製程式碼

vue-router傳參

程式設計式的導航 router.push 程式設計式的導航傳參我們需要使用 this.$router.push() 這個方法 我們有三種傳參方式

<script>
// 字串

// 這種方式可以實現路由跳轉 但是沒有辦法獲取到引數 沒有辦法傳參
this.$router.push("children");
// 物件傳參
// 這裡面我們就要用到路由裡面的name屬性了
// 命名路由傳遞引數需要使用params來傳遞,目標頁面接收傳遞引數時使用this.$route.params
// 特別注意:命名路由這種方式傳遞的引數,如果在目標頁面重新整理是會出錯的
this.$router.push({ name: 'children', params: { userId: 'qm' }})

// 想要傳遞引數主要就是以物件的方式來寫,分為兩種方式:命名路由、查詢引數,下面分別說明兩種方式的用法和注意事項。

// 查詢引數
this.$router.push({ path: '/children', query: { userId: 'qm' }});
// 這種方式引數是暴露在位址列上面的
//查詢引數其實就是在路由地址後面帶上引數和傳統的url引數一致的,傳遞引數使用query而且必須配合path來傳遞引數而不能用name,目標頁面接收傳遞的引數使用query。
//注意:和name配對的是params,和path配對的是query
</script>


複製程式碼

宣告式的導航 宣告式的導航也分為三種方式

<!-- 字串 -->
  <router-link to="children">click to news page</router-link>
<!-- 命名路由 -->
  <router-link :to="{ name: 'children', params: { userId: 'qm'}}">click to news page</router-link>
<!-- 查詢引數 -->
  <router-link :to="{ path: '/children', query: { userId: 'qm'}}">click to news page</router-link>
複製程式碼

1.命名路由搭配params,重新整理頁面引數會丟失 2.查詢引數搭配query,重新整理頁面資料不會丟失 3.接受引數使用this.$router後面就是搭配路由的名稱就能獲取到引數的值

url 傳參

這種傳參方法我們需要在書寫路由的時候做一個小小的改動


//router.js

import Vue from 'vue'
import Router from 'vue-router'

Vue.use(Router)

const Home = ()=> import('./views/Home.vue')   
const About = ()=> import('./views/About.vue')
const Children = ()=> import('./views/Children.vue')

// Router的內建屬性
export default new Router({
  // mode: 'history',  
  base: process.env.BASE_URL,  
  routes: [
    {
      path: '/',       
      name: 'home',
      component: Home,
      children:[
        {
          path: 'about/:id',  // 我們在後面加入/:id 這樣我們在url輸入的地址相應就變成了 /about/3  我們在about元件內 通過 this.$route.params  如何動態監聽路由的變化呢?要知道當我們僅僅引數變化元件可是沒有重新整理的,提示一下 watch可是可以監聽某些資料哦~實戰課程我會帶大家瞭解一下這個該如何運用
          name: 'about',
          component: About,
        },
        {
          path:'children',
          name:'children',
          component:Children
        }, 
      ]
    }
  ]
})

複製程式碼

相應頁面改動如下 home.vue about.vue

<!-- about -->
<template>
  <div class="about">
    <h1>This is an about page</h1>
    {{this.$route.params.id}}
  </div>
</template>

複製程式碼
<!-- home -->
<template>
  <div class="home">
    <img alt="Vue logo" src="../assets/logo.png">
    <div>
      <router-link to="/about/3">About</router-link> |   
      <router-link to="/children">children</router-link>
    </div>

      <router-view></router-view>
  </div>
</template>

<script>
// @ is an alias to /src
import HelloWorld from '@/components/HelloWorld.vue'

export default {
  name: 'home',
  components: {
    HelloWorld
  },
}
</script>

複製程式碼

404的製作

其實vue-router裡面還有很多細節內容,這裡由於我們是基礎課程所以不做太詳細的介紹,相信大家在瀏覽網頁的時候經常會看到404頁面,那麼用我們的vue-router如何去實現一個404呢?實際上是非常簡單的 我們需要在router.js裡面書寫一個通配路徑放置在最後位置,當所有的路徑都不匹配的時候,就會去通配這樣一個404頁面提示大家頁面丟失了,下面我詳細給大家書寫一下

// router.js
import Vue from 'vue'
import Router from 'vue-router'

Vue.use(Router)

const Home = ()=> import('./views/Home.vue')   
const About = ()=> import('./views/About.vue')
const Children = ()=> import('./views/Children.vue')
const NotFound = ()=> import('./views/notFound.vue')

// Router的內建屬性
export default new Router({
  // mode: 'history',  
  base: process.env.BASE_URL,  
  routes: [
    {
      path: '/',       
      name: 'home',
      component: Home,
      children:[
        {
          path: 'about/:id', 
          name: 'about',
          component: About,
        },
        {
          path:'children',
          name:'children',
          component:Children
        },
      ]
    },
    {
      path: '*',
      name: '404',
      component: NotFound,
    }
  ]
})

複製程式碼

學完這些,你對於vue-router的基本運用已經可以算是合格了,工作中的大部分用法也都接觸到了,我們接下來講解vuex。

vuex

首先來一個小demo展示一下vuex的具體用途

// store.js
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    number:0,
  },
  mutations: {
    ADD(state){
      state.number++
    },
    SUB(state){
      state.number--
    }
  },
  actions: {

  }
})
複製程式碼
<!-- children.vue -->
<template>
  <div class="children">
    <h1>This is an children page</h1>
    <button @click="add">
      +
    </button>
      {{$store.state.number}}
      <button  @click="sub">
      -
    </button>
  </div>
</template>

<script>
  export default{
    name: 'children',
    methods: {
      add() {
        this.$store.commit('ADD')
      },
      sub() {
        this.$store.commit('SUB')
      }
    }
  }
</script>
複製程式碼

這樣一個小小的demo實際上已經詮釋了我們vuex的作用,我們需要在重新整理之前永久保留的狀態,並且想要遠距離傳參並且及時做出響應,那麼都可以使用vuex來進行。它就是一個狀態管理和加工的倉庫,一共有五個重要屬性,state,mutations,actions , getter , module 這麼五個小玩意 我會帶大家一個一個認識他們的作用,並且教會大家基本用法,當然了,它也是有較為高階的小用法的。我們實戰課也會使用稍微高階的用法來講解。

state屬性

我們用VUE檔案來類比講解store state就相當於vue中的data屬性,所有的狀態或者說是資料都儲存在這個state裡面,我們在別的地方獲取需要使用 this.$store.state.屬性名稱 來獲取相應的值,並且我們可以通過 mutations 和 actions 來改變state的值,從而觸發所有使用到state的地方重新整理。state裡可以儲存各種資料型別,data裡面可以用的資料型別,state裡面同樣可以使用。

getters屬性

getters我們類比到vue中,那麼它應該是 computed了 我們在使用的時候 要使用 this.$store.getters.屬性名 用法也和computed類似,它實際上是呼叫一個方法,然後獲取到的資料是經過一系列處理後並且return回來的資料,它的具體寫法是。

// store.js
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    number:0,
  },
  mutations: {
    ADD(state){
      state.number++
    },
    SUB(state){
      state.number--
    }
  },
  actions: {

  },
  getters:{
    getNumber(state){   //getter的書寫方法
      return state.number + 100
    }
  }
})
複製程式碼
<!-- children.vue -->
<template>
  <div class="children">
    <h1>This is an children page</h1>
    <button @click="add">
      +
    </button>
      {{$store.state.number}}
      {{$store.getters.getNumber}}
      <!-- getters的基礎呼叫方法,當然還有更高階的 實戰課會講解 -->
      <button  @click="sub">
      -
    </button>
  </div>
</template>

<script>
  export default{
    name: 'children',
    methods: {
      add() {
        this.$store.commit('ADD')
      },
      sub() {
        this.$store.commit('SUB')
      }
    }
  }
</script>
複製程式碼

這就是getters的簡單實用

mutations

mutations類比到vuex中應該是 methods 它是更改 Vuex 的 store 中的狀態的唯一方法是提交 mutation。Vuex 中的 mutation 非常類似於事件:每個 mutation 都有一個字串的 事件型別 (type) 和 一個 回撥函式 (handler)。這個回撥函式就是我們實際進行狀態更改的地方,並且它會接受 state 作為第一個引數:

// store.js
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    number:0,
  },
  mutations: {
    ADD(state){  //我們把state傳入 就可以對 state內的資料進行我們想要的變化,它必須按照我們想要得到的格式去變化, 想要直接提交mutations 需要使用 this.$stote.commit('mutations的方法名',引數) 如果想要在mutations方法中傳參,寫法就要變成 ADD(state,形參){ ... } 這樣一種形式了 我舉個例子
      state.number++
    },
    SUB(state){
      state.number--
    },
    // ADDPARAM(state,param){
    //   if (typeof param !== 'number'){
    //     param = 0
    //   }
    //   state.number = state.number + param
    // }  這個方法就可以傳入我們想用的引數了,相應呼叫的地方也需要改變
  },
  actions: {

  },
  getters:{
    getNumber(state){   //getter的書寫方法
      return state.number + 100
    }
  }
})
複製程式碼

帶引數的commit如何使用

<!-- children.vue -->
<template>
  <div class="children">
    <h1>This is an children page</h1>
    <button @click="add">
      +
    </button>
      {{$store.state.number}}
      {{$store.getters.getNumber}}
      <!-- getters的基礎呼叫方法,當然還有更高階的 實戰課會講解 -->
      <button  @click="sub">
      -
    </button>
  </div>
</template>

<script>
  export default{
    name: 'children',
    methods: {
      add() {
        this.$store.commit('ADD')
      },
      // addparam() {
      //   this.$store.commit('ADDPARAM',5)
      // }, 
      //  this.$store.commit('要提交的mutations名字',要傳入的引數)
      sub() {
        this.$store.commit('SUB')
      }
    }
  }
</script>

複製程式碼

actions屬性

actions屬性用法和mutations類似,但是actions我們是不可以修改state的 需要在actions通過commit來呼叫mutations來修改資料,那麼action的意義何在呢?處理非同步事件就要用action來做了呀。呼叫方法是,this.$store.dispatch("action的名字",引數)

書寫的方法呢 我給大家展示一下

// store.js
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    number:0,
  },
  mutations: {
    ADD(state){ 
      state.number++
    },
    SUB(state){
      state.number--
    },
    ADDPARAM(state,param){
      if (typeof param !== 'number'){
        param = 0
      }
      state.number = state.number + param
    } 
  },
  actions: {
    ASYNCADD(context,param){  //這裡我們傳入context上下文,裡面包含 commit, state ,getters 這三個屬性都可以通過context來呼叫到並且觸發內部方法
      setTimeout(function(){
        context.commit('ADDPARAM',param)
      },1000)
    }
  },
  getters:{
    getNumber(state){   //getter的書寫方法
      return state.number + 100
    }
  }
})
複製程式碼

action的使用

<!-- children.vue -->
<template>
  <div class="children">
    <h1>This is an children page</h1>
    <button @click="add">
      +
    </button>
      {{$store.state.number}}
      {{$store.getters.getNumber}}
      <button  @click="sub">
      -
    </button>
    

    <button @click="actAdd">action</button>
  </div>
</template>

<script>
  export default{
    name: 'children',
    methods: {
      add() {
        this.$store.commit('ADD')
      },
      actAdd(){   // 我們通過 dispatch來呼叫action 然後由action去提交我們的 mutations來達到非同步更改狀態的目的
        this.$store.dispatch('ASYNCADD',50)
      },
      sub() {
        this.$store.commit('SUB')
      }
    }
  }
</script>

複製程式碼

vuex是不是非常簡單呢,到這裡大家可能在想,如果我的專案很大 我有很多的這些個方法啊,狀態啊,我都寫在這裡不就亂了嗎?沒錯,肯定亂了,所以vuex還提供了modules 方便我們分塊管理

modules

由於使用單一狀態樹,應用的所有狀態會集中到一個比較大的物件。當應用變得非常複雜時,store 物件就有可能變得相當臃腫。 為了解決以上問題,Vuex 允許我們將 store 分割成模組(module)。每個模組擁有自己的 state、mutation、action、getter、甚至是巢狀子模組——從上至下進行同樣方式的分割

我們把上面的這些個程式碼分割出去

// store.js
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

const children = {   // 因為我們是寫在了children這個元件裡面 這個命名規則也好讓我們知道它存在於哪裡
  state: {
    number:0,
  },
  mutations: {
    ADD(state){  
      state.number++
    },
    SUB(state){
      state.number--
    },
    ADDPARAM(state,param){
      if (typeof param !== 'number'){
        param = 0
      }
      state.number = state.number + param
    }  
  },
  actions: {
    ASYNCADD(context,param){  
      setTimeout(function(){
        context.commit('ADDPARAM',param)
      },1000)
    }
  },
  getters:{
    getNumber(state){   
      return state.number + 100
    }
  }
}


export default new Vuex.Store({
  modules:{
    children, // 這裡我們把children傳入以後 還是一樣可以使用我們的哪些方法,不過我們是state要加上 modules名字 所以我們的children.vue 要相應修改
  }
})
複製程式碼
<!-- children.vue -->
<template>
  <div class="children">
    <h1>This is an children page</h1>
    <button @click="add">
      +
    </button>
      {{$store.state.children.number}}
      <!-- 大家可以看到,這裡需要加上modules名字才可以獲取到number 但是其餘的不需要處理,所以我們開發中一般想要獲取到 state 最好是通過getter來獲取  -->
      {{$store.getters.getNumber}}
      <button  @click="sub">
      -
    </button>
    

    <button @click="actAdd">action</button>
  </div>
</template>

<script>
  export default{
    name: 'children',
    methods: {
      add() {
        this.$store.commit('ADD')
      },
      actAdd(){   // 我們通過 dispatch來呼叫action 然後由action去提交我們的 mutations來達到非同步更改狀態的目的
        this.$store.dispatch('ASYNCADD',50)
      },
      sub() {
        this.$store.commit('SUB')
      }
    },
  }
</script>

複製程式碼

很多時候,我們在正式使用中都會加上名稱空間,也就是 modules裡面的 namespaced 屬性我們讓它變為 namespaced: true, 如果大家想要學習,可以去vuex文件學習,得益於es6 vuex給我們提供了 mapState, mapGetters, mapActions 和 mapMutations 這四巨頭 我們可以輕鬆使用名稱空間 這裡不做過多講解,實戰課程中我們邊用邊說。

VUE基礎部分結束 實戰課程等待各位朋友的建議 暫時決定接下來出react

相關文章