VueJS рдХреЗ рд▓рд┐рдП Vuex Undo / Redo Plugin рдмрдирд╛рдирд╛

рдЫрд╡рд┐


Vuex рд╕реНрдЯреЛрд░ рдореЗрдВ рдЖрдкрдХреЗ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреА рд╕реНрдерд┐рддрд┐ рдХреЛ рдХреЗрдВрджреНрд░реАрдХреГрдд рдХрд░рдиреЗ рдХреЗ рдХрдИ рдлрд╛рдпрджреЗ рд╣реИрдВред рдПрдХ рдлрд╛рдпрджрд╛ рдпрд╣ рд╣реИ рдХрд┐ рд╕рднреА рд▓реЗрдирджреЗрди рд░рд┐рдХреЙрд░реНрдб рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВред рдпрд╣ рдЖрдкрдХреЛ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдХрд╛рд░реНрдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рдЬреИрд╕реЗ рд░рдирдЯрд╛рдЗрдо рдбреАрдмрдЧрд┐рдВрдЧ , рдЬрд╣рд╛рдВ рдЖрдк рдирд┐рд╖реНрдкрд╛рджрди рд╕реЗ рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдЕрд▓рдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд┐рдЫрд▓реЗ рд░рд╛рдЬреНрдпреЛрдВ рдХреЗ рдмреАрдЪ рд╕реНрд╡рд┐рдЪ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред


рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ, рдореИрдВ рджрд┐рдЦрд╛рдКрдВрдЧрд╛ рдХрд┐ рдХреИрд╕реЗ Vuex рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд░реЛрд▓рдУрдХ / рд░рд┐рдЯрд░реНрди рдХреЛ рдкреВрд░реНрд╡рд╡рдд рдХрд░реЗрдВ / рдлрд┐рд░ рд╕реЗ рдХрд░реЗрдВ, рдЬреЛ рдбрд┐рдмрдЧрд┐рдВрдЧ рдХреЗ рджреМрд░рд╛рди рдбреАрдмрдЧрд┐рдВрдЧ рдХреЗ рд╕рдорд╛рди рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред рдЗрд╕ рд╕реБрд╡рд┐рдзрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рд╡рд┐рднрд┐рдиреНрди рдкреНрд░рдХрд╛рд░ рдХреЗ рдкрд░рд┐рджреГрд╢реНрдпреЛрдВ рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЬрдЯрд┐рд▓ рд░реВрдкреЛрдВ рд╕реЗ рд▓реЗрдХрд░ рдмреНрд░рд╛рдЙрдЬрд╝рд░-рдЖрдзрд╛рд░рд┐рдд рдЧреЗрдо рддрдХред


рдЖрдк рд╕рдорд╛рдкреНрдд рдХреЛрдб рдХреЛ рдЬреАрдердм рдкрд░ рдпрд╣рд╛рдВ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕ рдХреЛрдбрдкреЗрди рдореЗрдВ рдбреЗрдореЛ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ ред рдпрджрд┐ рдЖрдк рдХрд┐рд╕реА рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдореЗрдВ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рдореИрдВрдиреЗ рдПрдХ NPM рдореЙрдбреНрдпреВрд▓ рдХреЗ рд░реВрдк рдореЗрдВ рдПрдХ рдкреНрд▓рдЧрдЗрди рдмрдирд╛рдпрд╛, рдЬрд┐рд╕реЗ vuex-undo-redo рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред


рдиреЛрдЯ: рдпрд╣ рд▓реЗрдЦ рдореВрд▓ рд░реВрдк рд╕реЗ рдпрд╣рд╛рдВ Vue.js 2017/11/13 рдбреЗрд╡рд▓рдкрд░ рдмреНрд▓реЙрдЧ рдкрд░ рдкреЛрд╕реНрдЯ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред

рдкреНрд▓рдЧрдЗрди рд╡рд┐рдиреНрдпрд╛рд╕


