1.0.0 • Published 4 months ago

gcomp-clone v1.0.0

Weekly downloads
-
License
MIT
Repository
github
Last release
4 months ago

useClone Composable

The useClone composable provides a way to manage a deep clone of your data (whether it is a plain object, a ref, or a reactive object) and detect changes between the clone and the original value. This is especially useful for form management, where you want to allow the user to apply changes only when there is a difference between the current and initial states.
Note: No matter what type of value you pass as initValue (plain object, ref, or reactive object), the returned clone is always a ref. This means you can access the cloned data as clone.value in your script, while Vue's template unwrapping lets you directly use properties (e.g., clone.name).

Installation

yarn add gcomp-clone

or

npm install gcomp-clone

Vue must be installed as a peer dependency with a minimum version of 3.2.25.

Usage

Below is an example showing how to use useClone with a plain object, a ref, and a reactive object.

    <div class="center mt-10">
        <p>{{ hasChangedPlain ? 'Changed' : 'Same' }}</p>
        <div
            style="width: 100px; height: 100px"
            class="ml-10"
            :class="[hasChangedPlain ? 'changed' : 'same']"
        ></div>
        <button @click="update">Apply</button>
    </div>

    <!-- Ref Example -->
    <div class="center new-sample">
        <p>Name:</p>
        <input class="ml-10" v-model="refClone.name" />
        <p class="ml-20">Age:</p>
        <input class="ml-10" v-model="refClone.age" type="number" />
    </div>

    <div class="center mt-10">
        <p>{{ hasChangedRef ? 'Changed' : 'Same' }}</p>
        <div
            style="width: 100px; height: 100px"
            class="ml-10"
            :class="[hasChangedRef ? 'changed' : 'same']"
        ></div>
        <button @click="updateRef">Apply</button>
    </div>

    <!-- Reactive Object Example -->
    <div class="center new-sample">
        <p>Name:</p>
        <input class="ml-10" v-model="reactiveClone.name" />
        <p class="ml-20">Age:</p>
        <input class="ml-10" v-model="reactiveClone.age" type="number" />
    </div>

    <div class="center mt-10">
        <p>{{ hasChangedReactive ? 'Changed' : 'Same' }}</p>
        <div
            style="width: 100px; height: 100px"
            class="ml-10"
            :class="[hasChangedReactive ? 'changed' : 'same']"
        ></div>
        <button @click="updateReactive">Apply</button>
    </div>
</div>
## Explanation
+ **Uniform Return Type:**  
No matter what type of initial value is provided, the useClone composable always 
returns a clone as a ref. In the script, you access the data via clone.value, 
but in templates Vue automatically unwraps refs, allowing you to bind directly 
(e.g., v-model="clone.name").

+ **Change Detection:**  
  The composable uses deep cloning (via lodash.clonedeep) and deep equality checking 
(via lodash.isequal) to detect changes. The computed property 
(hasChangedPlain, hasChangedRef, or hasChangedReactive) indicates whether the current clone 
differs from the original state.

+ **Applying Changes:**  
When you click the Apply button, the apply function updates the original state to match 
the current clone, effectively resetting the change detection.

+ **Usage Flexibility:**  
You can use `useClone` for plain objects, refs, or reactive objects, while always working 
with a ref for the clone, which simplifies handling in Vue templates.



## Notes
+ The `mockApi` function in this sample is used to simulate receiving a shallow copy of data from an external source.
+ The composable uses deep cloning (via lodash.clonedeep) and deep equality checking (via lodash.isequal) to manage and compare data states.
By using useClone, you can easily detect unsaved changes in your forms and trigger an action to apply those changes.