수색…


소개

Vuex는 Vue.js 응용 프로그램을위한 상태 관리 패턴 + 라이브러리입니다. 응용 프로그램의 모든 구성 요소에 대한 중앙 집중식 저장소 역할을하며 상태는 예측 가능한 방식으로 만 변형 될 수 있습니다. 또한 Vue의 공식 개발 도구 확장 기능을 통합하여 제로 구성 시간 이동 디버깅 및 상태 스냅 샷 내보내기 / 가져 오기와 같은 고급 기능을 제공합니다.

Vuex 란 무엇입니까?

Vuex는 Vue.js의 공식 플러그인으로, 애플리케이션 내에서 사용할 수있는 중앙 집중식 데이터 저장소를 제공합니다. 단방향 데이터 흐름을 특징으로하는 Flux 애플리케이션 아키텍처의 영향을 크게 받으면서 애플리케이션 설계 및 추론이 단순 해집니다.

Vuex 응용 프로그램 내에서 데이터 저장소는 모든 공유 응용 프로그램 상태를 보유합니다. 이 상태는 디스패처 를 통해 돌연변이 이벤트를 호출하는 액션 에 대한 응답으로 수행되는 돌연변이에 의해 변경됩니다.

Vuex 응용 프로그램의 데이터 흐름 예제는 아래 다이어그램에 요약되어 있습니다. Vuex 응용 프로그램 아키텍처 원래 공식 Vuex GitHub 레포 에서 나온 MIT 라이센스하에 사용 된 다이어그램.

개별 Vue.js 응용 프로그램 구성 요소는 getter 를 통해 데이터를 검색하기 위해 저장소 객체에 액세스 할 수 있습니다. getter 는 원하는 데이터의 읽기 전용 복사본을 반환하는 순수한 함수입니다.

구성 요소에는 구성 요소 자체의 데이터 복사본에 대한 변경 작업 을 수행 한 후 해당 Dispatcher 를 사용하여 변이 이벤트를 전달하는 기능을 수행 할 수 있습니다. 이 이벤트는 필요에 따라 상태를 업데이트하는 데이터 저장소에 의해 처리됩니다.

모든 구성 요소는 getter를 통해 저장소에 반응 적으로 바인딩되므로 변경 사항은 응용 프로그램 전체에 자동으로 반영됩니다.


vue 프로젝트에서 vuex를 사용하는 예를 보여줍니다.

const state = {
    lastClickTime: null
}

const mutations = {
    updateLastClickTime: (state, payload) => {
      state.lastClickTime = payload
  }
}

const getters = {
  getLastClickTime: state => {
    return new Date(state.lastClickTime)
  }
}

const actions = {
    syncUpdateTime: ({ commit }, payload) => {
    commit("updateLastClickTime", payload)
  },
  asyncUpdateTime: ({ commit }, payload) => {
    setTimeout(() => {
      commit("updateLastClickTime", payload)
    }, Math.random() * 5000)
  }
}

const store = new Vuex.Store({
  state,
  getters,
  mutations,
  actions
})

const { mapActions, mapGetters } = Vuex;

// Vue 
const vm = new Vue({
    el: '#container',
  store,
  computed: {
      ...mapGetters([
        'getLastClickTime'
    ])
  },
  methods: {
      ...mapActions([
        'syncUpdateTime',
      'asyncUpdateTime'
    ]),
    updateTimeSyncTest () {
        this.syncUpdateTime(Date.now())
    },
    updateTimeAsyncTest () {
        this.asyncUpdateTime(Date.now())
    }
  }
})

그리고 같은 HTML 템플릿 :

<div id="container">
  <p>{{ getLastClickTime || "No time selected yet" }}</p>
  <button @click="updateTimeSyncTest">Sync Action test</button>
  <button @click="updateTimeAsyncTest">Async Action test</button>
</div>
  1. 여기서 상태 에는 null로 초기화 된 lastClickTime 속성이 포함됩니다. 이 기본값을 설정하는 것은 속성의 반응 을 유지하는 데 중요합니다. 상태에 언급되지 않은 속성 은 사용할 수 있지만 그 이후 변경된 내용은 getter를 사용하여 액세스 할 수 없습니다 .

  2. 사용 된 getter는 mutation이 state 속성의 값을 업데이트 할 때마다 업데이트 될 계산 된 속성을 제공합니다.

  3. 변이 (mutations)만이 상태와 속성을 변경할 수있다 .

  4. 액션은 비동기식 업데이트의 경우에 사용할 수 있습니다. API 호출 (여기서는 무작위로 시간 지정된 setTimeout으로 조롱)을 액션에서 만들 수 있으며 응답을 받으면 변형을 적용하여 상태를 변경합니다 .

