Vuex를 사용하여 메모 작성 애플리케이션을 구현하는 방법

亚连
풀어 주다: 2018-05-30 15:36:38
원래의
1607명이 탐색했습니다.

이 글에서는 주로 Vuex를 사용하여 메모 작성 애플리케이션을 구현하는 방법을 소개하고 참고용으로 제공합니다.

저는 최근에 Vue를 배우기 시작했습니다. 먼저 공식 문서를 간략하게 읽은 다음 공식 문서에 몇 가지 DEMO를 입력했지만 여전히 이해가 되지 않습니다. 인터넷에서 초급 메모 작성 응용 프로그램을 찾았습니다. 초급 응용 프로그램이라도 배우기가 어렵습니다. 나중에 복습할 수 있도록 특별히 이 노트를 만들었습니다. Vue를 이제 막 배우기 시작한 여학생들에게 도움이 되기를 바랍니다

목적

노트에는 다음과 같은 기본 기능이 있습니다
1 . 추가
2. 삭제
3. 컬렉션
4. 모든 메모와 즐겨찾는 메모 간 전환
5. 현재 목록에서 검색


구매자 표시


1. 새 프로젝트

여기에서는 Git Bush 실행 문을 사용합니다($ 기호는 Git Bush와 함께 제공됨). 동일한

프로젝트 저장 위치 선택 모듈


3. 프로젝트 생성

명령줄에 vue init webpack vuex-note를 입력하고 프로젝트 생성을 위한 설정을 하세요

이게 대체 뭐죠


4. 각 구성은


vue init webpack vuex-note: webpack 빌드 도구를 사용하여 빌드된 vue 프로젝트를 초기화(init)합니다. 프로젝트 이름은 vuex-note

프로젝트 이름: 프로젝트 이름


입니다. 프로젝트 설명: 프로젝트 설명


저자: 朕

Vue 빌드: 빌드 방법은 독립 빌드와 런타임 빌드로 구분됩니다. 자세한 지침은 다음 링크를 참조하세요. vuejs.org/v2/guide/installation.html #Runtime-Compiler-vs-Runtime-only

  1. vue-router 설치: vue-router를 설치해야 합니까? 페이지로 이동하는 데 사용됩니다. 여기서는 필요하지 않습니다. 나중에 배우겠습니다

  2. ESLint를 사용하여 코드를 린트하세요. ESLint 사양 및 사용법. 아마도 ESLint를 사용하면 오류가 발생할 수 있습니다. n

  3. 을 선택하고 나머지는 모두 테스트용입니다. n

  4. 프로젝트가 생성된 후 'npm install'을 실행해야 할까요? Enter를 누르면 다양한 것들이 설치됩니다

  5. 5. 설치 후 프롬프트가 표시되면 프롬프트를 따르십시오
  6. 먼저 cd vuex-note로 vue 프로젝트 폴더에 들어가세요. 생성

  7. 설치가 완료되었습니다. NPM Run Dev
  8. 후속 조작을 통해 프로젝트를 실행합니다. :8080 브라우저를 통해 새 vue 페이지 열기

새로운 vue 페이지


7. 프로젝트 구조

현재 프로젝트 구조는 그림과 같습니다



프로젝트 구조

저는 초보라서 뭔가 먼저 생각나기 때문에 지저분한 구성은 일단 무시하고 이번에 관련된 것들만 골라보겠습니다. (사실 저한테는 너무 많아요) 저도 배우지 못했습니다 ...)

8. Vuex 확인

Vuex를 사용하여 메모 작성 애플리케이션을 구현하므로 먼저 빌드된 프로젝트에 Vuex 모듈이 포함되어 있는지 확인해야 합니다.

node_modules 폴더에는 기존 모듈이 포함되어 있지만 원하는 Vuex가 없습니다. 믿을 수 없다면 직접 확인해 보세요


package.json 파일은 프로젝트에 포함된 파일, 프로젝트 실행 방법 및 기타 정보를 설명합니다. 명령줄 -save는 package.json에 설치 정보를 작성하는 것입니다

Vuex가 설치되었습니다

이제 모든 사전 작업이 완료되었으며 부족한 부분을 하나씩 설명하겠습니다. 구현 과정 중

시작하기


Zero, Ideas


전체 애플리케이션은 세 가지 구성 요소로 나눌 수 있습니다

Split

각 노트에는 숫자(ID), 제목( title), content(content), 즐겨찾기(fav) 여부 4가지 정보

Vuex의 상태에는 모든 노트(notes)를 저장할 수 있는 장소가 있어야 합니다.

그리고 수집 및 삭제 작업은 오직 현재 노트에서 작동하므로 식별자도 필요합니다. 현재 노트(activeNote)를 기록하는 데 사용됩니다.

  1. 여기에는 all과 collection의 두 가지 전환 방법이 포함되어 있으므로 이를 구별하기 위한 로고가 필요합니다. show라고 부르겠습니다. , all은 모두를 나타내고, fav는 컬렉션을 나타냅니다.

    Component ==> actions.js ==> mutations.js = > state: 컴포넌트를 통해 액션(디스패치)에서 메소드를 호출합니다. (커밋) 액션 내 메소드를 통해, 뮤테이션을 통해 뮤테이션에서 메소드를 호출 상태에서 노트 목록(notes), 현재 노트(activeNote) 등을 조작하는 메소드
  2. 1. index.html

  3. <!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>
    로그인 후 복사

  4. 이에 대해서는 말할 것도 없습니다. p

2의 ID만 주의하세요. 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;
})
로그인 후 복사

1. 가져올 때 필요합니까?

프로젝트 모듈에서 내보낼 때는 가져올 때 ./가 필요하지 않지만, 직접 작성한 컴포넌트에서 가져올 때는 ./가 필요합니다.

2 소개가 필요한 abc에서 {aaa}를 가져와야 하는 경우는 언제입니까? 교정기? 언제 필요하지 않습니까?

abc에서 내보낸 부분이 aaa인 경우

가져오기가 기본적으로 내보낸 부분인 경우에는 {}가 추가되지 않으며 별칭을 지정할 수 있습니다

3. 프로젝트 구조에는 store 폴더만 있는데 './store'에서 저장소 가져오기는 무엇을 의미하나요?

모르겠습니다. 조언 부탁드립니다

4. 뉴뷰에서 별도 매장이 무슨 뜻인가요?

ES6의 약어 앞에 store:store가 옵니다. 이 문장은 Vuex를 전역적으로 주입한다는 의미이므로 각 컴포넌트에서 this.$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
})
로그인 후 복사

1. Vue.use(Vuex)는 무엇을 의미하나요?

Vuex를 사용하면 앞으로 Vue-router를 사용할 때 꼭 하게 되는데, 반드시 라우트 폴더 아래 index.js 파일에 작성해야 합니다

2. +new Date()는 무슨 뜻인가요?

new Date().getTime()3과 동일한 타임스탬프를 작성하는 또 다른 방법입니다. 상태, 게터, 돌연변이 및 작업 간의 관계는 무엇입니까?

state: 위에서 언급했듯이 상태 창고

getters: 상태 수정, 예를 들어 상태에 str: "abc"와 같은 속성이 있고 많은 구성 요소에서 str + "def" 작업이 필요합니다. 각각의 경우 모든 구성 요소에서 str + "def" 작업을 수행하는 것이 너무 번거로우므로 getter에 추가할 수 있습니다.

strAdd(){
  return this.str + "abc"
}
로그인 후 복사

앞으로는 구성 요소에서 strAdd를 사용하면 됩니다

mutations: 쉽게 말하면 상태 수정, 동기식 호출에 사용됩니다. $store.dispatch


4. 도구 .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>
로그인 후 복사

1.

    여기 아주 좋은 설명이 있습니다 http://www.imooc.com/article/14741
  1. 또한 메소드와 Vuex 액션에 동일한 이름의 속성 A가 있는 경우 mapActions(['A']는 ) 이 방법은 축약형입니다
  2. 참고: 1. 대괄호는 생략할 수 없습니다. 2. 대괄호는 문자열입니다. 3. 확장 연산자는... 생략할 수 없습니다.

  3. 별칭을 사용할 수도 있습니다. 쓰기는 다음과 같습니다. [ ]가 {}가 되었다는 점에 주의하세요:

...map({
 本组件的属性 : Vuex 中 actions 中的属性
})
로그인 후 복사

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

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

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>
로그인 후 복사

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>
로그인 후 복사

七、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)
  }
}
로그인 후 복사

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;])
로그인 후 복사

而 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
        }
      })
    }
  }
}
로그인 후 복사

实现一个过滤,根据 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
  }
}
로그인 후 복사

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"
로그인 후 복사

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

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

相关文章:

分析javascript原型及原型链

jQuery中each方法的使用详解

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

위 내용은 Vuex를 사용하여 메모 작성 애플리케이션을 구현하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
최신 이슈
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿
회사 소개 부인 성명 Sitemap
PHP 중국어 웹사이트:공공복지 온라인 PHP 교육,PHP 학습자의 빠른 성장을 도와주세요!