From 66e82ec992cedad798a1d91fbdf1da11d431dd07 Mon Sep 17 00:00:00 2001 From: sondh0127 <62163604+sondh0127@users.noreply.github.com> Date: Tue, 3 May 2022 23:51:08 +0700 Subject: [PATCH] feat(useVModel): add option to define defaultValue (#1537) Co-authored-by: Anthony Fu --- packages/core/useVModel/index.test.ts | 18 ++++++++++++++++++ packages/core/useVModel/index.ts | 15 +++++++++++---- packages/core/useVModels/index.ts | 2 +- 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/packages/core/useVModel/index.test.ts b/packages/core/useVModel/index.test.ts index caee598604b..07d545ee77a 100644 --- a/packages/core/useVModel/index.test.ts +++ b/packages/core/useVModel/index.test.ts @@ -93,4 +93,22 @@ describe('useVModel', () => { expect(emitMock).toBeCalledTimes(1) expect(emitMock).toHaveBeenCalledWith('update:data', { hobbies: ['coding', 'basketball'] }) }) + + it('should work with user define defaultValue', () => { + const props = { + ...defaultProps(), + } + const emitMock = vitest.fn() + const data = useVModel(props, 'data', emitMock, { defaultValue: 'default-data' }) + expect(data.value).toBe('default-data') + }) + + it('should work with user define defaultValue with passive', () => { + const props = { + ...defaultProps(), + } + const emitMock = vitest.fn() + const data = useVModel(props, 'data', emitMock, { passive: true, defaultValue: 'default-data' }) + expect(data.value).toBe('default-data') + }) }) diff --git a/packages/core/useVModel/index.ts b/packages/core/useVModel/index.ts index cad138d1e4c..ef5a255908a 100644 --- a/packages/core/useVModel/index.ts +++ b/packages/core/useVModel/index.ts @@ -1,7 +1,7 @@ import type { UnwrapRef } from 'vue-demi' import { computed, getCurrentInstance, isVue2, ref, watch } from 'vue-demi' -export interface VModelOptions { +export interface VModelOptions { /** * When passive is set to `true`, it will use `watch` to sync with props and ref. * Instead of relying on the `v-model` or `.sync` to work. @@ -21,6 +21,12 @@ export interface VModelOptions { * @default false */ deep?: boolean + /** + * Defining default value for return ref when no value is passed. + * + * @default undefined + */ + defaultValue?: T } /** @@ -35,12 +41,13 @@ export function useVModel

void, - options: VModelOptions = {}, + options: VModelOptions = {}, ) { const { passive = false, eventName, deep = false, + defaultValue, } = options const vm = getCurrentInstance() @@ -63,7 +70,7 @@ export function useVModel

(props[key!]) + const proxy = ref(props[key!] || defaultValue!) watch(() => props[key!], v => proxy.value = v as UnwrapRef) @@ -79,7 +86,7 @@ export function useVModel

({ get() { - return props[key!] + return props[key!] || defaultValue! }, set(value) { _emit(event, value) diff --git a/packages/core/useVModels/index.ts b/packages/core/useVModels/index.ts index cba8690d0a0..3e38deb45f5 100644 --- a/packages/core/useVModels/index.ts +++ b/packages/core/useVModels/index.ts @@ -12,7 +12,7 @@ import { useVModel } from '../useVModel' export function useVModels

( props: P, emit?: (name: Name, ...args: any[]) => void, - options: VModelOptions = {}, + options: VModelOptions = {}, ): ToRefs

{ const ret: any = {} // eslint-disable-next-line no-restricted-syntax