使用 Vuex + Vue.js 構建單頁應用【新篇】

使用 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 組件內部如何使用 vuexgithub

<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 提供的三個擴展方法 mapStatemapActionsmapGettersvuex

另一個不一樣點是在咱們的 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

相關文章
相關標籤/搜索