请教一个Vue pinia 的问题?

请教一个 pinia 的问题。

const { tableData } = useStore()
const { tableJson } = storeToRefs(tableData) 
这里tableJson.value 是 Proxy 对象。 现在我想 重写 这个 tableJson.value 中的 set get 方法。怎么做 ,
是在 store 里修改,还是怎么弄。可以给个小例子吗,多谢

tableJson.value 数据格式如下:

tableJson.value  ={ 
   style:{},
   option:{},
   body:[  // 表格的行与列
   [{td信息},{td},{td}],
   [{td},{td},{td}],
   [{td},{td},{td}],
   [{td},{td},{td}],
  ]
}

目的:主要是要记录 tableJson.value 的修改
实现 恢复 和重置功能

// pinia 的 .$subscribe方法。是监听整个,返回的也是整个,这里用不了
tableData.$subscribe((a,b)=>{
  console.log('subscribe -- a',a)
   console.log('subscribe -- b',b)
})

参考:

备忘录模式了解下,将需要记录的状态记录到一个专门的备忘录对象里进行处理

此处不建议直接监听响应式数据进行状态备份,因为引起数据变化的原因可能很多。

  1. 比如一种是tableJson自身的变更引起的,另一种是撤销和前进引起的变更。直接监听数据变更进行备份会发生环形依赖,需要在编程时进行特殊处理。
  2. 另一种,若tableJson是绑定在input上,那就会出现大量的中间态input的记录,无用数据过多。

建议将tableJson状态的记录改在外部,比如请求数据后,或者点击按钮后再某个action中对tableJson赋值时,手动进行状态记录。
下面的states是对备忘录的简单实现。可以看下


<script setup lang="ts">
import { reactive } from "vue";

const data = reactive<any>({
  text: "",
});

const states = {
  s: <any>[],
  idx: 0, // 下一状态位置,idx-1为当前状态位置
  pop() {
    if (this.idx > 0) {
      this.idx--;
    }
    console.log("pop:", this.s[this.idx - 1]);
    return this.s[this.idx - 1];
  },
  next() {
    if (this.idx < this.s.length) {
      this.idx++;
    }
    return this.s[this.idx - 1];
  },
  add(st: any) {
    this.s = [...this.s.slice(0, this.idx), st];
    this.idx++;
  },
  set(idx: number) {
    return this.s[this.idx];
  },
  clear() {
    this.idx = 0;
    this.s = [];
  },
};

const handleChange = (e) => {
  console.log("data:", e.target.value);
  states.add(e.target.value); // 状态更改后记录状态,放在行为触发时手动记录。 不建议放在响应式状态的计算属性里,自动添加,撤销或者前进可能再次导致text发生更改进而触发记录
};

const back = () => {
  data.text = states.pop();
};

const forward = () => {
  data.text = states.next();
};
const reset = () => {
  states.clear();
  data.text = "";
};
</script>

<template>
  <div>
    <p>input Text:<input v-model="data.text" @change="handleChange" /></p>
    <button @click="back">回退</button>
    <button @click="forward">前进</button>
    <button @click="reset">重置</button>
    <p>{{ data.append }}</p>
  </div>
</template>

<style scoped>
a {
  color: #42b983;
}

label {
  margin: 0 0.5em;
  font-weight: bold;
}

code {
  background-color: #eee;
  padding: 2px 4px;
  border-radius: 4px;
  color: #304455;
}
</style>