Home > Web Front-end > JS Tutorial > body text

How to implement a note-taking application using Vuex

亚连
Release: 2018-05-30 15:36:38
Original
1667 people have browsed it

This article mainly introduces the method of using Vuex to implement a note-taking application. Now I will share it with you and give you a reference.

I recently started to learn Vue. I first briefly went through the official documents, and then typed some DEMOs in the official documents, but I still don’t understand much. I found an entry-level note-taking application on the Internet. Even if it is an entry-level application, it is still difficult to learn. I will make this note for my study so that I can review it in the future. I also hope it can help female students who have just started learning Vue

expected goals

The notes are as follows Basic functions
1. Add
2. Delete
3. Collection
4. Switch between all notes and favorite notes
5. Search in the current list

Seller Show

Buyer Show

Preparation

1. Create a new project

Choose a folder to store the project. Here I use the Git Bush execution statement (the $ symbol comes with Git Bush), you can also Use the command line, the same

Select the project storage location

2. View the module (whether you like it or not)

View globally installed modules npm list --depth=0 -global

View globally installed modules

3. Create a project

Enter vue init webpack vuex-note on the command line and make settings to create a project

What the hell is this

4. Briefly explain what each configuration does

  1. vue init webpack vuex-note: Initialize (init) a vue project built using the webpack build tool. The project name is vuex-note

  2. Project name: Project name

  3. Project description: Project description

  4. Author: I

  5. Vue build: Build method, divided into independent build and Runtime build, see the following link for specific instructions, here choose to build standalone independently https://vuejs.org/v2/guide/installation.html#Runtime-Compiler-vs-Runtime-only

  6. Install vue-router: Do you need to install vue-router? It is used to jump to the page. It is not needed here. I will learn it later.

  7. Use ESLint to lint your code: ESLint specification and It is used by law. Maybe the writing methods you are familiar with are not standard. If you use ESLint, you may get an error. Here, choose n

  8. . The rest are for testing, n## all the way.

  9. #Should we run 'npm install' for you after the project has been created: If you need to directly install (npm install) related dependencies for you, just press Enter and we will install them for you. Kind of stuff

#5. There will be a prompt after installation, we will follow the prompts

First cd vuex-note to enter the vue just created Project folder


Installation completed


Run the project through npm run dev


Follow-up operations


6. Visit the page

At this time, you can open a new page by accessing localhost:8080 through the browser vue page


New vue page


7. Project structure

Deadline The current project structure is as shown in the figure

Project structure

Since I am a beginner, in order to come up with something first, I will ignore some messy configurations for the time being. Let me pick out the ones related to this time (in fact, I didn’t learn much...)

8. Check out Vuex

Since Vuex is used to implement the note application , we should first check whether the built project contains the Vuex module.


The node_modules folder contains existing modules, but there is no Vuex we want in it. If you don’t believe it, check it out for yourself


package.json file describes the files contained in the project, how the project runs and other information

package.json

9. Install Vuex

Enter npm install vuex --save on the command line: --save is to write the installation information into package.json

Vuex has been installed

At this point, all preliminary work has been completed, and the missing parts will be explained one by one during the implementation process

Start

Zero, idea

The entire application can be split into three components

开户

  1. Each note includes four types of information: number (ID), title (title), content (content), and whether it has been collected (fav)

  2. The state in Vuex must have a place to store all notes

  3. The collection and deletion operations can only operate on the current notes, so I We also need a logo to record the current note (activeNote), which

  4. contains two switching methods: all and favorites, so we also need a logo to distinguish it, let's call it show. , all represents all, fav represents the collection

  5. Component ==> actions.js ==> mutations.js = > state: Call the method in actions through the component ( dispatch), call the method in mutations (commit) through the method in actions, and use the method in mutations to operate the note list in the state (notes), the current note (activeNote), etc.

1. index.html

<!DOCTYPE html>
<html>
 <head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width,initial-scale=1.0">
  <title>vuex-note</title>
 </head>
 <body>
  <p id="app"></p>
  <!-- built files will be auto injected -->
 </body>
</html>
Copy after login

There is nothing to say about this, just pay attention to the ID of p

2. main.js