Vuex를 사용하는 이유는 무엇입니까?

일반적으로 많은 재사용 가능한 구성 요소로 구성된 SPA (Single Page Apps)와 같은 대규모 응용 프로그램을 구축 할 때는 신속하게 구축하고 유지 보수하기 어려워 질 수 있습니다. 이러한 구성 요소 간의 데이터 및 상태 공유는 신속하게 고장 나고 디버그 및 유지 관리가 어려워 질 수 있습니다.

중앙 집중식 응용 프로그램 데이터 저장소를 사용하면 전체 응용 프로그램 상태를 한 곳에서 표현할 수 있으므로 응용 프로그램을보다 체계적으로 구성 할 수 있습니다. 단방향 데이터 흐름, 돌연변이의 사용 및 필요한 데이터에 대한 구성 요소 데이터 액세스의 범위 지정을 통해 구성 요소 역할에 대한 추론이 훨씬 간단 해지고 응용 프로그램 상태에 어떤 영향을 미치는지 알아볼 수 있습니다.

VueJS 구성 요소는 별도의 엔터티이며 서로 쉽게 데이터를 공유 할 수 없습니다. vuex없이 데이터를 공유하기 위해 우리가 할 필요가 emit 데이터와 이벤트를 다음 듣고 함께 해당 이벤트를 잡을 on .

구성 요소 1

this.$emit('eventWithDataObject', dataObject)

구성 요소 2

this.$on('eventWithDataObject', function (dataObject) {
    console.log(dataObject)
})

vuex를 설치하면 이벤트를 청취 할 필요없이 모든 구성 요소에서 데이터에 액세스 할 수 있습니다.

this.$store.state.myData

뮤 테이터 와 함께 데이터를 동 기적으로 변경하고, 비동기 액션을 사용하고 게터 기능으로 데이터를 가져올 수도 있습니다.

게터 함수는 전역 계산 함수로 작동 할 수 있습니다. 우리는 컴포넌트들로부터 그것들에 접근 할 수있다 :

this.$store.getters.myGetter

액션은 글로벌 메소드입니다. 구성 요소에서 파견 할 수 있습니다.

this.$store.dispatch('myAction', myDataObject)

그리고 변이가 vuex에서 데이터를 변경하는 유일한 방법입니다. 우리는 변화를 저지를 수 있습니다 :

this.$store.commit('myMutation', myDataObject)

Vuex 코드는 다음과 같습니다.

state: {
  myData: {
    key: 'val'
  }
},
getters: {
  myGetter: state => {
     return state.myData.key.length
  }
},
actions: {
  myAction ({ commit }, myDataObject) {
    setTimeout(() => {
      commit('myMutation', myDataObject)
    }, 2000)
  }
},
mutations: {
  myMutation (state, myDataObject) {
    state.myData = myDataObject
  }
}

Vuex 설치 방법

Vuex를 사용하는 대부분의 시간은 단일 파일을 사용하는 경우 Vueify와 함께 Webpack 또는 Browserify와 같은 모듈 번들러를 사용할 가능성이있는 더 큰 구성 요소 기반 응용 프로그램에 포함됩니다.

이 경우 Vuex를 얻는 가장 쉬운 방법은 NPM에서입니다. 아래 명령을 실행하여 Vuex를 설치하고 응용 프로그램 종속성에 저장하십시오.

 npm install --save vuex

require('vue') 문 다음에 다음 행을 삽입하여 Vue 링크를로드하도록하십시오.

Vue.use(require('vuex'))

Vuex는 CDN에서도 구할 수 있습니다. cdnjs 에서 최신 버전을 가져올 수 있습니다 .

자동으로 거부 될 수있는 알림

이 예제는 자동으로 닫을 수있는 커스텀 통보를 저장하기 위해 동적으로 vuex 모듈을 등록합니다

notifications.js

vuex 저장소를 해결하고 몇 가지 상수를 정의합니다.

//Vuex store previously configured on other side
import _store from 'path/to/store';