рдЗрд╕ рд╕реБрд╡рд┐рдзрд╛ рдХреЛ рдкреБрди: рдкреНрд░рдпреЛрдЬреНрдп рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдЗрд╕реЗ Vue plugin рдХреЗ рд░реВрдк рдореЗрдВ рдмрдирд╛рдПрдВрдЧреЗред рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рд╕реЗ рд╣рдореЗрдВ Vue рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рдХреБрдЫ рддрд░реАрдХреЗ рдФрд░ рдбреЗрдЯрд╛ рдЬреЛрдбрд╝рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╣рдо рдкреНрд▓рдЧрдЗрди рдХреЛ рдПрдХ рдорд┐рдХреНрд╕рд┐рди рдХреЗ рд░реВрдк рдореЗрдВ рдмрдирд╛рддреЗ рд╣реИрдВред


module.exports = { install(Vue) { Vue.mixin({ // Code goes here }); } }; 

рдПрдХ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдмрд╕ рдкреНрд▓рдЧрдЗрди рдЖрдпрд╛рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕реЗ рдХрдиреЗрдХреНрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:


 import VuexUndoRedo from './plugin.js'; Vue.use(VuexUndoRedo); 

рд╡рд┐рдЪрд╛рд░


рдпрджрд┐ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд░рджреНрдж рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реИ, рдФрд░ рдлрд┐рд░ рдЙрд╕реЗ рджреЛрд╣рд░рд╛рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реИ рддреЛ рдпрд╣ рд╕реБрд╡рд┐рдзрд╛ рдЕрдВрддрд┐рдо рдореНрдпреВрдЯреЗрд╢рди рдХреЛ рд░реЛрд▓ рдХрд░рдХреЗ рдХрд╛рдо рдХрд░реЗрдЧреАред рд╣рдо рдпрд╣ рдХреИрд╕реЗ рдХрд░рддреЗ рд╣реИрдВ?


рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╕рдВрдЦреНрдпрд╛ рез


рдкрд╣рд▓рд╛ рд╕рдВрднрд╛рд╡рд┐рдд рджреГрд╖реНрдЯрд┐рдХреЛрдг рдкреНрд░рддреНрдпреЗрдХ рдореНрдпреВрдЯреЗрд╢рди рдХреЗ рдмрд╛рдж рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдХреА рд╕реНрдерд┐рддрд┐ рдХрд╛ "рд╕реНрдиреИрдкрд╢реЙрдЯ" рд▓реЗрдирд╛ рдФрд░ рд╕реНрдиреИрдкрд╢реЙрдЯ рдХреЛ рдПрдХ рд╕рд░рдгреА рдореЗрдВ рд░рдЦрдирд╛ рд╣реИред рдкреВрд░реНрд╡рд╡рдд / рдлрд┐рд░ рд╕реЗ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рд╕рд╣реА рд╕реНрдиреИрдкрд╢реЙрдЯ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕реЗ рд╕реНрдЯреЛрд░реЗрдЬ рд╕реНрдерд┐рддрд┐ рд╕реЗ рдмрджрд▓ рд╕рдХрддреЗ рд╣реИрдВред


рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЗ рд╕рд╛рде рд╕рдорд╕реНрдпрд╛ рдпрд╣ рд╣реИ рдХрд┐ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдХреА рд╕реНрдерд┐рддрд┐ рдПрдХ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдСрдмреНрдЬреЗрдХреНрдЯ рд╣реИред рдЬрдм рдЖрдк рдХрд┐рд╕реА рд╕рд░рдгреА рдореЗрдВ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдСрдмреНрдЬреЗрдХреНрдЯ рдбрд╛рд▓рддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рдмрд╕ рдСрдмреНрдЬреЗрдХреНрдЯ рдХрд╛ рд╕рдВрджрд░реНрдн рджреЗрддреЗ рд╣реИрдВред рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреА рддрд░рд╣ рдПрдХ рднреЛрд▓реА рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди, рдХрд╛рдо рдирд╣реАрдВ рдХрд░реЗрдЧрд╛:


 var state = { ... }; var snapshot = []; // Push the first state snapshot.push(state); // Push the second state state.val = "new val"; snapshot.push(state); // Both snapshots are simply a reference to state console.log(snapshot[0] === snapshot[1]); // true 

рд╕реНрдиреИрдкрд╢реЙрдЯ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА рдХрд┐ рдЖрдк рдкрд╣рд▓реЗ рдкреБрд╢ рд╕реЗ рдкрд╣рд▓реЗ рдПрдХ рд░рд╛рдЬреНрдп рдХреНрд▓реЛрди рдмрдирд╛рддреЗ рд╣реИрдВред рдпрд╣ рджреЗрдЦрддреЗ рд╣реБрдП рдХрд┐ Vue рдХреА рд╕реНрдерд┐рддрд┐ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдкреНрд░рд╛рдкреНрдд рдФрд░ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдЬреЛрдбрд╝рдХрд░ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛рд╢реАрд▓ рд╣реЛ рдЬрд╛рддреА рд╣реИ, рдпрд╣ рдХреНрд▓реЛрдирд┐рдВрдЧ рдХреЗ рд╕рд╛рде рдмрд╣реБрдд рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред


рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╕рдВрдЦреНрдпрд╛ реи


рдПрдХ рдЕрдиреНрдп рд╕рдВрднрд╛рд╡рд┐рдд рджреГрд╖реНрдЯрд┐рдХреЛрдг рдкреНрд░рддреНрдпреЗрдХ рдирд┐рд╢реНрдЪрд┐рдд рдореНрдпреВрдЯреЗрд╢рди рдХреЛ рдкрдВрдЬреАрдХреГрдд рдХрд░рдирд╛ рд╣реИред рд░рджреНрдж рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рд╕реНрдЯреЛрд░ рдХреЛ рдЗрд╕рдХреА рдкреНрд░рд╛рд░рдВрднрд┐рдХ рд╕реНрдерд┐рддрд┐ рдореЗрдВ рд░реАрд╕реЗрдЯ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдлрд┐рд░ рд╕реЗ рдореНрдпреВрдЯреЗрд╢рди рдЪрд▓рд╛рддреЗ рд╣реИрдВ; рд╕рднреА рд▓реЗрдХрд┐рди рдЕрдВрддрд┐рдоред рд░рд┐рдлрдВрдб рдЗрд╕реА рддрд░рд╣ рдХреА рдЕрд╡рдзрд╛рд░рдгрд╛ред


рдлреНрд▓рдХреНрд╕ рдХреЗ рд╕рд┐рджреНрдзрд╛рдВрддреЛрдВ рдХреЛ рджреЗрдЦрддреЗ рд╣реБрдП, рдПрдХ рд╣реА рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдЕрд╡рд╕реНрдерд╛ рд╕реЗ рдЙрддреНрдкрд░рд┐рд╡рд░реНрддрди рдХреЛ рдлрд┐рд░ рд╕реЗ рд╢реБрд░реВ рдХрд░рдХреЗ рдЖрджрд░реНрд╢ рд░реВрдк рд╕реЗ рд░рд╛рдЬреНрдп рдХреЛ рдлрд┐рд░ рд╕реЗ рдмрдирд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рдЪреВрдВрдХрд┐ рдпрд╣ рдкрд╣рд▓реЗ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдПрдХ рдХреНрд▓реАрдирд░ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╣реИ, рдЪрд▓реЛ рдЬрд╛рд░реА рд░рдЦреЗрдВред


рдореНрдпреВрдЯреЗрд╢рди рдХрд╛ рдкрдВрдЬреАрдХрд░рдг


Vuex рдореНрдпреВрдЯреЗрд╢рди рдХреА рд╕рджрд╕реНрдпрддрд╛ рдХреЗ рд▓рд┐рдП рдПрдХ рдПрдкреАрдЖрдИ рд╡рд┐рдзрд┐ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ, рдЬрд┐рд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рд╣рдо рдЙрдиреНрд╣реЗрдВ рдкрдВрдЬреАрдХреГрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рд╣рдо рдЗрд╕реЗ created рд╣реБрдХ рдкрд░ рд╕реЗрдЯ рдХрд░реЗрдВрдЧреЗред рдХреЙрд▓рдмреИрдХ рдореЗрдВ, рд╣рдо рдХреЗрд╡рд▓ рдПрдХ рд╕рд░рдгреА рдореЗрдВ рдореНрдпреВрдЯреЗрд╢рди рдбрд╛рд▓рддреЗ рд╣реИрдВ рдЬрд┐рд╕реЗ рдмрд╛рдж рдореЗрдВ рдлрд┐рд░ рд╕реЗ рдЪрд▓рд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред


 Vue.mixin({ data() { return { done: [] } }, created() { this.$store.subscribe(mutation => { this.done.push(mutation); } } }); 

рд░реЛрд▓рдмреИрдХ рд╡рд┐рдзрд┐


рдореНрдпреВрдЯреЗрд╢рди рдХреЛ рд░рджреНрдж рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдХреЛ рд╕рд╛рдл рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдлрд┐рд░ рдкрд┐рдЫрд▓реЗ рдПрдХ рдХреЛ рдЫреЛрдбрд╝рдХрд░ рд╕рднреА рдореНрдпреВрдЯреЗрд╢рди рдХреЛ рдлрд┐рд░ рд╕реЗ рдЪрд▓рд╛рддреЗ рд╣реИрдВред рдпрд╣рд╛рдВ рдмрддрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ рдХрд┐ рдХреЛрдб рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ:


  1. рдЕрдВрддрд┐рдо рдореНрдпреВрдЯреЗрд╢рди рдХреЛ рдирд┐рдХрд╛рд▓рдиреЗ рдХреЗ рд▓рд┐рдП pop рдРрд░реЗ рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВред
  2. рд╡рд┐рд╢реЗрд╖ рдореНрдпреВрдЯреЗрд╢рди EMPTY_STATE рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕реНрдкрд╖реНрдЯ рд╕реНрдЯреЛрд░ рд╕реНрдерд┐рддрд┐ (рдиреАрдЪреЗ рд╕рдордЭрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ)
  3. рдкреНрд░рддреНрдпреЗрдХ рд╢реЗрд╖ рдЙрддреНрдкрд░рд┐рд╡рд░реНрддрди рдХреЛ рджреЛрд╣рд░рд╛рдПрдВ, рдЗрд╕реЗ рдирдП рд╕реНрдЯреЛрд░ рдореЗрдВ рдлрд┐рд░ рд╕реЗ рдлрд┐рдХреНрд╕ рдХрд░рдирд╛ред рдХреГрдкрдпрд╛ рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдЗрд╕ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рджреМрд░рд╛рди рд╕рджрд╕реНрдпрддрд╛ рд╡рд┐рдзрд┐ рдЕрднреА рднреА рд╕рдХреНрд░рд┐рдп рд╣реИ, рдЕрд░реНрдерд╛рдд, рдкреНрд░рддреНрдпреЗрдХ рдореНрдпреВрдЯреЗрд╢рди рдХреЛ рдлрд┐рд░ рд╕реЗ рдЬреЛрдбрд╝рд╛ рдЬрд╛рдПрдЧрд╛ред pop рд╕рд╛рде рдЗрд╕реЗ рддреБрд░рдВрдд рд╣рдЯрд╛ рджреЗрдВред

 const EMPTY_STATE = 'emptyState'; Vue.mixin({ data() { ... }, created() { ... }, methods() { undo() { this.done.pop(); this.$store.commit(EMPTY_STATE); this.done.forEach(mutation => { this.$store.commit(`${mutation.type}`, mutation.payload); this.done.pop(); }); } } }); 

рд╕рдлрд╛рдИ рдХреА рджреБрдХрд╛рди


рдЬрдм рднреА рдЗрд╕ рдкреНрд▓рдЧрдЗрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдбреЗрд╡рд▓рдкрд░ рдХреЛ рдЕрдкрдиреА рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдореЗрдВ рдПрдХ рдореНрдпреВрдЯреЗрд╢рди рд▓рд╛рдЧреВ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ рдЬрд┐рд╕реЗ рдЦрд╛рд▓реА рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред рджреБрдХрд╛рди рдХреЛ рдЕрдкрдиреА рдореВрд▓ рд╕реНрдерд┐рддрд┐ рдореЗрдВ рд╡рд╛рдкрд╕ рдХрд░рдиреЗ рдХреА рдЪреБрдиреМрддреА рд╣реИ рддрд╛рдХрд┐ рд╡рд╣ рдЦрд░реЛрдВрдЪ рд╕реЗ рдЙрдмрд░рдиреЗ рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рд╣реЛред


рдбреЗрд╡рд▓рдкрд░ рдХреЛ рдпрд╣ рдЕрдкрдиреЗ рджрдо рдкрд░ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП, рдХреНрдпреЛрдВрдХрд┐ рдЬреЛ рдкреНрд▓рдЧрдЗрди рд╣рдо рдмрдирд╛рддреЗ рд╣реИрдВ, рдЙрд╕рдХреА рджреБрдХрд╛рди рддрдХ рдкрд╣реБрдВрдЪ рдирд╣реАрдВ рд╣реИ, рдХреЗрд╡рд▓ Vue рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдПред рдпрд╣рд╛рдБ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╣реИ:


 new Vuex.Store({ state: { myVal: null }, mutations: { emptyState() { this.replaceState({ myval: null }); } } }); 

рд╣рдорд╛рд░реЗ рдкреНрд▓рдЧрдЗрди рдкрд░ рд╡рд╛рдкрд╕ рд▓реМрдЯрддреЗ рд╣реБрдП, emptyState рдореНрдпреВрдЯреЗрд╢рди рдХреЛ рд╣рдорд╛рд░реЗ done рд╕реВрдЪреА рдореЗрдВ рдирд╣реАрдВ рдЬреЛрдбрд╝рд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП, рдХреНрдпреЛрдВрдХрд┐ рд╣рдо рд░реЛрд▓рдмреИрдХ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рджреМрд░рд╛рди рдЗрд╕реЗ рдлрд┐рд░ рд╕реЗ рдирд╣реАрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред рдЗрд╕реЗ рдирд┐рдореНрди рддрд░реНрдХ рд╕реЗ рд░реЛрдХреЗрдВ:


 Vue.mixin({ data() { ... }, created() { this.$store.subscribe(mutation => { if (mutation.type !== EMPTY_STATE) { this.done.push(mutation); } }); }, methods() { ... } }); 

рд╡рд╛рдкрд╕реА рд╡рд┐рдзрд┐


рдЖрдЗрдП рдПрдХ рдирдИ рдбреЗрдЯрд╛ рдкреНрд░реЙрдкрд░реНрдЯреА рдмрдирд╛рдПрдВ, рдЬреЛ undone рд╣реЛрдЧреАред рдЬрдм рд╣рдо рд░реЛрд▓рдмреИрдХ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рджреМрд░рд╛рди done рдЧрдП рдЕрдВрддрд┐рдо рдореНрдпреВрдЯреЗрд╢рди рдХреЛ рд╣рдЯрд╛рддреЗ рд╣реИрдВ, рддреЛ рд╣рдо рдЗрд╕реЗ рдЗрд╕ рдПрд░реЗ рдореЗрдВ рд░рдЦрддреЗ рд╣реИрдВ:


 Vue.mixin({ data() { return { done: [], undone: [] } }, methods: { undo() { this.undone.push(this.done.pop()); ... } } }); 

рдЕрдм рд╣рдо рдПрдХ рдРрд╕рд╛ redo рдореЗрдердб рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рдХреЗрд╡рд▓ рдЕрдВрддрд┐рдо рдЬреЛрдбрд╝реЗ рдЧрдП undone рдореНрдпреВрдЯреЗрд╢рди рдХреЛ рд▓реЗрдЧрд╛ рдФрд░ рдЗрд╕реЗ рдлрд┐рд░ рд╕реЗ рдХрд░реЗрдЧрд╛ред


 methods: { undo() { ... }, redo() { let commit = this.undone.pop(); this.$store.commit(`${commit.type}`, commit.payload); } } 

рдХреЛрдИ рд╡рд╛рдкрд╕реА рд╕рдВрднрд╡ рдирд╣реАрдВ


рдпрджрд┐ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдПрдХ рдпрд╛ рдПрдХ рд╕реЗ рдЕрдзрд┐рдХ рдмрд╛рд░ рд░рджреНрджреАрдХрд░рдг рдЖрд░рдВрдн рдХрд░рддрд╛ рд╣реИ рдФрд░ рдлрд┐рд░ рдПрдХ рдирдИ рдирдИ рдкреНрд░рддрд┐рдмрджреНрдзрддрд╛ рдмрдирд╛рддрд╛ рд╣реИ, рддреЛ undone рдХреА рд╕рд╛рдордЧреНрд░реА рдХреЛ рдЕрдорд╛рдиреНрдп рдХрд░ undone рдЬрд╛рдПрдЧрд╛ред рдпрджрд┐ рдРрд╕рд╛ рд╣реЛрддрд╛ рд╣реИ, рддреЛ рд╣рдореЗрдВ undone рдЦрд╛рд▓реА рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред


рдЬрдм рд╣рдо рдПрдХ рдкреНрд░рддрд┐рдмрджреНрдзрддрд╛ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ рддреЛ рд╣рдо рдЕрдкрдиреА рд╕рджрд╕реНрдпрддрд╛ рдХреЙрд▓рдмреИрдХ рд╕реЗ рдирдП рдХрдорд┐рдЯ рдЦреЛрдЬ рд╕рдХрддреЗ рд╣реИрдВред рд╣рд╛рд▓рд╛рдБрдХрд┐, рддрд░реНрдХ рдореБрд╢реНрдХрд┐рд▓ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдХреЙрд▓рдмреИрдХ рдореЗрдВ рдпрд╣ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдХрд╛ рдХреЛрдИ рд╕реНрдкрд╖реНрдЯ рддрд░реАрдХрд╛ рдирд╣реАрдВ рд╣реИ рдХрд┐ рдПрдХ рдирдИ рдкреНрд░рддрд┐рдмрджреНрдзрддрд╛ рдХреНрдпрд╛ рд╣реИ рдФрд░ рдкреВрд░реНрд╡рд╡рдд / рдлрд┐рд░ рд╕реЗ рдХреНрдпрд╛ рд╣реИред


рд╕рдмрд╕реЗ рдЖрд╕рд╛рди рддрд░реАрдХрд╛ рдиреНрдпреВрдореИрдЯреЗрд╢рди рдлреНрд▓реИрдЧ рдХреЛ рд╕реЗрдЯ рдХрд░рдирд╛ рд╣реИред рдпрд╣ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рд╕рд╣реА рд╣реЛрдЧрд╛, рд▓реЗрдХрд┐рди рд░реЛрд▓рдмреИрдХ рдФрд░ рд░рд┐рдЯрд░реНрди рдХреЗ рддрд░реАрдХреЗ рдЕрд╕реНрдерд╛рдпреА рд░реВрдк рд╕реЗ рдЗрд╕реЗ рдЧрд▓рдд рдкрд░ рд╕реЗрдЯ рдХрд░реЗрдВрдЧреЗред рдпрджрд┐ рдореНрдпреВрдЯреЗрд╢рди рд╕рд╣реА рдкрд░ рд╕реЗрдЯ рд╣реИ, рддреЛ subscribe рдХреЙрд▓рдмреИрдХ undone рд╕рд░рдгреА рдХреЛ рд╕рд╛рдлрд╝ рдХрд░ рджреЗрдЧрд╛ред


 module.exports = { install(Vue) { Vue.mixin({ data() { return { done: [], undone: [], newMutation: true }; }, created() { this.$store.subscribe(mutation => { if (mutation.type !== EMPTY_STATE) { this.done.push(mutation); } if (this.newMutation) { this.undone = []; } }); }, methods: { redo() { let commit = this.undone.pop(); this.newMutation = false; this.$store.commit(`${commit.type}`, commit.payload); this.newMutation = true; }, undo() { this.undone.push(this.done.pop()); this.newMutation = false; this.$store.commit(EMPTY_STATE); this.done.forEach(mutation => { this.$store.commit(`${mutation.type}`, mutation.payload); this.done.pop(); }); this.newMutation = true; } } }); }, } 

рдореБрдЦреНрдп рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдЕрдм рдкреВрд░реА рд╣реЛ рдЧрдИ рд╣реИ! рдЗрд╕реЗ рдкрд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдкрдиреЗ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдпрд╛ рдореЗрд░реЗ рдбреЗрдореЛ рдореЗрдВ рдкреНрд▓рдЧрдЗрди рдЬреЛрдбрд╝реЗрдВред


рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рдПрдкреАрдЖрдИ


рдореЗрд░реЗ рдбреЗрдореЛ рдореЗрдВ, рдЖрдк рджреЗрдЦреЗрдВрдЧреЗ рдХрд┐ рдпрджрд┐ рдЙрдирдХреА рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рд╡рд░реНрддрдорд╛рди рдореЗрдВ рд╕рдВрднрд╡ рдирд╣реАрдВ рд╣реИ рддреЛ рд░рджреНрдж рдФрд░ рд╡рд╛рдкрд╕реА рдмрдЯрди рдЕрдХреНрд╖рдо рд╣реИрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрджрд┐ рдЕрднреА рддрдХ рдХреЛрдИ рдХрдорд┐рдЯ рдирд╣реАрдВ рд╣реБрдЖ рд╣реИ, рддреЛ рдЖрдк рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рд░рджреНрдж рдпрд╛ рдлрд┐рд░ рд╕реЗ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЗрд╕ рдкреНрд▓рдЧрдЗрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╡рд╛рд▓рд╛ рдПрдХ рдбреЗрд╡рд▓рдкрд░ рд╕рдорд╛рди рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдЪрд╛рд╣ рд╕рдХрддрд╛ рд╣реИред


рдЗрд╕реЗ рд╕рдХреНрд╖рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдкреНрд▓рдЧрдЗрди рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рдПрдкреАрдЖрдИ рдХреЗ рднрд╛рдЧ рдХреЗ рд░реВрдк рдореЗрдВ рджреЛ рдХрдореНрдкреНрдпреВрдЯреЗрдб рдЧреБрдг, canUndo рдФрд░ canRedo рдкреНрд░рджрд╛рди рдХрд░ рд╕рдХрддрд╛ рд╣реИред рдпрд╣ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рддреБрдЪреНрдЫ рд╣реИ:


 module.exports = { install(Vue) { Vue.mixin({ data() { ... }, created() { ... }, methods: { ... }, computed: {}, computed: { canRedo() { return this.undone.length; }, canUndo() { return this.done.length; } }, }); }, } 

Source: https://habr.com/ru/post/hi433986/


All Articles