import Vue from &#39;vue&#39;
import App from &#39;./App&#39;
import store from &#39;./store&#39;     

Vue.config.productionTip = false

new Vue({
 el: &#39;#app&#39;,
 store,        
 components: { App },
 template: &#39;<App/>&#39;
})
Copy after login

1. When is importing need' ./ '?

Export from the project module, you do not need ./ when importing, but you need ./ when importing from a component written by yourself

2. When is import { aaa} from abc The introduction of this kind of braces? When is it not needed?

When the exported part in abc is export aaa

When the import is the part exported by export default, {} is not added, and an alias can be used

3. There is no store file in the project structure, only the store folder. What does import store from './store' mean?

I don’t know, please give me some advice

4. What does a separate store in new Vue mean?

An abbreviation of ES6, the abbreviation is preceded by store:store. This sentence means to inject Vuex globally, so that the state library can be called through this.$store in each component. , if it is not injected globally, it needs to be introduced separately in each component. It will be very troublesome if there are too many.

3. Index.js under store

import Vue from &#39;vue&#39;
import Vuex from &#39;vuex&#39;
import getters from &#39;./getters&#39;
import mutations from &#39;./mutations&#39;
import actions from &#39;./actions&#39;

Vue.use(Vuex)    

const defaultNote = {
  id: +new Date(),    
  title: &#39;新建笔记&#39; + new Date().getMilliseconds(),    // 加时间是为了做一下区分
  content: &#39;笔记内容&#39;,
  fav: false
}

// 可以理解为一个状态的仓库  
const state = {
  notes: [defaultNote],      // 以数组方式存放所有的笔记
  activeNote: defaultNote,    // 用来记录当前笔记  
  show: &#39;all&#39;           // 用于切换 全部 / 已收藏 两种不同列表的标识
}

export default new Vuex.Store({
  state,
  getters,
  mutations,
  actions
})
Copy after login

1. What does Vue.use(Vuex) mean?

Using Vuex, you will have to do this when using Vue-router in the future, but it must be written in the index.js file under the route folder

2. What does new Date() mean?

Another way to get timestamp, which is equivalent to new Date().getTime()

3. The relationship between state, getters, mutations, actions ?

state: State warehouse as mentioned above

getters: modification of state, for example, there is an attribute like str: "abc" in state, which is required in many components To perform str "def" operation, it would be too troublesome to perform str "def" operation on each component, so you can add in getters:

strAdd(){
  return this.str + "abc"
}
Copy after login

Just use strAdd in the component in the future

  1. mutations: Simply put, it is used to modify state, synchronous method. Regularly call this.$store.commit

  2. actions: Simply speaking, it is used to call mutations, asynchronous method. Regular call this.$store.dispatch

4. tool.vue

<template>
  <p id="tool">
    <button class="add" @click="add_note">新增</button>
    <button class="fav" @click="fav_note">收藏</button>
    <button class="del" @click="del_note">删除</button>
  </p>
</template>
<script type="text/javascript">
  import { mapState, mapGetter, mapActions } from &#39;vuex&#39;
  export default {
    name: &#39;tool&#39;,
    methods:{      
      ...mapActions([&#39;add_note&#39;,&#39;del_note&#39;,&#39;fav_note&#39;])
    }
  }
</script>
<style type="text/css" scoped>
  #tool {
    width: 200px;
    height: 600px;
    border: 2px solid #ccc;
    float: left;
  }
  
  button {
    width: 100%;
    height: calc(100% / 3);    
    font-size: 60px;
  }
</style>
Copy after login

1. What are mapState, mapGetter, and mapActions?

Here is a very good explanation http://www.imooc.com/article/14741

In addition, when methods and Vuex actions have attribute A with the same name , you can use mapActions(['A']) This method is abbreviated as

Note: 1. The square brackets cannot be omitted; 2. The square brackets are strings; 3. The expansion operator... You cannot omit

and you can also use an alias. It is written as follows. Note that [] becomes {}:

...map({
 本组件的属性 : Vuex 中 actions 中的属性
})
Copy after login

需要传入参数时,前提是 actions 中的属性(方法)能接收参数:

methods:{
 ...mapActions([&#39;abc&#39;])
 // 自定义一个方法,通过触发这个方法调用之前重名的方法并传入参数
 tragger_abc(参数){
  this.abc(参数)
 }
}
Copy after login

2.scoped

对当前组件生效的 CSS

3.calc

使用时记得在运算符前后各加一个空格

五、list.vue

<template>
  <p id="list">
    <p class="switch">
      <button class="all" @click=&#39;get_switch_note("all")&#39;>全部</button><button class="fav" @click=&#39;get_switch_note("fav")&#39;>已收藏</button>
    </p>
    <p class="search">
      <input type="text" placeholder="在这里搜索" v-model="search" />
    </p>
    <p class="noteList">
      <p class="note" v-for="note in search_filteredNote" :class="{favColor:note.fav===true,active:note.id===activeNote.id}" @click=&#39;get_select_note(note)&#39;>
        <p class="title">
          <p>{{note.title}}</p>
        </p>
        <p class="content">
          <p>{{note.content}}</p>
        </p>
      </p>
    </p>
  </p>
</template>
<script type="text/javascript">
  import { mapState, mapGetters, mapActions } from &#39;vuex&#39;
  export default {
    name: &#39;list&#39;,
    data: function() {
      return {
        search: "" 
      }
    },
    computed: {
      ...mapState([&#39;notes&#39;, &#39;activeNote&#39;]),
      ...mapGetters([&#39;filteredNote&#39;]),
      // 二次过滤:在当前列表(全部 或 已收藏)中进行筛选,返回值被用在组件的 v-for 中 
      search_filteredNote() {
        if(this.search.length > 0) {    // 如果输入框有值,返回二次过滤的结果并加载
          return this.filteredNote.filter(note => {
            if(note.title.indexOf(this.search) > 0) {
              return note
            }
          })
        } else {      // 输入框没值,不过滤,直接拿来加载
          return this.filteredNote
        }
      }
    },
    methods: {
      ...mapActions([&#39;select_note&#39;, &#39;switch_note&#39;]), 
      get_select_note(note) {
        this.select_note(note)
      },
      get_switch_note(type) {
        this.switch_note(type)
      }
    }
  }
</script>
<style type="text/css" scoped="scoped">
  #list {
    width: 300px;
    height: 600px;
    border: 2px solid #ccc;
    float: left;
    margin-left: 10px;
    display: flex;
    flex-direction: column;
  }
  
  p {
    margin: 0;
  }
  
  .switch {}
  
  .switch button {
    height: 60px;
    width: 50%;
    font-size: 40px;
  }
  
  .search {
    border: 1px solid #CCCCCC
  }
  
  input {
    width: 100%;
    box-sizing: border-box;
    height: 50px;
    line-height: 50px;
    padding: 10px;
    outline: none;
    font-size: 20px;
    border: none;
  }
  
  .noteList {
    flex-grow: 1;
    overflow: auto;
  }
  
  .note {
    border: 1px solid #CCCCCC;
  }
  
  .favColor {
    background: pink;
  }
  
  .active {
    background: lightblue
  }
</style>
Copy after login

1.data 中的 search 是干嘛的?可不可以写在 computed 中?

用来与搜索框进行关联。可以写在 computed 中,但 computed 中的属性默认都是 getter ,就是只能获取值,如果想修改,需要设置 setter ,详见官方文档

六、edit.vue

<template>
  <p id="edit">
    <p class="title">
      <input type="text" placeholder="在这里输入标题" v-model="activeNote.title"/>
    </p>
    <p class="content">
      <textarea name="" placeholder="在这里吐槽" v-model="activeNote.content"></textarea>
    </p>
  </p>
</template>
<script type="text/javascript">
  import { mapState, mapGetter, mapActions } from &#39;vuex&#39;
  export default {
    name: &#39;edit&#39;,
    computed:{
      ...mapState([&#39;activeNote&#39;])   // 当本组件中 computed 中的属性名与 Vuex 中的 state 属性名相同时,就可以在 mapState() 中简写
    }
  }
</script>
<style type="text/css" scoped="scoped">
  #edit {
    width: 300px;
    height: 600px;
    border: 2px solid #ccc;
    float: left;
    margin-left: 10px;
    display: flex;
    flex-direction: column;
  }
  
  .title {
    border: 1px solid #CCCCCC;
  }
  
  input {
    width: 100%;
    box-sizing: border-box;
    height: 50px;
    line-height: 50px;
    padding: 10px;
    outline: none;
    font-size: 20px;
    border: none;
  }
  
  .content {
    flex-grow: 1;
    background: orange;
    display: flex;
    flex-direction: column;
  }
  
  textarea {
    width: 100%;
    box-sizing: border-box;
    flex-grow: 1;
    resize: none;
    padding: 10px;
    font-size: 20px;
    outline: none;
    font-family: inherit;
  }
</style>
Copy after login

七、actions.js

export default {
  add_note({commit}) {
    commit(&#39;ADD_NOTE&#39;)
  },
  select_note({commit}, note) {
    commit("SELECT_NOTE", note)
  },
  del_note({commit}) {
    commit("DEL_NOTE")
  },
  fav_note({commit}) {
    commit("FAV_NOTE")
  },
  switch_note({commit}, type) {
    commit("SWITCH_NOTE", type)
  }
}
Copy after login

1.这是干什么?

这里的每个方法实际上是通过 commit 调用 mutations.js 中的方法;

举个栗子:tool.vue 的 新增 按钮上绑了一个 add_note 自定义方法,在 actions.js 中也定义一个同名的方法,这样就可以在 tool.vue 中的 mapActions 中简写,就是下面这句:

# tool.vue
...mapActions([&#39;add_note&#39;,&#39;del_note&#39;,&#39;fav_note&#39;])
Copy after login

而 actions.js 中的 add_note 去调用 mutations.js 中写好的 ADD_NOTE 方法,而实际的添加操作也是在 ADD_NOTE 中,组件也好,actions 也好,最终只是调用 ADD_NOTE 。之所以这么做是因为 mutations 中的方法都是同步的,而 actions 中的方法是异步的,不过在本例里没啥区别

八、getters.js

export default {
  filteredNote: (state) => {
    if(state.show === &#39;all&#39;) {
      return state.notes
    } else {
      return state.notes.filter((note) => {
        if(note.fav === true) {
          return note
        }
      })
    }
  }
}
Copy after login

实现一个过滤,根据 show 来判断展示 全部笔记 还是 已收藏笔记

九、mutations.js

import { SWITCH_NOTE, ADD_NOTE, SELECT_NOTE, DEL_NOTE, FAV_NOTE } from &#39;./mutation-types&#39;

export default {
  [ADD_NOTE](state, note = {
    id: +new Date(),
    title: &#39;新建笔记&#39; + new Date().getMilliseconds(),
    content: &#39;笔记内容&#39;,
    fav: false
  }) {
    state.notes.push(note)
    state.activeNote = note
  },
  [SELECT_NOTE](state, note) {
    state.activeNote = note
  },
  [DEL_NOTE](state) {
    for(let i = 0; i < state.notes.length; i++) {
      if(state.notes[i].id === state.activeNote.id) {
        state.notes.splice(i, 1)
        state.activeNote = state.notes[i] || state.notes[i - 1] || {}
        return
      }
    }
  },
  [FAV_NOTE](state) {
    state.activeNote.fav = !state.activeNote.fav
  },
  [SWITCH_NOTE](state, type) {
    state.show = type
  }
}
Copy after login

1.export default 那里看着好熟悉

ES6 函数的一种写法,中括号 + 常量 作为函数名,这里常量从其它文件引入

十、mutation-types.js

export const ADD_NOTE = "ADD_NOTE"
export const SELECT_NOTE = "SELECT_NOTE"
export const DEL_NOTE = "DEL_NOTE"
export const FAV_NOTE = "FAV_NOTE"
export const SWITCH_NOTE = "SWITCH_NOTE"
Copy after login

抛出常量,mutations.js 中的函数常量就是这里抛出的,查资料说是这么做便于一目了然都有那些方法。

上面是我整理给大家的,希望今后会对大家有帮助。

相关文章:

分析javascript原型及原型链

jQuery中each方法的使用详解

jquery 实现拖动文件上传加载进度条功能

The above is the detailed content of How to implement a note-taking application using Vuex. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template