zoukankan      html  css  js  c++  java
  • 使用 Vuex + Vue.js 构建单页应用【新篇】

    使用 Vuex + Vue.js 构建单页应用【新篇】

    在去年的七月六号的时候,发布了一篇 使用 Vuex + Vue.js 构建单页应用 的文章,文章主要是介绍 vuex 的基本使用方法,发现对大部分的入门同学有很大的帮助,时至今日还有很多同学不断的点赞与收藏,浏览量最高达到 20.4K 。鉴于前端技术发展更新快速,特此在这里重新整理一篇 vue2.0 版本的 vuex 基本使用方法,希望能给更多刚入门或者将要入门的同学带来帮助。

    这篇文章主要是介绍最新 vue2.0 API 的使用方法, 和 vue1.x 的一些差异的地方。

    阅读建议

    1、在阅读这篇文章之前,我希望你已经阅读过我上一篇文章 使用 Vuex + Vue.js 构建单页应用 ,明白我们需要实现的基本需求。

    2、希望你阅读并掌握以下知识点

    目录层级变化

    首先是目录层级的变动,我们看下前后对比:

    2.0 版本,vuex 的文件夹改为了 store

    ├── 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 版本

    ├── 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

    <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 提供的三个扩展方法 mapStatemapActionsmapGetters

    另外一个不同点是在我们的 NodeList.vue 组件中,在 vue2.0 里面已经移除了自带的过滤器函数,官方建议我们使用计算属性,下面是我们更改后的使用方法:

    <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

  • 相关阅读:
    Silverlight 中使用不同面板进行布局的效果比较
    将PDF格式文件添加到iPhone4手机 iBooks程序中.
    [转]学习WPF参考书
    [转]OEM版XP SP3安装时提示“序列号无效”的解决方法
    关于系统响应函数OnSysCommand
    为何在自定义消息处理函数中无法利用wParam或lParam传递指针?
    自定义消息(上)
    VC++中单选与复选按钮的使用
    VC++ Combo Box/Combo Box Ex控件
    VC++中的ON_COMMAND_RANGE宏
  • 原文地址:https://www.cnblogs.com/10manongit/p/12863168.html
Copyright © 2011-2022 走看看