برنامه نویسی

جدید در Vue.js 3.3: اتصال دو طرفه با ماکرو defineModel

با نسخه 3.3 آینده VueJS، جامعه بار دیگر ناامید نمی‌شود و بسیاری از ویژگی‌های مفید را برای توسعه‌دهندگان منتشر می‌کند تا بهره‌وری بیشتری داشته باشند و ویژگی‌ها را سریع‌تر ارسال کنند.

یکی از ویژگی هایی که به تازگی مورد استقبال قرار گرفته است defineModel است که به ما امکان می دهد اتصال دو طرفه بسیار روان تری را پیاده سازی کنیم. بیایید استفاده از آن را در پست وبلاگ زیر نشان دهیم.

2-Way Binding چیست؟

اتصال دو طرفه یک ویژگی در VueJS است که به تغییرات داده اجازه می دهد تا نمای را به طور خودکار به روز کند و بالعکس. این بدان معناست که وقتی کاربر نمای را به روز می کند، داده های زیربنایی نیز به روز می شوند و زمانی که داده ها به صورت برنامه ای به روز می شوند، نما به طور خودکار به روز می شود تا داده های جدید را منعکس کند. با استفاده از v-model دستورالعمل، که یک عنصر ورودی فرم را به یک قطعه داده متصل می کند.

<template>
    <input v-model="message" />
</template>

<script setup>
    import { ref } from 'vue'

    const message = ref('Hello from Bitovi!') 
</script>
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

اتصال دو طرفه مفید است زیرا نیاز به مدیریت رویداد دستی برای همگام نگه داشتن نما و داده ها را از بین می برد، که می تواند خسته کننده و مستعد خطا باشد. استفاده از v-model معادل است

<template>
    <input 
      :value="message" 
      @input="message = $event.target.value" 
    />
</template>

<script setup>
    import { ref } from 'vue'

    const message = ref('Hello from Bitovi!') 
</script>
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

صحافی دو طرفه سفارشی

یک مثال ممکن است داشتن یک مؤلفه جستجوی سفارشی باشد که به کاربر اجازه می دهد مقداری را در جستجو تایپ کند، که چندین گزینه را تا زمانی که یکی را انتخاب کند نمایش می دهد. این رفتار در کد زیر نشان داده شده است:

// MySearch.vue

<template>
  <div>
    <!-- search text input -->
    <input v-model="searchRef" type="text" placeholder="Search"/>

    <!-- display selected value -->
    <div v-if="props.modelValue">
      Selected: {{ props.modelValue.title }}
    </div>

    <!-- results -->
    <div v-if="searchRef.length > 3">
      <button
        v-for="data in store.getLoadedElements"
        :key="data.id"
        @click="onClick(data)"
      >
        {{ data.title }}
      </button>
    </div>
  </div>
</template>

<script setup lang="ts">
// imports

const store = useStore();

const props = defineProps({
  modelValue: {
    type: Object as PropType<Element | null>,
    required: true,
    default: null
  }
});

const emit = defineEmits<{
  (e: "update:modelValue", value: Element): void;
}>();

// reference to search input
const searchRef = ref<string>("");

// fetch data from API
watchEffect(() => {
   store.fetchElements(searchRef.value);
});

const onClick = (data: Element) => {
  emit("update:modelValue", data);
};
</script>
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

در مثال بالا، برای اینکه صحافی سفارشی دو طرفه کار کند، از استفاده می کنید defineProps برای ایجاد یک modelValue ویژگی ورودی برای کامپوننت و شما از آن استفاده می کنید defineEmits با update:modelValue برای اطلاع والدین در مورد تغییر.

استفاده از مؤلفه فرزند فوق با نحو زیر در مؤلفه دیگر به دست می آید.

<MySearch v-model="someRef" />
<!-- same as -->
<MySearch
    :modelValue="someRef"
    @update:modelValue="someRef = $event"
/>
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

توجه داشته باشید: یک نکته مفید این است که می توانید چندین ویژگی را برای آن تعریف کنید MySearch جزء به defineProps و defineEmits. نام modelValue نام مقدار پیش‌فرض است، با این حال با ایجاد چندین ویژگی، می‌توانید به آنها در مؤلفه والد دسترسی داشته باشید <MySearch v-model:first="first" v-model:second="second"/>.

با استفاده از defineModel

با نسخه آینده VueJS، 3.3 یک نسخه جدید است ماکرو defineModel، دیگر نیازی به نوشتن تمام مراحل ذکر شده در بالا برای اجرای اتصال دو طرفه سفارشی ندارید.

این ویژگی جدید از نسخه 3.3.0-alpha.9 در دسترس است، با این حال، هنوز یک ویژگی آزمایشی در نظر گرفته می شود. اگر مایل به استفاده از آن هستید یا در ارتقاء به نسخه 3.3m مشکل دارید، همچنان می توانید از جایگزین آن، defineModels، از کتابخانه Vue Macros استفاده کنید، که این ویژگی از آن الهام گرفته شده است. به طور کلی آنها به همان روش کار می کنند.

پس از تکمیل دستورالعمل های نصب، می توانید از defineModels با سینتکس زیر استفاده کنید:

// MySearch.vue

<template>
  <div>
    <!-- search text input -->
    <input v-model="searchRef" type="text" placeholder="Search"/>

    <!-- display selected value -->
    <div v-if="modelValue">Selected: {{ modelValue.title }}</div>

    <!-- results -->
    <div v-if="searchRef.length > 3">
      <button
        v-for="data in store.getLoadedElements"
        :key="data.title"
        @click="modelValue = data"
      >
        {{ data.title }}
      </button>
    </div>
  </div>
</template>

<script setup lang="ts">
// imports

const store = useStore();
const { modelValue } = defineModels<{ modelValue: Element }>();

// reference to search input
const searchRef = ref<string>("");

// fetch data from API
watchEffect(() => {
  store.fetchElements(searchRef.value);
});
</script>
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

ماکرو defineModels جایگزین موارد استفاده شده قبلی می شود defineProps و defineEmits به یک عملکرد

هر بار، کاربر مقداری را به این مؤلفه ارسال می کند <MySearch :modelValue="someRef" /> را MySearch کامپوننت به روز می شود و همچنین در خط 16 وقتی کاربر عنصری را انتخاب می کند، توسط modelValue = data، شنونده در مؤلفه والد فعال می شود.

خلاصه

دیدن این که تیم VueJS کمک‌های ارزشمند توسعه‌دهندگان به اکوسیستم VueJS را می‌شناسد و به مرور زمان پیاده‌سازی آن‌ها را ارسال می‌کند، بسیار خوب است. با نسخه 3.3 آینده، VueJS ابزارهای مفید دیگری را برای ما به ارمغان می آورد که توسعه ما را سرعت می بخشد.

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا