±à¼ÍƼö: |
±¾ÎÄÀ´×Ôsegmentfault.com£¬ÔÚÕâÆª½Ì³ÌÖÐÎÒÃǽ«Í¨¹ý¹¹½¨Ò»¸ö±Ê¼ÇÓ¦ÓÃÀ´Ñ§Ï°ÈçºÎÔÚÎÒÃǵÄ
Vue ÏîÄ¿ÖÐʹÓà Vuex¡£ |
|
ÎÒÃǽ«´ó¸ÅµÄ¹ýÒ»±éʲôÊÇ Vuex.js£¬ÔÚÏîÄ¿ÖÐʲôʱºòʹÓÃËü£¬ºÍÈçºÎ¹¹½¨ÎÒÃǵÄ
Vue Ó¦Óá£
ÕâÀï·ÅÒ»ÕÅÎÒÃÇÏîÄ¿µÄÔ¤ÀÀͼƬ£º

ÏîĿԴÂ룺vuex-notes-app£»ÓÐÐèÒªµÄͬѧ¿ÉÒÔÖ±½ÓÏÂÔØÔ´Âë²é¿´¡£
Ö÷Ҫ֪ʶµã
Vuex ״̬¹ÜÀí»úÖÆµÄʹÓÃ
Vue.js µÄ»ù´¡ api
Vue-cli ½ÅÊּܵݲװ¼°Ê¹ÓÃ
vur-router µÄʹÓÃ
ES6 µÄÓï·¨£¬ÕâÀïÍÆ¼ö¿´ÏÂÈîÒ»·åµÄÈëÃŽ̳Ì
Vuex ¸ÅÊö
ÔÚÎÒÃÇÆÈ²»¼°´ýµÄ¿ªÊ¼ÏîĿ֮ǰ£¬ÎÒÃÇ×îºÃÏÈ»¨¼¸·ÖÖÓÀ´Á˽âÏ Vuex µÄºËÐĸÅÄî¡£
Vuex ÊÇÒ»¸öרÃÅΪ Vue.js Ó¦ÓÃËùÉè¼ÆµÄ¼¯ÖÐʽ״̬¹ÜÀí¼Ü¹¹¡£Ëü½è¼øÁË Flux ºÍ Redux
µÄÉè¼ÆË¼Ï룬µ«¼ò»¯Á˸ÅÄ²¢ÇÒ²ÉÓÃÁËÒ»ÖÖΪÄܸüºÃ·¢»Ó Vue.js Êý¾ÝÏìÓ¦»úÖÆ¶ø×¨ÃÅÉè¼ÆµÄʵÏÖ¡£
state ÕâÑù¸ÅÄî³õ´Î½Ó´¥µÄʱºò¿ÉÄÜ»á¸Ð¾õµ½ÓеãÄ£ºý£¬¼òµ¥À´Ëµ¾ÍÊǽ« state ¿´³ÉÎÒÃÇÏîÄ¿ÖÐʹÓõÄÊý¾ÝµÄ¼¯ºÏ¡£È»ºó£¬Vuex
ʹµÃ ×é¼þ±¾µØ×´Ì¬£¨component local state£©ºÍ Ó¦Óò㼶״̬(application
state) ÓÐÁËÒ»¶¨µÄ²îÒì
component local state: ¸Ã״̬±íʾ½ö½öÔÚ×é¼þÄÚ²¿Ê¹ÓõÄ״̬£¬ÓеãÀàËÆÍ¨¹ýÅäÖÃÑ¡Ïî´«Èë
Vue ×é¼þÄÚ²¿µÄÒâ˼¡£
application level state: Ó¦Óò㼶״̬£¬±íʾͬʱ±»¶à¸ö×é¼þ¹²ÏíµÄ״̬²ã¼¶¡£
¼ÙÉèÓÐÕâÑùÒ»¸ö³¡¾°£ºÎÒÃÇÓÐÒ»¸ö¸¸×é¼þ£¬Í¬Ê±°üº¬Á½¸ö×Ó×é¼þ¡£¸¸×é¼þ¿ÉÒÔºÜÈÝÒ×µÄͨ¹ýʹÓà props ÊôÐÔÀ´Ïò×Ó×é¼þ´«µÝÊý¾Ý¡£
µ«ÊÇÎÊÌâÀ´ÁË£¬µ±ÎÒÃǵÄÁ½¸ö×Ó×é¼þÈçºÎºÍ¶Ô·½»¥ÏàͨÐŵģ¿ »òÕß×Ó×é¼þÈçºÎ´«µÝÊý¾Ý¸øËû¸¸×é¼þµÄ£¿ÔÚÎÒÃǵÄÏîÄ¿ºÜСµÄʱºò£¬Õâ¸öÁ½¸öÎÊÌâ¶¼²»»áÌ«ÄÑ£¬ÒòΪÎÒÃÇ¿ÉÒÔͨ¹ýʼþÅÉ·¢ºÍ¼àÌýÀ´Íê³É¸¸×é¼þºÍ×Ó×é¼þµÄͨÐÅ¡£
È»¶ø£¬Ëæ×ÅÎÒÃÇÏîÄ¿µÄÔö³¤£º
±£³Ö¶ÔËùÓеÄʼþ×·×Ù½«±äµÃºÜÀ§ÄÑ¡£µ½µ×ÄĸöʼþÊÇÄĸö×é¼þÅÉ·¢µÄ£¬Äĸö×é¼þ¸Ã¼àÌýÄĸöʼþ£¿
ÏîÄ¿Âß¼·ÖÉ¢ÔÚ¸÷¸ö×é¼þµ±ÖУ¬ºÜÈÝÒ×µ¼ÖÂÂß¼µÄ»ìÂÒ£¬²»ÀûÓÚÎÒÃÇÏîÄ¿µÄά»¤¡£
¸¸×é¼þ½«±äµÃºÍ×Ó×é¼þñîºÏÔ½À´Ô½ÑÏÖØ£¬ÒòΪËüÐèÒªÃ÷È·µÄÅÉ·¢ºÍ¼àÌý×Ó×é¼þµÄijЩʼþ¡£
Õâ¾ÍÊÇ Vuex ÓÃÀ´½â¾öµÄÎÊÌâ¡£ Vuex µÄËĸöºËÐĸÅÄî·Ö±ðÊÇ£º
The state tree£ºVuex ʹÓõ¥Ò»×´Ì¬Ê÷£¬ÓÃÒ»¸ö¶ÔÏó¾Í°üº¬ÁËÈ«²¿µÄÓ¦Óò㼶״̬¡£ÖÁ´ËËü±ã×÷Ϊһ¸ö¡ºÎ¨Ò»Êý¾ÝÔ´(SSOT)¡»¶ø´æÔÚ¡£ÕâÒ²Òâζ×Å£¬Ã¿¸öÓ¦Óý«½ö½ö°üº¬Ò»¸ö
store ʵÀý¡£µ¥×´Ì¬Ê÷ÈÃÎÒÃÇÄܹ»Ö±½ÓµØ¶¨Î»ÈÎÒ»ÌØ¶¨µÄ״̬Ƭ¶Î£¬ÔÚµ÷ÊԵĹý³ÌÖÐÒ²ÄÜÇáÒ×µØÈ¡µÃÕû¸öµ±Ç°Ó¦ÓÃ״̬µÄ¿ìÕÕ¡£
Getters: ÓÃÀ´´Ó store »ñÈ¡ Vue ×é¼þÊý¾Ý¡£
Mutators: ʼþ´¦ÀíÆ÷ÓÃÀ´Çý¶¯×´Ì¬µÄ±ä»¯¡£
Actions: ¿ÉÒÔ¸ø×é¼þʹÓõĺ¯Êý£¬ÒÔ´ËÓÃÀ´Çý¶¯Ê¼þ´¦ÀíÆ÷ mutations
ÈçºÎÄãÔÝʱ»¹²»Ì«Àí½âÕâ¸öËĸö¸ÅÄ²»ÓÃ׿±£¬ÎÒÃǽ«ÔÚºóÃæµÄÏîĿʵսÖÐÏêϸµÄ½âÊÍ¡£
ÏÂÃæÕâÕÅͼÏêϸµÄ½âÊÍÁË Vuex Ó¦ÓÃÖÐÊý¾ÝµÄÁ÷Ïò£¨Vuex ¹Ù·½Í¼£©

¼òµ¥½âÊÍÏ£º
Vuex ¹æ¶¨£¬ÊôÓÚÓ¦Óò㼶µÄ״ֻ̬ÄÜͨ¹ý Mutation Öеķ½·¨À´Ð޸쬶øÅÉ·¢ Mutation
ÖеÄʼþÖ»ÄÜͨ¹ý action¡£
´Ó×óµ½ÓÖ£¬´Ó×é¼þ³ö·¢£¬×é¼þÖе÷Óà action£¬ÔÚ action ÕâÒ»²ã¼¶ÎÒÃÇ¿ÉÒԺͺǫ́Êý¾Ý½»»¥£¬±ÈÈç»ñÈ¡³õʼ»¯µÄÊý¾ÝÔ´£¬»òÕßÖмäÊý¾ÝµÄ¹ýÂ˵ȡ£È»ºóÔÚ
action ÖÐÈ¥ÅÉ·¢ Mutation¡£Mutation È¥´¥·¢×´Ì¬µÄ¸Ä±ä£¬×´Ì¬µÄ¸Ä±ä£¬½«´¥·¢ÊÓͼµÄ¸üС£
×¢ÒâÊÂÏî
Êý¾ÝÁ÷¶¼Êǵ¥ÏòµÄ
×é¼þÄܹ»µ÷Óà action
action ÓÃÀ´ÅÉ·¢ Mutation
Ö»ÓÐ mutation ¿ÉÒԸıä״̬
store ÊÇÏìӦʽµÄ£¬ÎÞÂÛ state ʲôʱºò¸üУ¬×é¼þ¶¼½«Í¬²½¸üÐÂ
»·¾³°²×°
Õâ¸öÓ¦Óý«Ê¹Óà webpack À´×öÄ£¿é´ò°ü£¬´¦ÀíºÍÈÈÖØÆô¡£Ê¹Óà Vue ¹Ù·½ÌṩµÄ½ÅÊÖ¼Ü vue-cli¡£
°²×° vue-cli
*Node.js >= 4.x,5.x×îºÃ
³õʼ»¯Ó¦ÓÃ
vue init webpack
vue-notes-app
cd vue-notes-app
npm install // °²×°ÒÀÀµ°ü
npm run dev // Æô¶¯·þÎñ |
³õʼ»¯Ò»¸öÏîÄ¿ÃûΪvue-notes-appµÄÓ¦Ó㬲¢Ñ¡ÔñʹÓà webpack ´ò°ü·½Ê½¡£ÔÚÃüÁîÐÐÖа´ÕÕÌáʾѡÔñ³õʼ»¯ÅäÖÃÏî¡£ÆäÖÐÔÚÑ¡Ôñ
JSLint УÑéµÄʱºò£¬ÍƼöÑ¡Ôñ AirBNB ¹æ·¶¡£
ʹÓÃÄã×îϲ»¶µÄ±à¼Æ÷´ò¿ªÎÒÃǸոÕн¨µÄÏîÄ¿£¬ÏîÄ¿µÄ½á¹¹´ó¸ÅÈçÏÂͼ£º

components/ Îļþ¼ÐÓÃÀ´´æ·ÅÎÒÃÇµÄ Vue ×é¼þ
vuex/ Îļþ¼Ð´æ·ÅµÄÊÇºÍ Vuex store Ïà¹ØµÄ¶«Î÷£¨state object£¬actions£¬mutators)
build/ ÎļþÊÇ webpack µÄ´ò°ü±àÒëÅäÖÃÎļþ
config/ Îļþ¼Ð´æ·ÅµÄÊÇһЩÅäÖÃÏ±ÈÈçÎÒÃÇ·þÎñÆ÷·ÃÎʵĶ˿ÚÅäÖõÈ
dist/ ¸ÃÎļþ¼ÐÒ»¿ªÊ¼ÊDz»´æÔÚ£¬ÔÚÎÒÃǵÄÏîÄ¿¾¹ý build Ö®ºó²Å»á²ú³ö
App.vue ¸ù×é¼þ£¬ËùÓеÄ×Ó×é¼þ¶¼½«ÔÚÕâÀï±»ÒýÓÃ
index.html Õû¸öÏîÄ¿µÄÈë¿ÚÎļþ£¬½«»áÒýÓÃÎÒÃǵĸù×é¼þ App.vue
main.js Èë¿ÚÎļþµÄ js Âß¼£¬ÔÚ webpack ´ò°üÖ®ºó½«±»×¢Èëµ½ index.html
ÖÐ
¹¦ÄÜÄ£¿é
ÐÂÔö±Ê¼Ç£¬ÐÂÔöһƪ±Ê¼Ç£¬±à¼ÇøÏÔʾ¿ÕµÄ±Ê¼ÇÄÚÈÝ
ɾ³ý±Ê¼Ç£¬É¾³ýһƪ±Ê¼ÇÖ®ºó£¬±à¼ÇøÓòÏÔʾµ±Ç°±Ê¼ÇÀà±ðµÄµÚÒ»Ïî
±Ê¼ÇÁбíÇл»£¬·ÖΪȫ²¿±Ê¼ÇºÍÊղرʼÇÁ½ÖÖ£¬ÔÚÇл»Ö®ºó£¬±à¼ÇøÓòÏÔʾµ±Ç°ÁбíµÄµÚÒ»Ìõ±Ê¼Ç
Êղرʼǣ¬¸øµ±Ç°¼¤»îµÄ±Ê¼Ç´òÉÏÊղصıêÇ©
ÏîÄ¿×é¼þ»®·Ö
ÔÚÕâ¸öÏîÄ¿ÖУ¬ÎÒÃǽ«×ܹ²Ê¹ÓÃËĸö×é¼þ£º¸ù×é¼þ App.vue£¬²Ù×÷À¸×é¼þ Toolbar.vue£¬±ð±í×é¼þ
NotesList.vue£¬±Ê¼Ç±à¼×é¼þ Editor.vue¡£

´´½¨ Vuex Store
°´ÕÕÉÏÃæÎÒÃÇÁгöÀ´µÄ¹¦ÄÜÄ£¿é£¬ÎÒÃÇÔÚ Vuex/ ÏÂÃæ½¨Á¢Ò»¸ö store.js Îļþ
rt Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
// ÐèҪά»¤µÄ״̬
const state = {
notes: [],
activeNote: {},
show: ''
};
const mutations = {
// ³õʼ»¯ state
INIT_STORE(state, data) {
state.notes = data.notes,
state.show = data.show;
state.activeNote = data.activeNote;
},
// ÐÂÔö±Ê¼Ç
NEW_NOTE(state) {
var newNote = {
id: +new Date(),
title: '',
content: '',
favorite: false
};
state.notes.push(newNote);
state.activeNote = newNote;
},
// Ð޸ıʼÇ
EDIT_NOTE(state, note) {
state.activeNote = note;
// ÐÞ¸ÄÔʼÊý¾Ý
for (var i = 0; i < state.notes.length; i++)
{
if(state.notes[i].id === note.id){
state.notes[i] = note;
break;
}
};
},
// ɾ³ý±Ê¼Ç
DELETE_NOTE(state) {
state.notes.$remove(state.activeNote);
state.activeNote = state.notes[0] || {};
},
// Çл»±Ê¼ÇµÄÊÕ²ØÓëÈ¡ÏûÊÕ²Ø
TOGGLE_FAVORITE(state) {
state.activeNote.favorite = !state.activeNote.favorite;
},
// Çл»ÏÔʾÊý¾ÝÁбíÀàÐÍ£ºÈ«²¿ or ÊÕ²Ø
SET_SHOW_ALL(state, show){
state.show = show;
// Çл»Êý¾Ýչʾ£¬ÐèҪͬ²½¸üРactiveNote
if(show === 'favorite'){
state.activeNote = state.notes.filter(note =>
note.favorite)[0] || {};
}else{
state.activeNote = state.notes[0] || {};
}
},
// ÉèÖõ±Ç°¼¤»îµÄ±Ê¼Ç
SET_ACTIVE_NOTE(state, note) {
state.activeNote = note;
}
};
export default new Vuex.Store({
state,
mutations
}); |
´´½¨ Vuex Actions
ÔÚ Vuex/ ÏÂÃæ½¨Á¢Ò»¸ö action.js£¬ÓÃÀ´¸ø×é¼þʹÓõĺ¯Êý
eAction(type)
{
return ({ dispatch }, ...args) => dispatch(type,
...args);
};
const initNote = {
id: +new Date(),
title: 'ÎҵıʼÇ',
content: 'µÚһƪ±Ê¼ÇÄÚÈÝ',
favorite: false
};
// Ä£Äâ³õʼ»¯Êý¾Ý
const initData = {
show: 'all',
notes: [initNote],
activeNote: initNote
};
export const initStore = ({ dispatch }) =>
{
dispatch('INIT_STORE', initData);
};
// ¸üе±Ç°activeNote¶ÔÏó
export const updateActiveNote = makeAction('SET_ACTIVE_NOTE');
// Ìí¼ÓÒ»¸önote¶ÔÏó
export const newNote = makeAction('NEW_NOTE');
// ɾ³ýÒ»¸önote¶ÔÏó
export const deleteNote = makeAction('DELETE_NOTE');
export const toggleFavorite = makeAction('TOGGLE_FAVORITE');
export const editNote = makeAction('EDIT_NOTE');
// ¸üÐÂÁбíչʾ
export const updateShow = makeAction('SET_SHOW_ALL'); |
´´½¨ Vuex Getters
ÔÚ vuex/ ÏÂÃæ½¨Á¢Ò»¸ö getter.js Îļþ£¬ÓÃÀ´´Ó store »ñÈ¡Êý¾Ý
// »ñÈ¡ noteList,ÕâÀォ»á¸ù¾Ý
state.show µÄ״̬×öÊý¾Ý¹ýÂË
export const filteredNotes = (state) => {
if(state.show === 'all'){
return state.notes || {};
}else if(state.show === 'favorite'){
return state.notes.filter(note => note.favorite)
|| {};
}
};
// »ñÈ¡Áбíչʾ״̬ £º all or favorite
export const show = (state) => {
return state.show;
};
// »ñÈ¡µ±Ç°¼¤»î note
export const activeNote = (state) => {
return state.activeNote;
}; |
ÒÔÉϾÍÊÇÎÒÃÇ Vuex µÄËùÓÐÂß¼ÁË£¬ÔÚ¶¨ÏÂÁËÎÒÃÇÐèÒªÍê³ÉµÄ¹¦ÄÜÖ®ºó£¬½ÓÏÂÀ´¾ÍÊÇÖ»ÐèÒªÔÚ×é¼þÖÐÈ¥µ÷ÓÃ
action À´ÊµÏÖ¶ÔÓ¦µÄ¹¦ÄÜÁË¡£
·ÓÉÅäÖÃ
ÔÚÕâÀïÎÒÃǽ«Ê¹Óà vue-router À´×ö·ÓÉ£¬ÒýÓà bootstrap Ñùʽ¡£
index.html
<html>
<head> <meta charset="utf-8">
<title>vuex-notes-app</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
</head> <body> <div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html> |
ËùÓеÄÈë¿ÚÂß¼ÎÒÃǶ¼½«ÔÚ main.js Öбàд
main.js
import Vue from
'vue';
import App from './App';
import VueRouter from 'vue-router';
import VueResource from 'vue-resource';
// ·ÓÉÄ£¿éºÍHTTPÄ£¿é
Vue.use(VueResource);
Vue.use(VueRouter);
const router = new VueRouter();
router.map({
'/index': {
component: App
}
});
router.redirect({
'*': '/index'
});
router.start(App, '#app'); |
¸ù×é¼þ App.vue
<template>
<div id="app" class="app">
<toolbar></toolbar> <notes-list></notes-list>
<editor></editor> </div>
</template>
<style>
html, #app {
height: 100%;
}
body {
margin: 0;
padding: 0;
border: 0;
height: 100%;
max-height: 100%;
position: relative;
}
</style>
<script> |
ÔÚ¸ù×é¼þÖÐÒýÓÃÁËÈý¸ö×Ó×é¼þ£ºToolbar.vue, NotesList.vue, Editor.vue¡£
×¢Ò⣺ÎÒÃÇÔÚÅäÖÃÀïÃæ¼ÓÈëÁË vuex Õâôһ¸öÑ¡ÏÕâÀïÓÃÀ´½«ÎÒÃÇ action ÀïÃæ¶¨ÒåµÄ·½·¨¸ø±©Â¶³öÀ´£¬ÎÒÃÇÔÚ¸ù×é¼þÖÐÖ»×öÁËÒ»¼þÊÂÇ飬ÄǾÍÊdzõʼ»¯Ä£ÄâÊý¾Ý£¬Òò´ËÎÒÃÇÔÚ×é¼þÉúÃüÖÜÆÚµÄ
ready ½×¶Îµ÷ÓÃÁË actions ÀïÃæµÄ initStore À´³õʼ»¯ÎÒÃÇµÄ store ÀïÃæµÄ
state
Toolbar.vue
<template>
<div id="toolbar"> <i class="glyphicon
logo"><img src="../assets/logo.png"
width="30" height="30"></i>
<i @click="newNote" class="glyphicon
glyphicon-plus"></i> <i @click="toggleFavorite"
class="glyphicon glyphicon-star" :class="{starred:
activeNote.favorite}"></i> <i
@click="deleteNote" class="glyphicon
glyphicon-remove"></i> </div>
</template>
<script>
import { newNote, deleteNote, toggleFavorite
} from '../vuex/actions';
import { activeNote } from '../vuex/getters';
export default {
vuex: {
getters: {
activeNote
},
actions: {
newNote,
deleteNote,
toggleFavorite
}
}
}
</script>
<style lang="scss" scoped>
#toolbar{
float: left;
width: 80px;
height: 100%;
background-color: #30414D;
color: #767676;
padding: 35px 25px 25px 25px;
.starred {
color: #F7AE4F;
}
i{
font-size: 30px;
margin-bottom: 35px;
cursor: pointer;
opacity: 0.8;
transition: opacity 0.5s ease;
&:hover{
opacity: 1;
}
}
}
</style> |
ÔÚÕâÀÎÒÃÇÓõ½ÁË Vuex µÄÒ»¸ö°¸Àý¾ÍÊÇÎÒÃÇÐèÒªÖªµÀµ±Ç°µÄ¼¤»îµÄ±Ê¼ÇÊÇ·ñÊÇÊÕ²ØÀà±ðµÄ£¬Èç¹ûÊÇ£¬ÎÒÃÇÐèÒª¸ßÁÁÊղذ´Å¥£¬ÄÇôÈçºÎÖªµÀÄØ£¿ÄǾÍÊÇͨ¹ý
vuex ÀïÃæµÄ getters »ñÈ¡µ±Ç°¼¤»îµÄ±Ê¼Ç¶ÔÏó£¬ÅжÏËüµÄ favorite ÊÇ·ñΪ true¡£
ʼÖÕÀμÇÒ»¸ö¸ÅÄvuex ÖÐÊý¾ÝÊǵ¥ÏòµÄ£¬Ö»ÄÜ´Ó store »ñÈ¡£¬¶øÎÒÃÇÕâ¸öÀý×ÓÖÐµÄ activeNote
Ò²ÊÇʼÖÕ¶¼ÔÚ store.js ÖÐά»¤µÄ£¬ÕâÑù×ӾͿÉÒÔ¸øÆäËû×é¼þ¹«ÓÃÁË
// ÐèҪά»¤µÄ״̬
const state = {
notes: [],
activeNote: {},
show: ''
}; |
NotesList.vue
<template>
<div id="notes-list"> <div
id="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>
<!-- äÖȾ±Ê¼ÇÁбí -->
<div class="container">
<div class="list-group">
<a v-for="note in filteredNotes"
class="list-group-item" href="#"
:class="{active: activeNote === note}"
@click="updateActiveNote(note)">
<h4 class="list-group-item-heading">
{{note.title.trim().substring(0,30)}}
</h4>
</a>
</div>
</div>
</div>
</template>
<script>
import { updateActiveNote, updateShow } from
'../vuex/actions';
import { show, filteredNotes, activeNote } from
'../vuex/getters';
export default {
vuex: {
getters: {
show,
filteredNotes,
activeNote
},
actions: {
updateActiveNote,
updateShow
}
},
methods: {
toggleShow(show) {
this.updateShow(show);
}
}
}
</script> |
±Ê¼ÇÁбí×é¼þ£¬Ö÷ÒªÓÐÈý¸ö²Ù×÷
äÖȾ±Ê¼Ç
Çл»äÖȾ±Ê¼Ç
µã»÷Áбí title£¬Çл» activeNote
ÎÒÃÇͨ¹ý getters ÖÐµÄ filteredNotes ·½·¨»ñÈ¡±Ê¼ÇÁбí
// »ñÈ¡ noteList,ÕâÀォ»á¸ù¾Ý
state.show µÄ״̬×öÊý¾Ý¹ýÂË
export const filteredNotes = (state) => {
if(state.show === 'all'){
return state.notes || {};
}else if(state.show === 'favorite'){
return state.notes.filter(note => note.favorite)
|| {};
}
}; |
¿ÉÒÔ¿´µ½£¬ÎÒÃÇ»ñÈ¡µÄÁбíÊÇÒÀÀµÓÚ state.show Õâ¸ö״̬µÄ¡£¶øÎÒÃǵÄÇл»Áбí²Ù×÷Ç¡ºÃ¾ÍÊǵ÷ÓÃ
actions ÀïÃæµÄ·½·¨À´¸üРstate.show £¬ÕâÑùÒ»À´£¬ÊµÏÖÁËÊý¾ÝÁбíµÄ¶¯Ì¬Ë¢Ð£¬¶øÇÒÎÒÃǶÔÊ÷µÄ²Ù×÷¶¼ÊÇͨ¹ýµ÷ÓÃ
actions µÄ·½·¨À´ÊµÏֵġ£
ÎÒÃÇÔÙ¿´£¬ÔÚÇл»ÁбíµÄʱºò£¬ÎÒÃÇ»¹ÐèÒª¶¯Ì¬µÄ¸üРactiveNote ¡£ ¿´¿´ÎÒÃÇÔÚ store.js
ÖÐÊÇÈçºÎ×öµÄ£º
// Çл»ÏÔʾÊý¾ÝÁбíÀàÐÍ£ºÈ«²¿
or ÊÕ²Ø
SET_SHOW_ALL(state, show){
state.show = show;
// Çл»Êý¾Ýչʾ£¬ÐèҪͬ²½¸üРactiveNote
if(show === 'favorite'){
state.activeNote = state.notes.filter(note =>
note.favorite)[0] || {};
}else{
state.activeNote = state.notes[0] || {};
}
} |
´¥·¢ÕâЩ²Ù×÷µÄÊÇÎÒÃǸøÁ½¸ö°´Å¥·Ö±ð°ó¶¨ÁËÎÒÃÇ×Ô¶¨ÒåµÄº¯Êý£¬Í¨¹ý¸øº¯Êý´«È벻ͬµÄ²ÎÊý£¬È»ºóµ÷Óà actions
ÀïÃæµÄ·½·¨£¬À´ÊµÏÖ¶ÔÊý¾ÝµÄ¹ýÂË£¬¸üС£
Editor.vue
<template>
<div id="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>
<script>
import { editNote } from '../vuex/actions';
import { activeNote } from '../vuex/getters';
export default {
vuex: {
getters: {
activeNote
},
actions: {
editNote
}
},
computed: {
// ͨ¹ý¼ÆËãÊôÐԵõ½µÄÒ»¸ö¶ÔÏó£¬ÕâÑù×ÓÎÒÃǾÍÄÜÓä¿ìµÄʹÓà v-model ÁË
currentNote: activeNote
},
methods: {
// ΪʲôÕâô×ö£¿ ÒòΪÔÚÑϸñģʽÖв»ÔÊÐíÖ±½ÓÔÚÄ£°å²ãÃæÈ¥ÐÞ¸Ä state ÖеÄÖµ
updateNote() {
this.editNote(this.currentNote);
}
}
}
</script> |
ÔÚ Editor.vue ×é¼þÖУ¬ÎÒÃÇÐèÒªÄܹ»ÊµÊ±µÄ¸üе±Ç°µÄ activeNote ×é¼þºÍÁбíÖжÔÓ¦µÄÎÒÃÇÕýÔÚÐ޸ĵıʼǶÔÏóµÄÄÚÈÝ¡£
ÓÉÓÚÎÒÃÇÇ°ÃæÌáµ½¹ý£¬ÔÚ×é¼þÖÐÊDz»ÔÊÐíÖ±½ÓÐÞ¸Ä store.jsÔÚÀïÃæµÄ״ֵ̬µÄ£¬ËùÒÔÔÚÕâÀïµÄʱºò£¬ÎÒÃÇͨ¹ýÒ»¸ö¼ÆËãÊôÐÔ£¬½«
store ÀïÃæµÄ״ֵ̬¸³Öµ¸øÒ»¸ö¶ÔÏó£¬È»ºóÔÚ×Ô¶¨ÒåµÄ updateNotes() ·½·¨ÖУ¬È¥µ÷ÓÃ
action,ͬʱ´«Èë currentNote ¶ÔÏó¡£
ÔÚ store.js ÖУ¬ÎÒÃÇÊÇÕâô×öµÄ£¬ÕÒµ½¶ÔÓ¦µÄ id µÄ¶ÔÏó£¬ÖØÐ¸³Öµ£¬ÒòÎªÇ°ÃæÌáµ½¹ý£¬ÎÒÃǵÄÊý¾ÝÊÇÏìӦʽµÄ£¬ÔÚÕâÀï½øÐÐÁ˸ı䣬¶ÔÓ¦µÄÊÓͼҲ½«Ë¢Ð¸ı䣬ÕâÑùÒ»À´¾ÍʵÏÖÁËʵʱ±à¼£¬ÊµÊ±äÖȾµÄ¹¦ÄÜÁË¡£
// Ð޸ıʼÇ
EDIT_NOTE(state, note) {
state.activeNote = note;
// ÐÞ¸ÄÔʼÊý¾Ý
for (var i = 0; i < state.notes.length; i++)
{
if(state.notes[i].id === note.id){
state.notes[i] = note;
break;
}
};
}, |
Q&A
ÔÚÕâ¸öÏîÄ¿ÖУ¬ÎÒÃDz¢Ã»ÓÐÒýÈë vue-resource ²å¼þ£¬Ö»ÊÇ×Ô¼ºÄ£ÄâÁ˲¿·ÖµÄÊý¾Ý£¬ÓÐÐËȤµÄͬѧ¿ÉÒÔ×Ô¼ºÈ¥ÊÔÊÔ¡£
ÓÉÓÚÎÒÃǵÄÀý×ÓÏà¶Ô¼òµ¥£¬Ã»ÓÐÉæ¼°µ½ºÜÉîÈëµÄ¶«Î÷£¬¸üÉî²ã´ÎµÄÑо¿ÐèÒª´ó¼Ò»¨¸ü¶àµÄʱ¼äȥʵ¼ùÁË¡£
×îºó£¬ÔÙ˵һ¾ä£¬ÔÚ action ÀïÃæ£¬ÎÒÃÇÆäʵ¿ÉÒÔ×öµÄ»¹Óиü¶à£¬±ÈÈç¸ù¾Ý id ¶¯Ì¬µÄÒì²½»ñÈ¡±Ê¼ÇÄÚÈݵȵȣ¬ÕâЩÓÐÐËȤµÄͬѧ¿ÉÒÔ×Ô¼ºÈ¥³¢ÊÔ£¬Ò»µãµãµÄ·á¸»Õâ¸öÀý×Ó¡£
|