使用 Vuex + Vue.js 構建單頁應用【新篇】
在去年的七月六號的時候,發佈了一篇 使用 Vuex + Vue.js 構建單頁應用 的文章,文章主要是介紹
vuex
的基本使用方法,發現對大部分的入門同窗有很大的幫助,時至今日還有不少同窗不斷的點贊與收藏,瀏覽量最高達到 20.4K 。鑑於前端技術發展更新快速,特此在這裏從新整理一篇 vue2.0 版本的vuex
基本使用方法,但願能給更多剛入門或者將要入門的同窗帶來幫助。javascript
這篇文章主要是介紹最新 vue2.0 API 的使用方法, 和 vue1.x 的一些差別的地方。html
閱讀建議
一、在閱讀這篇文章以前,我但願你已經閱讀過我上一篇文章 使用 Vuex + Vue.js 構建單頁應用 ,明白咱們須要實現的基本需求。前端
二、但願你閱讀並掌握如下知識點vue
目錄層級變化
首先是目錄層級的變更,咱們看下先後對比:java
2.0 版本,vuex 的文件夾改成了 storegit
├── index.html ├── src │ ├── App.vue │ ├── assets │ │ └── logo.png │ ├── components │ │ ├── Editor.vue │ │ ├── NoteList.vue │ │ └── Toolbar.vue │ ├── main.js │ └── store │ ├── actions.js │ ├── getters.js │ ├── index.js │ ├── mutation-types.js │ └── mutations.js └── static
1..0 版本es6
├── index.html ├── src │ ├── App.vue │ ├── assets │ │ └── logo.png │ ├── components │ │ ├── Editor.vue │ │ ├── NotesList.vue │ │ └── Toolbar.vue │ ├── main.js │ └── vuex │ ├── actions.js │ ├── getters.js │ └── store.js └── static
使用方式的變更
在文件的 main.js
中注入,2.0 的注入方式以下
import Vue from 'vue' import App from './App' import store from './store'; Vue.config.productionTip = false /* eslint-disable no-new */ new Vue({ el: '#app', template: '<App/>', store, components: { App } })
在組件中使用方式
咱們來看 Editor.vue
組件內部如何使用 vuex
的github
<template> <div class="note-editor"> <div class="form-group"> <input type="text" name="title" class="title form-control" placeholder="請輸入標題" @input="updateNote" v-model="currentNote.title"> <textarea v-model="currentNote.content" name="content" class="form-control" row="3" placeholder="請輸入正文" @input="updateNote"></textarea> </div> </div> </template> <style> ... </style> <script> import { mapState, mapActions, mapGetters } from 'vuex'; export default { name: 'Editor', computed: { ...mapGetters([ 'activeNote' ]), currentNote() { return this.activeNote; } }, methods: { ...mapActions({ update: 'updateNote' }), updateNote() { this.update({ note: this.currentNote }); } } } </script>
因爲咱們在入口文件 main.js
中已經注入 store
對象,使得咱們可以在子組件中獲取到它,在這裏,咱們使用了 vuex
提供的三個擴展方法 mapState
、mapActions
、mapGetters
。vuex
另一個不一樣點是在咱們的 NodeList.vue
組件中,在 vue2.0
裏面已經移除了自帶的過濾器函數,官方建議咱們使用計算屬性,下面是咱們更改後的使用方法:segmentfault
<template> <div class="notes-list"> <div class="list-header"> <h2>Notes | heavenru.com</h2> <div class="btn-group btn-group-justified" role="group"> <!-- all --> <div class="btn-group" role="group"> <button type="button" class="btn btn-default" @click="toggleShow('all')" :class="{active: show === 'all'}">All Notes</button> </div> <!-- favorites --> <div class="btn-group" role="group"> <button type="button" class="btn btn-default" @click="toggleShow('favorite')" :class="{active: show === 'favorite'}">Favorites</button> </div> </div> <div class="btn-group btn-group-justified" role="group"> <div class="input-group search"> <input type="text" class="form-control" v-model="search" placeholder="Search for..."> <span class="input-group-addon"> <i class="glyphicon glyphicon-search"></i> </span> </div> </div> </div> <!-- 渲染筆記列表 --> <div class="container"> <div class="list-group"> <div v-for="(note, index) in searchNotes" :key="index" class="list-group-item" :class="{active: activeNote === note}" @click="updateActiveNote(note)"> <h4 class="list-group-item-heading"> {{note.title.trim().substring(0,30)}} </h4> </div> </div> </div> </div> </template> <style scoped> ... </style> <script> import { mapGetters, mapState, mapActions } from 'vuex'; export default { name: 'NoteList', data() { return { search: '' } }, computed: { ...mapGetters([ 'filteredNotes' ]), // state 內部狀態 ...mapState([ 'show', 'activeNote' ]), // 計算屬性,自定義過濾 searchNotes() { if (this.search.length > 0) { return this.filteredNotes.filter((note) => note.title.toLowerCase().indexOf(this.search) > -1); } else { return this.filteredNotes; } } }, methods: { ...mapActions([ 'toggleListShow', 'setActiveNote' ]), // 切換列表,所有或者收藏 toggleShow(type) { this.toggleListShow({ show: type}); }, // 點擊列表,更新當前激活文章 updateActiveNote(note) { this.setActiveNote({ note }); } } } </script>
Q&A
其餘的變更,你們自行的查看源碼學習:vuex-notes-app2。