在去年的七月六号的时候,发布了一篇 使用 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>
其余的变更,你们自行的查看源码学习:vuex-notes-app2。