npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

vuex-undo

v1.2.7

Published

a vuex plugin to record action of undo and redo

Readme

vuex-undo

A vuex efficient's plugin to record action of undo and redo". it will record vuex state change properties, don't replace whole state. when you dispatch an action of undo or redo, vuex-undo will change only the vuex state change properties.

why vuex-undo is performance effciency

for example
Demo Address: https://lixueshiaa.github.io/webtest/www/index.html#/h5-editor

const state = { // default vuex state
  elementList: []
}
const mutations = {
  // type : add(新增元素) editor(编辑元素) delete(删除元素)
  ['SET_ELEMENT_LIST_ITEM_CAPTURE'] (state, { type, element }) {
    if (type == 'add') {
      if (isPlainObject(element)) {
        state.elementList.push(element)
      } else if (isArray(element)) {
        state.elementList = state.elementList.concat(element)
      }
    } else if (type == 'editor') {
      const index = state.elementList.findIndex(item => item.elementId == element.elementId)
      if (index > -1) {
        state.elementList.splice(index, 1, element)
      } else {
        state.elementList.push(element)
      }
    } else if (type == 'delete') {
      const index = state.elementList.findIndex(item => item.elementId == element.elementId)
      if (index > -1) {
        state.elementList.splice(index, 1)
      }
    }
  }
}

const defaultElement = {
  text: '默认元素',
  elementId: 0,
  style: {
    color: 'black',
    margin: 0,
    position: 'absolute',
    top: '60px',
    left: '10px',
    transform: 'none',
    fontSize: '24px',
    lineHeight: '1.5',
    width: '150px',
    height: '36px',
    cursor: 'default'
  }
}
const change_one = {
  text: '默认元素',
  elementId: 0,
  style: {
    color: 'black',
    margin: 0,
    position: 'absolute',
    top: '104px', // changes property
    left: '516px',  // changes property
    transform: 'none',
    fontSize: '24px',
    lineHeight: '1.5',
    width: '150px',
    height: '36px',
    cursor: 'default'
  }
}
const change_second = {
  text: '默认元素',
  elementId: 0,
  style: {
    color: 'black',
    margin: 0,
    position: 'absolute',
    top: '104px',
    left: '516px',
    transform: 'rotateZ(76deg)', // changes property
    transition: '',
    fontSize: '24px',
    lineHeight: '1.5',
    width: '150px',
    height: '36px',
    cursor: 'default'
  }
}
this.$store.commit('SET_ELEMENT_LIST_ITEM_CAPTURE', {type: 'add', element: defaultElement})
this.$store.commit('SET_ELEMENT_LIST_ITEM_CAPTURE', {type: 'editor', element: change_one})
this.$store.commit('SET_ELEMENT_LIST_ITEM_CAPTURE', {type: 'add', element: defaultElement})
//  when you commit a mutation, vuex-undo will record the vuex state change properties like it(undo action list)
[{
	"actionPath": [{
		"kind": "A",
		"path": ["elementList"],
		"index": 0,
		"item": {
			"kind": "N",
			"rhs": {
				"text": "默认元素",
				"elementId": 1,
				"style": {
					"color": "black",
					"margin": 0,
					"position": "absolute",
					"top": "104px",
					"left": "516px",
					"transform": "rotateZ(76deg)",
					"fontSize": "24px",
					"lineHeight": "1.5",
					"width": "150px",
					"height": "36px",
					"cursor": "default",
				}
			}
		}
	}]
}, {
	"actionPath": [{
		"kind": "E",  
		"path": ["elementList", 0, "style", "top"], // changes property path
		"lhs": "60px",  // previous value
		"rhs": "104px"  // current value
	}, {
		"kind": "E",
		"path": ["elementList", 0, "style", "left"], // changes property path
		"lhs": "10px", // previous value
		"rhs": "516px" // current value
	}]
}, {
	"actionPath": [{
		"kind": "E",
		"path": ["elementList", 0, "style", "transform"],
		"lhs": "none",
		"rhs": "rotateZ(76deg)"
	}]
}]
 

Install

npm i --save vuex-undo

Usage

How to use it in your store module

import Vue from 'vue'
import Vuex from 'vuex'
import undoable, { install } from 'vuex-undo'

Vue.use(Vuex)

const SETELEMENT = 'SETELEMENT' // define mormal mutation
// if you want to capture a mutation, you can add capture mark like it:
const SETELEMENT_CAPTURE =  'SETELEMENT_CAPTURE'  // define a capture mutation

const state = {
  // Define vuex state as normal
  element: {
    a: 1,
    b: [2, 3]
  }
}
const mutations = {
  // Define vuex mutation as normal 
  SETELEMENT (state, element) {
    state.element = element
  },
  // will be capture vuex mutation
  SETELEMENT_CAPTURE (state, element) {
    state.element = element
  }
}
const actions = {
  // Define vuex actions as normal
}
const getters = {
  // Define vuex getters as normal
  element: state => state.element
}

const moduleA = {
  state: {
    // Define vuex state as normal
    ...
  },
  mutations: {
    // Define vuex mutation as normal 
    ...
  }
}
const moduleB = {
  state: {
    // Define vuex state as normal
    ...
  },
  mutations: {
    // Define vuex mutation as normal 
    ...
  }
}

const modules = {
  // Define vuex modules as normal
  moduleA,
  moduleB,
  ...
}

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

const options = { 
  captureActionMask: '_CAPTURE', // Define capture mutation mark, default: '_CAPTURE'
  store // vuex store example
}
Vue.use({ install }, options)


export default store

registry Vuex inside your app entrypoint

main.js

import store from './store'
import router from './router'

new Vue({
  el: '#app',
  store,
  router,
  render: h => {
    return h(App)
  }
})

How to use in your Vue components

<template>
<div>
  <div class="opreate-block">
    <button @click="undo" :disabled="!isVuexCaptureHaveUndo" type="button">undo</button>
    <button @click="redo" :disabled="!isVuexCaptureHaveRedo" type="button">redo</button>
    <button @click="normalMutations" type="button">normal mutation</button>
    <button @click="captureMutations" type="button">capture mutation</button>
     <button @click="captureContinuityMutations" type="button">capture continuity mutation</button>
  </div>
  <div>
    <p>{{element.a}}</p>
    <p :key="index" v-for="(it, index) in element.b">{{it}}<p>
  </div>
</div>
</template>

import { mapGetters } from 'vuex'

export default {
  data () {
    return {
      num: 0
    }
  },
  computed: {
    // isVuexCaptureHaveUndo : whether it have capture undo
    // isVuexCaptureHaveRedo : whether it have capture redo
    ...mapGetters(['isVuexCaptureHaveUndo', 'isVuexCaptureHaveRedo', 'element'])
  },
  mounted () {
  },
  methods: {
    undo () {
      // if you want to undo mutations, you can dispatch an action "vuex_action_undo" to undo like it:
      this.$store.dispatch('vuex_action_undo')
    },
    redo () {
      // if you want to redo mutations, you can dispatch an action "vuex_action_redo" to undo like it:
      this.$store.dispatch('vuex_action_redo')
    },
    normalMutations () {
      // if you use mutation key haven't capture mutation mark, it will be not capture
      this.$store.commit('SETELEMENT', {
        a: this.num++,
        b: [34]
      })
    },
    captureMutations () {
      // if you use mutation key have capture mutation mark, it will be capture
      this.$store.commit('SETELEMENT_CAPTURE', {
        a: this.num++,
        b: [34, 434]
      })

      // if you already use mutation key have capture mutation mark, but you don't capture the mutation yet. you can use like it:
      this.$store.commit('SETELEMENT_CAPTURE', {
        a: this.num++,
        b: [34, 434],
        vuexCaptureMark: 'noCapture'
      })
    },
    captureContinuityMutations () {
      // if you are ues continuity mutations, the mutation's payload will be a object, it have one retain key "vuexCaptureMark"  use to capture continuity mutation commit 
      this.$store.commit('SETELEMENT_CAPTURE', {
        vuexCaptureMark: 'start', // set continuity mutation start capture mark
        a: this.num++,
        b: [34, 434]
      })
      let n = 10
      const timer = setInterval(() => {
        n--
        // when you already capture continuity mutations start, vuex-undo will don't capture state property change to you commit every mutation
        this.$store.commit('SETELEMENT_CAPTURE', {
          a: this.num++
        })
        if (n < 0) {
          clearInterval(timer)
          this.$store.commit('SETELEMENT_CAPTURE', {
            vuexCaptureMark: 'end', // set continuity mutations end capture mark
            a: 44,
            b: [34, 434 + this.num++]
          })
        }
      }, 1000)
    }
  }
}

API

Options

captureActionMask: a String of capture mutation mark
store: a vuex store example

Computed properties

isVuexCaptureHaveUndo: undoes the last mutation
isVuexCaptureHaveRedo: redoes the last mutation

vuex actions

'vuex_action_undo' this.$store.dispatch('vuex_action_undo') // dispatch an undo action

'vuex_action_redo' this.$store.dispatch('vuex_action_redo') // despatch an redo action

Remarks

if you want more functions, you can add my QQ(920804994)