z0ffy / z0ffy.github.io

Welcome to my space – where code runs like a dream (and sometimes crashes like a nightmare). Grab your coffee, dive into the docs, and let’s debug life, one semicolon at a time.
https://zoffy.me
MIT License
0 stars 0 forks source link

【Vue】Vue3 重置组件状态 #21

Closed z0ffy closed 2 weeks ago

z0ffy commented 2 weeks ago

在某些场景下,例如表单提交,经常会需要重置表单状态。可以通过以下的方式进行组件状态优雅重置。

xxx写法


<template>
  <div>
    <div>{{ state.name }} - {{ state.age }}</div>
    <div @click="resetState">reset ref</div>
  </div>
</template>

<script setup>
  import { reactive } from 'vue';

  const state = reactive({
    name: 1,
    age: 2,
  });

  function resetState() {
    state.name = 1;
    state.age = 2;
  }
</script>

Hook 封装

import { ref, reactive } from 'vue';

function clone(value) {
  return JSON.parse(JSON.stringify(value));
}

export function useResettableRef(value) {
  const initialValue = clone(value);
  const state = ref(value);

  const reset = () => {
    state.value = clone(initialValue);
  }

  return [state, reset];
}

export function useResettableReactive(value) {
  const state = reactive(clone(value));

  const reset = () => {
    Object.keys(state).forEach((key) => delete state[key]);
    Object.assign(state, clone(value));
  }

  return [state, reset];
}

Hook 使用


<template>
  <div>
    <div>ref:{{ refState.name }} - {{ refState.age }}</div>
    <div @click="resetRefState">reset ref</div>

    <div>reactive:{{ reactiveState.name }} - {{ reactiveState.age }}</div>
    <div @click="resetReactiveState">reset ref</div>
  </div>
</template>

<script setup>
  import { useResettableRef, useResettableReactive } from '@/hooks/index.js';

  const [refState, resetRefState] = useResettableRef({
    name: 1,
    age: 2
  });

  const [reactiveState, resetReactiveState] = useResettableReactive({
    name: 1,
    age: 2
  });
</script>