//Notification default duration in milliseconds
const defaultDuration = 8000;

//Valid mutation names
const NOTIFICATION_ADDED = 'NOTIFICATION_ADDED';
const NOTIFICATION_DISMISSED = 'NOTIFICATION_DISMISSED';

모듈 초기 상태 설정

const state = {
  Notifications: []
}

우리 모듈 getters 설정

const getters = {
  //All notifications, we are returning only the raw notification objects
  Notifications: state => state.Notifications.map(n => n.Raw)
}

우리의 모듈을 설정 액션

const actions = {
  //On actions we receive a context object which exposes the 
  //same set of methods/properties on the store instance
  //{commit} is a shorthand for context.commit, this is an 
  //ES2015 feature called argument destructuring
  Add({ commit }, notification) {
    //Get notification duration or use default duration
    let duration = notification.duration || defaultDuration

    //Create a timeout to dismiss notification
    var timeOut = setTimeout(function () {
      //On timeout mutate state to dismiss notification
      commit(NOTIFICATION_DISMISSED, notification);
    }, duration);

    //Mutate state to add new notification, we create a new object 
    //for save original raw notification object and timeout reference
    commit(NOTIFICATION_ADDED, {
      Raw: notification,
      TimeOut: timeOut
    })
  },
  //Here we are using context object directly
  Dismiss(context, notification) {
    //Just pass payload
    context.commit(NOTIFICATION_DISMISSED, notification);
  }
}

모듈 변이를 설정하십시오.

const mutations = {
  //On mutations we receive current state and a payload
  [NOTIFICATION_ADDED](state, notification) {
    state.Notifications.push(notification);
  },
  //remember, current state and payload
  [NOTIFICATION_DISMISSED](state, rawNotification) {
    var i = state.Notifications.map(n => n.Raw).indexOf(rawNotification);
    if (i == -1) {
      return;
    }

    clearTimeout(state.Notifications[i].TimeOut);
    state.Notifications.splice(i, 1);
  }
}

정의 된 상태, getter, 액션 및 돌연변이를 사용하여 모듈 등록

_store.registerModule('notifications', {
  state,
  getters,
  actions,
  mutations
});

용법

componentA.vue

이 구성 요소는 모든 알림을 화면의 오른쪽 상단 모서리에 부트 스트랩 알림으로 표시하고 각 알림을 수동으로 해제 할 수도 있습니다.

<template>
<transition-group name="notification-list" tag="div" class="top-right">
  <div v-for="alert in alerts" v-bind:key="alert" class="notification alert alert-dismissible" v-bind:class="'alert-'+alert.type">
    <button v-on:click="dismiss(alert)" type="button" class="close" aria-label="Close"><span aria-hidden="true">&times;</span></button>
    <div>
      <div>
        <strong>{{alert.title}}</strong>
      </div>
      <div>
        {{alert.text}}
      </div>
    </div>
  </div>
</transition-group>
</template>

<script>
export default {
  name: 'arc-notifications',
  computed: {
    alerts() {
      //Get all notifications from store
      return this.$store.getters.Notifications;
    }
  },
  methods: {
    //Manually dismiss a notification
    dismiss(alert) {
      this.$store.dispatch('Dismiss', alert);
    }
  }
}
</script>
<style lang="scss" scoped>
$margin: 15px;

.top-right {
    top: $margin;
    right: $margin;
    left: auto;
    width: 300px;
    //height: 600px;
    position: absolute;
    opacity: 0.95;
    z-index: 100;
    display: flex;
    flex-wrap: wrap;
    //background-color: red;
}
.notification {
    transition: all 0.8s;
    display: flex;
    width: 100%;
    position: relative;
    margin-bottom: 10px;
    .close {
        position: absolute;
        right: 10px;
        top: 5px;
    }

    > div {
        position: relative;
        display: inline;
    }
}
.notification:last-child {
    margin-bottom: 0;
}
.notification-list-enter,
.notification-list-leave-active {
    opacity: 0;
    transform: translateX(-90px);
}
.notification-list-leave-active {
    position: absolute;
}
</style>

다른 구성 요소에 알림 추가 스 니펫

//payload could be anything, this example content matches with componentA.vue 
this.$store.dispatch('Add', {
  title = 'Hello',
  text = 'World',
  type = 'info',
  duration = 15000
});


Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow