Äú¿ÉÒÔ¾èÖú£¬Ö§³ÖÎÒÃǵĹ«ÒæÊÂÒµ¡£

1Ôª 10Ôª 50Ôª





ÈÏÖ¤Â룺  ÑéÖ¤Âë,¿´²»Çå³þ?Çëµã»÷Ë¢ÐÂÑéÖ¤Âë ±ØÌî



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓÆµ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Model Center   Code  
»áÔ±   
   
 
     
   
 ¶©ÔÄ
  ¾èÖú
Vuex2.0СÃ×±ãÇ©ÏîĿʵÀý
 
  2968  次浏览      32
  2018-11-26
 
±à¼­ÍƼö:
±¾ÎÄÀ´×Ôsegmentfault£¬ÎÄÕÂÖ÷Òª´Ó¹¹½¨Ò»¸öСÃ×±ãǩӦÓÃÀ´Ñ§Ï°ÔõôʹÓÃVuexµÈÏà¹ØÄÚÈÝ¡£

ÔÚÕâ¸ö½Ì³ÌÖУ¬ÎÒÃÇ»áͨ¹ý¹¹½¨Ò»¸öСÃ×±ãǩӦÓÃÀ´Ñ§Ï°ÔõôʹÓÃVuex,¿ªÊ¼ÎÒ»á¼òµ¥µÄ½éÉÜVuexµÄһЩ»ù´¡ÄÚÈÝ£¬Ê²Ã´Ê±ºòʹÓÃÒÔ¼°ÓÃVuexÔõô×éÖ¯´úÂ룬ȻºóÒ»²½Ò»²½µÄ°ÑÕâЩ¸ÅÄîÓ¦Óõ½Ð¡Ã×±ãǩӦÓÃÀïÃæ¡£

·Ï»°²»¶à˵£¬Ïȸø´ó¼Ò¿´Ò»ÏÂСÃ×±ãǩӦÓõĽØÍ¼£º

Äã¿ÉÒÔ´ÓGitHubÉÏÏÂÔØÔ´Â룬ÕâÀïÊÇÏîĿԴ´úÂëµÄµØÖ·ºÍÔÚÏßÔ¤ÀÀµØÖ·£¬°²×°³É¹¦ºóÍÆ¼öʹÓÃchromeµÄÉ豸ģʽ²é¿´Ð§¹û¸ü¼Ñ¡£

Vuex¸ÅÊö

Vuex ÊÇÒ»¸öרÃÅΪ Vue.js Ó¦ÓÃËùÉè¼ÆµÄ¼¯ÖÐʽ״̬¹ÜÀí¼Ü¹¹£¬Ëü½è¼øÁË Flux ºÍ Redux µÄÉè¼ÆË¼Ï룬µ«¼ò»¯Á˸ÅÄ²¢ÇÒ²ÉÓÃÁËÒ»ÖÖΪÄܸüºÃ·¢»Ó Vue.js Êý¾ÝÏìÓ¦»úÖÆ¶ø×¨ÃÅÉè¼ÆµÄʵÏÖ¡£

Èç¹ûÄ㲻̫Àí½â Vue.js Ó¦ÓÃÀïµÄ״̬ÊÇʲôÒâ˼µÄ»°£¬Äã¿ÉÒÔÏëÏóÒ»ÏÂÄã´ËǰдµÄ Vue ×é¼þÀïÃæµÄ data ×ֶΡ£Vuex °Ñ״̬·Ö³É×é¼þÄÚ²¿×´Ì¬ºÍÓ¦Óü¶±ð״̬£º

×é¼þÄÚ²¿×´Ì¬£º½öÔÚÒ»¸ö×é¼þÄÚʹÓõÄ״̬(data ×Ö¶Î)

Ó¦Óü¶±ð״̬£º¶à¸ö×é¼þ¹²ÓõÄ״̬

¾Ù¸öÀý×Ó£º±ÈÈç˵ÓÐÒ»¸ö¸¸×é¼þ£¬ËüÓÐÁ½¸ö×Ó×é¼þ¡£Õâ¸ö¸¸×é¼þ¿ÉÒÔÓà props Ïò×Ó×é¼þ´«µÝÊý¾Ý£¬ÕâÌõÊý¾ÝͨµÀºÜºÃÀí½â¡£

ÄÇÈç¹ûÕâÁ½¸ö×Ó×é¼þÏ໥֮¼äÐèÒª¹²ÏíÊý¾ÝÄØ?»òÕß×Ó×é¼þÐèÒªÏò¸¸×é¼þ´«µÝÊý¾ÝÄØ?ÕâÁ½¸öÎÊÌâÔÚÓ¦ÓÃÌåÁ¿½ÏСµÄʱºò¶¼ºÃ½â¾ö£¬Ö»ÒªÓÃ×Ô¶¨Òåʼþ¼´¿É¡£

µ«ÊÇËæ×ÅÓ¦ÓùæÄ£µÄÀ©´ó£º

×·×ÙÕâЩʼþÔ½À´Ô½ÄÑÁË¡£Õâ¸öʼþÊÇÄĸö×é¼þ´¥·¢µÄ£¿Ë­ÔÚ¼àÌýËü£¿

ÒµÎñÂß¼­±é²¼¸÷¸ö×é¼þ£¬µ¼Ö¸÷ÖÖÒâÏë²»µ½µÄÎÊÌâ¡£

ÓÉÓÚÒªÏÔʽµØ·Ö·¢ºÍ¼àÌýʼþ£¬¸¸×é¼þºÍ×Ó×é¼þÇ¿ñîºÏ¡£

Vuex Òª½â¾öµÄ¾ÍÊÇÕâЩÎÊÌ⣬Vuex ±³ºóÓÐËĸöºËÐĵĸÅÄ

State: °üº¬ËùÓÐÓ¦Óü¶±ð״̬µÄ¶ÔÏó

Getters: ÔÚ×é¼þÄÚ²¿»ñÈ¡ store ÖÐ״̬µÄº¯Êý

Mutations: ÐÞ¸Ä״̬µÄʼþ»Øµ÷º¯Êý

Actions: ×é¼þÄÚ²¿ÓÃÀ´·Ö·¢ mutations ʼþµÄº¯Êý

ÏÂÃæÕâÕÅͼÍêÃÀµØ½âÊÍÁËÒ»¸ö Vuex Ó¦ÓÃÄÚ²¿µÄÊý¾ÝÁ÷¶¯£º

ÕâÕÅͼµÄÖØµã£º

Êý¾ÝÁ÷¶¯Êǵ¥ÏòµÄ

×é¼þ¿ÉÒÔµ÷Óà actions

Actions ÊÇÓÃÀ´·Ö·¢ mutations µÄ

Ö»ÓÐ mutations ¿ÉÒÔÐÞ¸Ä״̬

store ÊÇ·´Ó¦Ê½µÄ£¬¼´£¬×´Ì¬µÄ±ä»¯»áÔÚ×é¼þÄÚ²¿µÃµ½·´Ó³

´î½¨ÏîÄ¿

ÏîÄ¿½á¹¹£º

ÏîÄ¿Ö÷ÒªÎļþ´æ·ÅÓÚsrcĿ¼Ï£º

assets/¹«¹²Í¼Æ¬£¬cssÎļþ

components/°üº¬ËùÓÐ×é¼þ

libs/À©Õ¹Îļþ

router/·ÓÉÎļþ

store/vuexÏà¹ØÎļþ(state,actions,getters,mutation)

App.vue¸ù×é¼þ

main.jsÓ¦ÓÃ×ÜÈë¿Ú

н¨ÏîÄ¿£º

ʹÓÃvue-cli½ÅÊּܣ¬¿ÉÓÃÓÚ¿ìËٴ´óÐ͵¥Ò³Ó¦Ó᣸ù¤¾ßΪÏÖ´ú»¯µÄǰ¶Ë¿ª·¢¹¤×÷Á÷ÌṩÁË¿ªÏä¼´ÓõĹ¹½¨ÅäÖá£Ö»Ð輸·ÖÖÓ¼´¿É´´½¨²¢Æô¶¯Ò»¸ö´øÈÈÖØÔØ¡¢±£´æÊ±¾²Ì¬¼ì²éÒÔ¼°¿ÉÓÃÓÚÉú²ú»·¾³µÄ¹¹½¨ÅäÖõÄÏîÄ¿£º

# °²×°vue
npm install vue
# È«¾Ö°²×° vue-cli
npm install --global vue-cli
# ´´½¨Ò»¸ö»ùÓÚ webpack Ä£°åµÄÐÂÏîÄ¿
vue init webpack notepad-xiaomi
# °²×°ÒÀÀµ£¬×ßÄã
cd notepad-xiaomi
# °²×°ÒÀÀµ
npm install muse-ui vue-awesome --save
# °²×°vuex
npm install vue vuex --save
# ÔËÐÐ
npm run dev

ʹÓÃvue-cli½ÅÊּܴ´½¨ÏîĿʱ£¬Ò»¶¨Òª°²×°vue-router²å¼þ¡£

°²×°ÒÀÀµºóÔÙmain.jsÖÐÒýÓÃ

´´½¨Vuex Store

ÔÚstoreÎļþ¼ÐÏ´´½¨µÚÒ»¸öindex.js£º

import Vue from 'vue'
import Vuex from 'vuex'
import state from './state'
import mutations from './mutation'
import * as getters from './getters'
import * as actions from './actions'

Vue.use(Vuex)

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

ÏÖÔÚÎÒÓÃÏÂÃæÕâÕÅͼ°ÑÓ¦Ó÷ֽâ³É¶à¸ö×é¼þ£¬²¢°Ñ×é¼þÄÚ²¿ÐèÒªµÄÊý¾Ý¶ÔÓ¦µ½ store.js ÀïµÄ state¡£

App¸ù×é¼þ£¬µÚÒ»·ùͼÖеĺìÉ«ºÐ×Ó

HeaderÍ·²¿×é¼þ£¬µÚÒ»·ùͼÖеÄÂÌÉ«ºÐ×Ó

NoteListÁбí×é¼þ£¬µÚÒ»·ùͼÖеijÈÉ«ºÐ×Ó

ToolBar¹¤¾ßÀ¸×é¼þ£¬µÚÒ»·ùͼÖеÄÀ¶É«ºÐ×Ó£¨°üÀ¨É¾³ýºÍÒÆ¶¯°´Å¥£©

Editor±à¼­×é¼þ£¬µÚ¶þ·ùͼ£¬

NoteFolder±ãÇ©¼Ð×é¼þ£¬µÚÈý·ùͼ

TrashHeader·Ïֽ¨ͷ²¿×é¼þ£¬µÚËÄ·ùͼÀ¶É«ºÐ×Ó

TrashNoteList·Ïֽ¨Áбí×é¼þ£¬µÚËÄ·ùͼ»ÒÉ«ºÐ×Ó

TrashToolBar·Ïֽ¨¹¤¾ßÀ¸×é¼þ£¬µÚËÄ·ùͼ»ÆÉ«ºÐ×Ó

state.jsÀïÃæµÄ״̬¶ÔÏó»á°üº¬ËùÓÐÓ¦Óü¶±ðµÄ״̬£¬Ò²¾ÍÊǸ÷¸ö×é¼þÐèÒª¹²ÏíµÄ״̬¡£

±Ê¼ÇÁбí(notes: [])°üº¬ÁË NodesList ×é¼þÒªäÖȾµÄ notes ¶ÔÏó¡£µ±Ç°±ãÇ©(activeNote: {})Ôò°üº¬µ±Ç°±à¼­µÄ±ãÇ©¶ÔÏ󣬶à¸ö×é¼þ¶¼ÐèÒªÕâ¸ö¶ÔÏó¡£

ÁÄÍêÁË״̬state,ÎÒÃÇÀ´¿´¿´ mutations, ÎÒÃÇҪʵÏÖµÄ mutation ·½·¨°üÀ¨£º

Ìí¼Ó±êÇ©µ½notesÊý×éÖÐ

±à¼­Ñ¡ÖбãÇ©

ɾ³ý±ãÇ©

±ãÇ©²¼¾Ö

¹´Ñ¡±ãÇ©

È«²¿/È¡Ïû¹´Ñ¡±ãÇ©

±£´æ±ãÇ©

¹´Ñ¡·Ïֽ¨±ãÇ©

È«²¿/È¡Ïû¹´Ñ¡·Ïֽ¨±ãÇ©

»Ö¸´·Ïֽ¨±ãÇ©

mutation-typesÖÐÓÃÓÚ½«³£Á¿·ÅÔÚµ¥¶ÀµÄÎļþÖУ¬·½±ãЭ×÷¿ª·¢¡£

export const NEW_NOTE = 'NEW_NOTE'
export const EDIT_NOTE = 'EDIT_NOTE'
export const TOGGLE_NOTE = 'TOGGLE_NOTE'
export const CANCEL_CHECK = 'CANCEL_CHECK'
export const ALL_CHECK = 'ALL_CHECK'
export const DELETE_NOTE = 'DELETE_NOTE'
export const BACK_SAVE = 'BACK_SAVE'
export const TOGGLE_TRASHNOTE = 'TOGGLE_TRASHNOTE'
export const CANCEL_TRASHCHECk = 'CANCEL_TRASHCHECk'
export const ALL_TRASHCHECK = 'ALL_TRASHCHECK'
export const DELETE_TRASHNOTE = 'DELETE_TRASHNOTE'
export const RECOVERY_NOTE = 'RECOVERY_NOTE'

Ê×ÏÈ£¬´´½¨Ò»ÌõеıãÇ©£¬ÎÒÃÇÐèÒª×öµÄÊÇ:

н¨Ò»¸ö¶ÔÏó

³õʼ»¯ÊôÐÔ

pushµ½state.notesÊý×éÖÐ

[types.NEW_NOTE](state) {
let newNote = {
id: +new Date(),
date: new Date().Format('yyyy-MM-dd hh:mm'),
content: '',
done: false
}
state.notes.push(newNote)
}

È»ºó£¬±à¼­±ãÇ©ÐèÒªÓñʼÇÄÚÈÝ content ×÷²ÎÊý£º

[types.EDIT_NOTE](state, note) {
state.activeNote = note;
}

ʣϵÄÕâЩ mutations ºÜ¼òµ¥¾Í²»Ò»Ò»×¸ÊöÁË¡£Õû¸ö store/mutation.js ÈçÏ£º

import Format from '../libs/dateFormat'
import * as types from './mutation-types';

const mutations = {
[types.NEW_NOTE](state) {
let newNote = {
id: +new Date(),
date: new Date().Format('yyyy-MM-dd hh:mm'),
content: '',
done: false
}
state.notes.push(newNote)
},
[types.EDIT_NOTE](state, note) {
state.activeNote = note;
},
[types.TOGGLE_NOTE](state, note) {
state.notes.map((item, i) => {
if (item.id == note.id) {
item.done = !note.done;
}
})
if (note.done) {
state.deleteNotes.push(note);
} else {
state.deleteNotes.splice(state.deleteNotes.
indexOf(note), 1);
}
},
[types.CANCEL_CHECK](state) {
state.notes.map((item, i) => {
item.done = false;
})
state.deleteNotes = [];
state.isCheck = false;
},
[types.ALL_CHECK](state, done) {
state.deleteNotes = [];
state.notes.map((item, i) => {
item.done = done;
if (done) {
state.deleteNotes.push(item);
} else {
state.deleteNotes = [];
}
})
},
[types.DELETE_NOTE](state) {
state.deleteNotes.map((item, i) => {
item.done = false;
state.notes.splice(state.notes.indexOf(item), 1);
state.trashNotes.push(item)
})
state.isCheck = false;
state.deleteNotes = [];
},
[types.BACK_SAVE](state, note) {
if (note.content != '') return;
state.notes.splice(state.notes.indexOf(note), 1);
},
[types.TOGGLE_TRASHNOTE](state, note) {
state.trashNotes.map((item, i) => {
if (item.id == note.id) {
item.done = !note.done;
}
})
if (note.done) {
state.deleteTrashNotes.push(note);
} else {
state.deleteTrashNotes.splice(state.
deleteTrashNotes.indexOf(note), 1);
}
},
[types.CANCEL_TRASHCHECk](state) {
state.trashNotes.map((item, i) => {
item.done = false;
})
state.deleteTrashNotes = [];
state.isTrashCheck = false;
},
[types.ALL_TRASHCHECK](state, done) {
state.deleteTrashNotes = [];
state.trashNotes.map((item, i) => {
item.done = done;
if (done) {
state.deleteTrashNotes.push(item);
} else {
state.deleteTrashNotes = [];
}
})
},
[types.DELETE_TRASHNOTE](state) {
state.deleteTrashNotes.map((item, i) => {
state.trashNotes.splice(state.trashNotes.indexOf(item), 1);
})
state.deleteTrashNotes = [];
state.isTrashCheck = false;
},
[types.RECOVERY_NOTE](state) {
state.deleteTrashNotes.map((item, i) => {
item.done = false;
state.notes.unshift(item)
state.trashNotes.splice(state.trashNotes.indexOf(item), 1);
})
state.deleteTrashNotes = [];
state.isTrashCheck = false;
}
}

export default mutations;

½ÓÏÂÀ´ÁÄ actions, actions ÊÇ×é¼þÄÚÓÃÀ´·Ö·¢ mutations µÄº¯Êý¡£ËüÃǽÓÊÕ store ×÷ΪµÚÒ»¸ö²ÎÊý¡£±È·½Ëµ£¬µ±Óû§µã»÷ Toolbar ×é¼þµÄÌí¼Ó°´Å¥Ê±£¬ÎÒÃÇÏëÒªµ÷ÓÃÒ»¸öÄÜ·Ö·¢NEW_NOTE mutation µÄ action¡£ÏÖÔÚÎÒÃÇÔÚ store/Îļþ¼ÐÏ´´½¨Ò»¸ö actions.js ²¢ÔÚÀïÃæÐ´ÉÏ newNoteº¯Êý:

// ´´½¨Ð±ãÇ©
export const newNote = ({ commit }) => {
commit(types.NEW_NOTE)
}

ÆäËûµÄÕâЩactions¶¼ÀàËÆ£¬Õû¸östore/actions.jsÈçÏ£º

import * as types from './mutation-types';

//´´½¨Ð±ãÇ©
export const newNote = ({ commit }) => {
commit(types.NEW_NOTE)
}

//±à¼­±ãÇ©
export const editNote = ({ commit }, note) => {
commit(types.EDIT_NOTE, note)
}

//¹´Ñ¡±ãÇ©
export const toggleNote = ({ commit }, note) => {
commit(types.TOGGLE_NOTE, note)
}

//È¡Ïû¹´Ñ¡±ãÇ©
export const cancelCheck = ({ commit }) => {
commit(types.CANCEL_CHECK)
}

//È«²¿¹´Ñ¡
export const allCheck = ({ commit }, done) => {
commit(types.ALL_CHECK, done)
}

//ɾ³ý±ãÇ©
export const deleteNote = ({ commit }) => {
commit(types.DELETE_NOTE)
}

//·µ»Ø×Ô¶¯±£´æ
export const backSave = ({ commit }, note) => {
commit(types.BACK_SAVE, note)
}

//¹´Ñ¡·Ïֽ¨±ãÇ©
export const toggleTrashNote = ({ commit }, note) => {
commit(types.TOGGLE_TRASHNOTE, note)
}

//È¡Ïû¹´Ñ¡·Ïֽ¨±ãÇ©
export const cancelTrashCheck = ({ commit }) => {
commit(types.CANCEL_TRASHCHECk)
}

//ȫѡ·Ïֽ¨±ãÇ©
export const allTrashCheck = ({ commit }, done) => {
commit(types.ALL_TRASHCHECK, done)
}

//ɾ³ý·Ïֽ¨±ãÇ©
export const deleteTrashNote = ({ commit }) => {
commit(types.DELETE_TRASHNOTE)
}

//»Ö¸´±ãÇ©
export const recoveryNote = ({ commit }) => {
commit(types.RECOVERY_NOTE)
}

×îºó˵һÏÂgetters,ÔÚStore²Ö¿âÀstate¾ÍÊÇÓÃÀ´´æ·ÅÊý¾Ý£¬ÈôÊǶÔÊý¾Ý½øÐд¦ÀíÊä³ö£¬±ÈÈçÊý¾ÝÒª¹ýÂË£¬Ò»°ãÎÒÃÇ¿ÉÒÔдµ½computedÖС£µ«ÊÇÈç¹ûºÜ¶à×é¼þ¶¼Ê¹ÓÃÕâ¸ö¹ýÂ˺óµÄÊý¾Ý£¬±ÈÈç±ý״ͼ×é¼þºÍÇúÏßͼ×é¼þ£¬ÎÒÃÇÊÇ·ñ¿ÉÒÔ°ÑÕâ¸öÊý¾Ý³éÌá³öÀ´¹²Ïí£¿Õâ¾ÍÊÇgetters´æÔÚµÄÒâÒå¡£ÎÒÃÇ¿ÉÒÔÈÏΪ£¬gettersÊÇstoreµÄ¼ÆËãÊôÐÔ

// ËÑË÷¹ýÂ˱ãÇ©
export const filterNote = (state) => {
if (state.search != '' && state.notes.length > 0) {
return state.notes.filter(note => note.content.indexOf(state.search) > -1) || {}
} else {
return state.notes || {}
}
}
// µ±Ç°±à¼­µÄ±ãÇ©
export const activeNote = (state) => {
return state.activeNote
}
// ±ãÇ©ÁÐ±í²¼¾Ö
export const layout = state => state.layout
// ±ãǩѡÖÐ״̬
export const isCheck = state => state.isCheck
// ·Ïֽ¨±ãǩѡÖÐ״̬
export const isTrashCheck = state => state.isTrashCheck

ÕâÑù£¬ÔÚ storeÎļþ¼ÐÀïÃæÒªÐ´µÄ´úÂë¾Í¶¼Ð´ÍêÁË¡£ÕâÀïÃæ°üÀ¨ÁË state.js ÖÐµÄ state ºÍ mutation.jsÖеÄmutations,ÒÔ¼° actions.js ÀïÃæÓÃÀ´·Ö·¢ mutations µÄ actions£¬ºÍgetters.jsÖеĴ¦ÀíÊä³ö¡£

¹¹½¨Vue×é¼þ

×îºóÕâ¸öС½á£¬ÎÒÃÇÀ´ÊµÏÖËĸö×é¼þ (App, Header,Toolbar, NoteList ºÍ Editor) ²¢Ñ§Ï°ÔõôÔÚÕâЩ×é¼þÀïÃæ»ñÈ¡ Vuex store ÀïµÄÊý¾ÝÒÔ¼°µ÷Óà actions¡£

´´½¨¸ùʵÀý - main.js

main.jsÊÇÓ¦ÓõÄÈë¿ÚÎļþ£¬ÀïÃæÓиùʵÀý£¬ÎÒÃÇÒª°Ñ Vuex store ¼Óµ½µ½Õâ¸ö¸ùʵÀýÀïÃæ£¬½ø¶ø×¢Èëµ½ËüËùÓеÄ×Ó×é¼þÀïÃæ£º

// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'
import store from './store/index'

/* µÚÈý·½²å¼þ */
import MuseUI from 'muse-ui'
import 'muse-ui/dist/muse-ui.css'
import 'muse-ui/dist/theme-teal.css'
import Icon from 'vue-awesome/components/Icon'
import 'vue-awesome/icons/flag'
import 'vue-awesome/icons'


Vue.use(MuseUI)
Vue.component('icon', Icon);
Vue.config.productionTip = false


/* eslint-disable no-new */
new Vue({
el: '#app',
router,
store,
components: { App },
template: '<App/>'
})

App - ¸ù×é¼þ

¸ù×é¼þ App ×÷Ϊ×ܵÄ·ÓÉÈë¿Ú:

<template>
<div id="app">
<router-view/>
</div>
</template>

<script>
export default {
name: 'App'
}
</script>

Notepad

Notepad ×é¼þ»á import ÆäÓàÈý¸ö×é¼þ£ºHeader,NoteListºÍToolBar£º

<template>
<div class="notepad">
<Header />
<NoteList />
<ToolBar />
</div>
</template>

<script>
import Header from './Header'
import NoteList from './NoteList'
import ToolBar from './ToolBar'
export default {
name: 'Notepad',
data () {
return {
}
},
components:{
Header,
NoteList,
ToolBar,
}
}
</script>

Header

Header×é¼þÌṩËÑË÷ºÍ±ãÇ©¹´Ñ¡ºÍÈ¡Ïû£¬²¢Í³¼Æ¹´Ñ¡ÊýÁ¿¹¦ÄÜ£¬Èçͼ£º

¶ÔÓÚHeader×é¼þÀ´Ëµ£¬ËÑË÷¿òÖÐÊäÈë²éѯÄÚÈÝʱ£¬ÐèÒª¶Ô±ãÇ©ÁбíÖеÄÊý¾Ý½øÐйýÂË£¬ÔÚ´´½¨state.jsµÄʱºò¾ÍÌí¼ÓÁËsearch×ֶΣ¬ÓÃÓÚ´æ´¢ËÑË÷ÄÚÈÝ£¬¶øÔÚgetters.jsÖÐͨ¹ýfilterNote·½·¨¶Ô±ãÇ©ÁÐ±í½øÐйýÂË£¬É¸Ñ¡³ö·ûºÏÌõ¼þµÄ±ãÇ©²¢·µ»Ø£¬ÕâʱºòÎÒÃÇÔÚNoteList×é¼þÖоÍÖ±½Ó±éÀúfilterNote·½·¨¾Í¿ÉÒÔʵÏÖËÑË÷¹¦ÄÜ¡£

store/gettersÖÐʵÏÖfilterNote·½·¨

// ËÑË÷¹ýÂ˱ãÇ©
export const filterNote = (state) => {
if (state.search != '' && state.notes.length > 0) {
return state.notes.filter(note => note.content.indexOf(state.search) > -1) || {}
} else {
return state.notes || {}
}
}

NoteList×é¼þÖбéÀúfilterNote

<li v-for="note in filterNote" :key="note.id" @mousedown="gtouchstart(note)" @mouseup="gtouchend(note)" @touchstart="loopstart(note)" @touchend="clearLoop">
<h4>{{note.date}}</h4>
<p>{{note.content}}</p>
<mu-checkbox label="" v-model="note.done" class="checkbox" v-show="isCheck"/>
</li>

Header×é¼þ£º

...mapGettersÖеÄ...ÊÇes6µÄÀ©Õ¹ÔËËã·û£¬²»¶®µÄ¿ÉÒÔ²éÔÄes6Îĵµ

<template>
<header class="header" :class="{visible:isVisible}">
<mu-flexbox class="headerTool" :class="{visible:isVisible}">
<mu-flexbox-item order="0" class="flex">
<mu-raised-button v-if="isCheck" label="È¡Ïû" @click="cancelCheck" class="raised-button"/>
<span v-else class="icon" @click="openFolder"><icon name="folder-open"></icon></span>
</mu-flexbox-item>
<mu-flexbox-item order="1" class="flex" style="text-align:center">
<span v-if="isCheck">{{checkTitle}}</span>
<span v-else>{{title}}</span>
</mu-flexbox-item>
<mu-flexbox-item order="2" class="flex" style="text-align:right">
<mu-raised-button v-if="isCheck" :label="checkBtnTxt" @click="allCheck(!allChecked)" class="raised-button"/>
<span v-else>
<span class="icon" v-if="layout=='grid'" @click="changeLayout"><icon name="list"></icon></span>
<span class="icon" v-else @click="changeLayout"><icon name="th-large"></icon></span>
</span>
</mu-flexbox-item>
</mu-flexbox>
<div class="search">
<div class="icon"><icon name="search"></icon></div>
<input type="text" v-model="searchTxt" @keyup="search" @focus="searchFocus" @blur="searchBlur"/>
</div>
</header>
</template>

<script>
import { mapActions,mapGetters } from 'vuex'
export default {
name: 'Header',
data(){
return {
title:'±ãÇ©',
checkBtnTxt:'ȫѡ',
searchTxt:'',
isVisible:false
}
},
computed:{
...mapGetters([
'layout',
'isCheck'
]),
//»ñÈ¡±ãÇ©¹´Ñ¡×´Ì¬
allChecked(){
return this.$store.state.notes.every(note => note.done)
},
//±ãǩѡÖÐÊýÁ¿Ìáʾ
checkTitle(){
return `ÒÑÑ¡Ôñ${this.$store.state.deleteNotes.length}Ïî`
}
},
methods:{
//ÏÔʾËÑË÷¿ò
searchFocus(){
this.isVisible = true;
},
//Òþ²ØËÑË÷¿ò
searchBlur(){
this.isVisible = false;
},
//ËÑË÷
search(){
this.$store.state.search = this.searchTxt
},
//Çл»²¼¾Ö
changeLayout(){
if(this.$store.state.layout == 'list'){
this.$store.state.layout = 'grid'
}else{
this.$store.state.layout = 'list'
}

},
//È¡Ïû¹´Ñ¡
cancelCheck(){
this.$store.dispatch('cancelCheck')
},
//ȫѡÇл»
allCheck(done){
this.checkBtnTxt = done?'È¡Ïûȫѡ':'ȫѡ'
this.$store.dispatch('allCheck',done)
},
//´ò¿ª±ãÇ©¼Ð
openFolder(){
this.$router.push({path:'noteFolder'})
}
}
}
</script>

NoteList

NotesList ×é¼þÖ÷ÒªÓÐÈý¸ö¹¦ÄÜ£º

äÖȾ±ãÇ©Áбí

¶Ô±ãÇ©½øÐй´Ñ¡»òÈ¡Ïû

µã»÷±à¼­±ãÇ©

<template>
<ul class="noteList" :class="layout">
<li v-for="note in filterNote" :key="note.id" @mousedown="gtouchstart(note)" @mouseup="gtouchend(note)" @touchstart="loopstart(note)" @touchend="clearLoop">
<h4>{{note.date}}</h4>
<p>{{note.content}}</p>
<mu-checkbox label="" v-model="note.done" class="checkbox" v-show="isCheck"/>
</li>
</ul>
</template>

<script>
import { mapGetters,mapActions } from 'vuex'
export default {
name: 'NoteList',
data(){
return {
timeOutEvent: 0,
Loop:null
}
},
computed:{
...mapGetters([
'filterNote',
'layout',
'isCheck'
])
},
methods:{
//±à¼­&Ñ¡ÖÐ
editNote(note){
if(this.isCheck){
this.$store.dispatch('toggleNote',note);
}else{
this.$store.dispatch('editNote',note);
this.$router.push({path:'/editor'})
}

},
//Êó±ê°´Ï£¬Ä£Äⳤ°´Ê¼þ
gtouchstart(note){
var _this = this;
this.timeOutEvent = setTimeout(function(){
_this.longPress(note)
},500);//ÕâÀïÉèÖö¨Ê±Æ÷£¬¶¨Ò峤°´500ºÁÃë´¥·¢³¤°´Ê¼þ£¬Ê±¼ä¿ÉÒÔ×Ô¼º¸Ä£¬¸öÈ˸оõ500ºÁÃë·Ç³£ºÏÊÊ
return false;
},
//Êó±ê·Å¿ª£¬Ä£Äⳤ°´Ê¼þ
gtouchend(note){
clearTimeout(this.timeOutEvent);//Çå³ý¶¨Ê±Æ÷
if(this.timeOutEvent!=0){
//ÕâÀïдҪִÐеÄÄÚÈÝ£¨ÓÈÈçonclickʼþ£©
this.editNote(note);
}
return false;
},
longPress(note){
this.timeOutEvent = 0;
this.$store.state.isCheck = true;
this.$store.dispatch('toggleNote',note);
},
//ÊÖ°´×¡¿ªÊ¼£¬Ä£Äⳤ°´Ê¼þ
loopstart(note){
var _this = this;
clearInterval(this.Loop);
¡¡¡¡¡¡¡¡¡¡¡¡ this.Loop = setTimeout(function(){
¡¡¡¡¡¡¡¡ _this.$store.state.isCheck = true;
_this.$store.dispatch('toggleNote',note);
¡¡¡¡¡¡¡¡¡¡¡¡},500);
},
//ÊÖ·Å¿ª½áÊø£¬Ä£Äⳤ°´Ê¼þ
clearLoop(){
clearTimeout(this.Loop);
}
}
}
</script>

ToolBar

Toolbar×é¼þÌṩ¸øÓû§Èý¸ö°´Å¥£º´´½¨±ãÇ©£¬±à¼­±ãÇ©ºÍÒÆ¶¯±ãÇ©£¨Òƶ¯±ãÇ©¹¦ÄÜ»¹Ã»ÓÐ×ö£©£º

<template>
<div class="toolBar">
<div class="toolBtn" v-if="isCheck">
<span class="icon" @click="deleteNote"><icon name="trash-alt"></icon></span>
<span class="icon"><icon name="dolly"></icon></span>
</div>
<div class="addNote" v-else>
<div class="float-button mu-float-button" @click="addNote"><icon name="plus"></icon></div>
</div>
<mu-dialog :open="dialog" title="ɾ³ý±ãÇ©" @close="close">
ÄúÈ·¶¨É¾³ýËùÑ¡±ãÇ©Âð£¿
<mu-flat-button slot="actions" @click="close" primary label="È¡Ïû"/>
<mu-flat-button slot="actions" primary @click="deleteConfirm" label="È·¶¨"/>
</mu-dialog>
</div>
</template>

<script>
import { mapGetters,mapActions } from 'vuex'
export default {
name: 'ToolBar',
data(){
return {
dialog: false
}
},
computed:{
...mapGetters([
'isCheck'
])
},
methods:{
//Ìí¼Ó±ãÇ©
addNote(){
this.$store.dispatch('newNote');
this.$router.push({path:'editor'});
},
//ɾ³ý±ãÇ©
deleteNote(){
this.dialog = true;
},
//¹Ø±Õ´°¿Ú
close () {
this.dialog = false;
},
//È·¶¨É¾³ý
deleteConfirm(){
this.dialog = false;
this.$store.dispatch('deleteNote');
}
}
}
</script>

Editor

Editor ×é¼þÊÇ×î¼òµ¥µÄ£¬ËüÖ»×öÁ½¼þÊ£º

´Ó store »ñÈ¡µ±Ç°±Ê¼ÇactiveNote£¬°ÑËüµÄÄÚÈÝչʾÔÚ textarea

ÔÚÓû§¸üбʼǵÄʱºò£¬µ÷Óà editNote() action

ÒÔÏÂÊÇÍêÕûµÄ Editor.vue:

<template>
<div class="edit-panel">
<div class="edit-tool">
<span class="back-list" @click="backList"><icon name="angle-left"></icon></span>
<span class="date" v-text="activeNote.date"></span>
<span class="saveNote" v-show="isShow" @click="backList">Íê³É</span>
</div>
<textarea v-focus class="edit-area" v-model="activeNote.content" @keyup="editorNote"></textarea>
</div>
</template>

<script>
import { mapGetters } from 'vuex'
export default {
name: 'Editor',
data(){
return {
content:'',
isShow:false
}
},
created(){
this.content = this.activeNote.content
},
computed:{
//»ñÈ¡ÕýÔÚ²Ù×÷µÄ±ãÇ©
...mapGetters([
'activeNote'
])
},
directives:{
focus:{
inserted(el){
el.focus();
}
}
},
methods:{
//·µ»Ø±ãÇ©Áбí
backList(){
this.$router.push({path:'/'})
this.$store.dispatch('backSave',this.activeNote)
},
//Íê³É°´Å¥ÏÔʾ&Òþ²Ø
editorNote(){
if(this.content != this.activeNote.content){
this.isShow = true;
}else{
this.isShow = false;
}
}
}
}
</script>

Õâ¾ÍÊÇÒ»¸öСÃ×±ãÇ©µÄ´´½¨ºÍ±à¼­£¬»¹ÓÐɾ³ýÒÔ¼°·Ïֽ¨¹¦ÄÜÕâÀï¾Í²»¶à˵ÁË£¬¹¦Äܶ¼ºÜ¼òµ¥²»Ã÷°×µÄµØ·½¿ÉÒÔ¿´Ô´´úÂ룬Ȼºó×Ô¼ºÊµÕ½²Ù×÷Ò»·¬£¬ÈçÓÐдµÄ²»¶ÔµÄµØ·½´ó¼ÒÌá³öÀ´£¬»¥Ïàѧϰ»¥Ïà°ïÖúÂлл£¡

Ïà¹ØÎÄÕÂ

Éî¶È½âÎö£ºÇåÀíÀôúÂë
ÈçºÎ±àд³öÓµ±§±ä»¯µÄ´úÂë
ÖØ¹¹-ʹ´úÂë¸ü¼ò½àÓÅÃÀ
ÍŶÓÏîÄ¿¿ª·¢"±àÂë¹æ·¶"ϵÁÐÎÄÕÂ
Ïà¹ØÎĵµ

ÖØ¹¹-¸ÄÉÆ¼ÈÓдúÂëµÄÉè¼Æ
Èí¼þÖØ¹¹v2
´úÂëÕû½àÖ®µÀ
¸ßÖÊÁ¿±à³Ì¹æ·¶
Ïà¹Ø¿Î³Ì

»ùÓÚHTML5¿Í»§¶Ë¡¢Web¶ËµÄÓ¦Óÿª·¢
HTML 5+CSS ¿ª·¢
ǶÈëʽC¸ßÖÊÁ¿±à³Ì
C++¸ß¼¶±à³Ì

   
2968 ´Îä¯ÀÀ       32