اذهب إلى المحتوى

السؤال

نشر (معدل)

يمكننا إنشاء ملف جاسكربت (أضع فيه custom directives)   و تصديره،  ثم استيراده في ملف main.js بسهولة في vue 2.

لكني لم أنجح في ذلك في vue 3 ، حيث أني استطعت أن أصدر الدالات (functions) في ملف directives.js إلى main.js وعملت الأكواد فيها، لكن custom directives لم تعمل ، وكأنها غير موجودة .

في ملف directives.js المنشأ :

// directives.js

import { createApp } from 'vue'
import App from './App.vue'

const app = createApp(App)



// global Custom Directive 

export default function glob() {
    app.directive('globalexternal', {
        mounted: function (el) {
            el.placeholder = 'Global Custom Directive from external file'
        }
    })
    console.log('Global Custom Directive from external file')
}

و في ملف main.js الأساسي :

// main.js

import glob from './directives'

glob();

وفي ملف App.vue  مثلاُ :

// App.vue

<input v-globalexternal style="width: 370px" />

النتيجة أن الأمر console.log('Global Custom Directive from external file') قد تم بنجاح ، لكن <input v-globalexternal style="width: 370px" /> لم يعمل v-globalexternal .

هل من لديه تجربة في ذلك ؟

تم التعديل في بواسطة Hadi255

Recommended Posts

  • 1
نشر
بتاريخ الآن قال Hadi255:

لا يوجد أخطاء من هذه النواحي فالكود نفسه يعمل عندما أكتبه في ملف main.js

حسن، فيما يلي الطريقة الصحيحة لذلك: 

عدل ملف directives.js ليصبح: 

const globalexternal = {
    mounted: function (el) {
        el.placeholder = 'Global Custom Directive from external file'
    }
}

export default globalexternal;

في ملف main.js قم باستيراد الموجه وسجله باستعمال التابع directive: 

import globalexternal from './directives'

const app = createApp(App)

app.directive('globalexternal' ,globalexternal)
app.mount('#app')

استعمل الموجه في أي ملف فرعي: 

<input v-globalexternal style="width: 370px" />

 

  • 0
نشر

لا أظن أن هنالك تغيير من حيث استعمال الموجهات directives ما بين vue 3 و vue 2 .

يحتمل أن يكون ذلك بسبب استعمال الخطاف mounted، جرب استعمال beforeMount أو created: 

app.directive('globalexternal', {
     created: function (el) {

أيضا قد تكون المشكلة بسبب طريقتك في الوصول الى الخاصية placeholder، فالعنصر المستقبل كمعامل أول el هو عنصر DOM الذي يتم ربطه بالموجه bound element. جرب استعمال السياق التالي: 

mounted: function (el) {
    el.setAttribute('placeholder' ,'Global Custom Directive from external file')
}
  • 0
نشر

في Vue 3، هناك بعض التغييرات في استخدام custom directives مقارنةً بـ Vue 2، وتستطيع تحقيق ما تريده عن طريق التالي:

في ملف directives.js، يجب تصدير الـ custom directive مباشرة بدون استخدام دالة glob()، وذلك لأنك ستقوم بتصدير الـ directive ذاتها، وليس دالة لتسجيل الـ directive:

// directives.js

import { createApp } from 'vue'
import App from './App.vue'

const app = createApp(App)

// global Custom Directive 
app.directive('globalexternal', {
  mounted: function (el) {
    el.placeholder = 'Global Custom Directive from external file'
  }
})

console.log('Global Custom Directive from external file')

export default app

وفي ملف main.js، قم بتصدير ما يتم استيراده من ملف directives.js ثم تشغيل التطبيق:

// main.js

import { createApp } from 'vue'
import App from './App.vue'
import directivesApp from './directives'

const app = createApp(App)

directivesApp.mount('#app')
app.mount('#app')

وفي ملف App.vue، قم بتطبيق الـ custom directive المستورد باستخدام v-globalexternal:

<!-- App.vue -->

<template>
  <input v-globalexternal style="width: 370px" />
</template>

<script>
export default {
  // ...
}
</script>

ومن المفترض أن يعمل الـ custom directive بشكل صحيح في تطبيق Vue 3 لديك، وانتبه إلى أنه في Vue 3 لم يعد هناك حاجة لاستدعاء الـ custom directive في الملف main.js مثلما كان في Vue 2، بل تستطيع تسجيلها مباشرة في الملف directives.js.

  • 0
نشر (معدل)
بتاريخ 29 دقائق مضت قال Mustafa Suleiman:

في Vue 3، هناك بعض التغييرات في استخدام custom directives مقارنةً بـ Vue 2، وتستطيع تحقيق ما تريده عن طريق التالي:

في ملف directives.js، يجب تصدير الـ custom directive مباشرة بدون استخدام دالة glob()، وذلك لأنك ستقوم بتصدير الـ directive ذاتها، وليس دالة لتسجيل الـ directive:

// directives.js

import { createApp } from 'vue'
import App from './App.vue'

const app = createApp(App)

// global Custom Directive 
app.directive('globalexternal', {
  mounted: function (el) {
    el.placeholder = 'Global Custom Directive from external file'
  }
})

console.log('Global Custom Directive from external file')

export default app

وفي ملف main.js، قم بتصدير ما يتم استيراده من ملف directives.js ثم تشغيل التطبيق:

// main.js

import { createApp } from 'vue'
import App from './App.vue'
import directivesApp from './directives'

const app = createApp(App)

directivesApp.mount('#app')
app.mount('#app')

وفي ملف App.vue، قم بتطبيق الـ custom directive المستورد باستخدام v-globalexternal:

<!-- App.vue -->

<template>
  <input v-globalexternal style="width: 370px" />
</template>

<script>
export default {
  // ...
}
</script>

ومن المفترض أن يعمل الـ custom directive بشكل صحيح في تطبيق Vue 3 لديك، وانتبه إلى أنه في Vue 3 لم يعد هناك حاجة لاستدعاء الـ custom directive في الملف main.js مثلما كان في Vue 2، بل تستطيع تسجيلها مباشرة في الملف directives.js.

شكرا لك على الإجابة ، لكنه لم يعمل و ظهر لي خطأ لم أستطع فهمه واختفت الصفحة بسبب الخطأ :

runtime-dom.esm-bundler.js:13 Uncaught TypeError: Cannot read properties of null (reading 'parentNode')
    at remove (runtime-dom.esm-bundler.js:13:26)
    at performRemove (runtime-core.esm-bundler.js:6257:7)
    at remove2 (runtime-core.esm-bundler.js:6271:7)
    at unmount (runtime-core.esm-bundler.js:6226:9)
    at Object.remove (runtime-core.esm-bundler.js:6592:11)
    at unmount (runtime-core.esm-bundler.js:6205:20)
    at unmountChildren (runtime-core.esm-bundler.js:6314:7)
    at unmount (runtime-core.esm-bundler.js:6215:9)
    at unmountComponent (runtime-core.esm-bundler.js:6294:7)
    at unmount (runtime-core.esm-bundler.js:6195:7)
remove @ runtime-dom.esm-bundler.js:13
performRemove @ runtime-core.esm-bundler.js:6257
remove2 @ runtime-core.esm-bundler.js:6271
unmount @ runtime-core.esm-bundler.js:6226
remove @ runtime-core.esm-bundler.js:6592
unmount @ runtime-core.esm-bundler.js:6205
unmountChildren @ runtime-core.esm-bundler.js:6314
unmount @ runtime-core.esm-bundler.js:6215
unmountComponent @ runtime-core.esm-bundler.js:6294
unmount @ runtime-core.esm-bundler.js:6195
unmountChildren @ runtime-core.esm-bundler.js:6314
unmount @ runtime-core.esm-bundler.js:6215
unmountChildren @ runtime-core.esm-bundler.js:6314
unmount @ runtime-core.esm-bundler.js:6215
unmountComponent @ runtime-core.esm-bundler.js:6294
unmount @ runtime-core.esm-bundler.js:6195
patch @ runtime-core.esm-bundler.js:4991
render2 @ runtime-core.esm-bundler.js:6332
mount @ runtime-core.esm-bundler.js:3824
app.mount @ runtime-dom.esm-bundler.js:1431
(anonymous) @ main.js?t=1688563145513:50
Show 20 more frames

هل يمكنك تجريب ذلك و ينجح معك


 

تم التعديل في بواسطة Hadi255
  • 0
نشر
بتاريخ الآن قال Hadi255:

شكرا لك على الإجابة ، لكنه لم يعمل و ظهر لي خطأ لم أستطع فهمه واختفت الصفحة بسبب الخطأ :

runtime-dom.esm-bundler.js:13 Uncaught TypeError: Cannot read properties of null (reading 'parentNode')
    at remove (runtime-dom.esm-bundler.js:13:26)
    at performRemove (runtime-core.esm-bundler.js:6257:7)
    at remove2 (runtime-core.esm-bundler.js:6271:7)
    at unmount (runtime-core.esm-bundler.js:6226:9)
    at Object.remove (runtime-core.esm-bundler.js:6592:11)
    at unmount (runtime-core.esm-bundler.js:6205:20)
    at unmountChildren (runtime-core.esm-bundler.js:6314:7)
    at unmount (runtime-core.esm-bundler.js:6215:9)
    at unmountComponent (runtime-core.esm-bundler.js:6294:7)
    at unmount (runtime-core.esm-bundler.js:6195:7)
remove @ runtime-dom.esm-bundler.js:13
performRemove @ runtime-core.esm-bundler.js:6257
remove2 @ runtime-core.esm-bundler.js:6271
unmount @ runtime-core.esm-bundler.js:6226
remove @ runtime-core.esm-bundler.js:6592
unmount @ runtime-core.esm-bundler.js:6205
unmountChildren @ runtime-core.esm-bundler.js:6314
unmount @ runtime-core.esm-bundler.js:6215
unmountComponent @ runtime-core.esm-bundler.js:6294
unmount @ runtime-core.esm-bundler.js:6195
unmountChildren @ runtime-core.esm-bundler.js:6314
unmount @ runtime-core.esm-bundler.js:6215
unmountChildren @ runtime-core.esm-bundler.js:6314
unmount @ runtime-core.esm-bundler.js:6215
unmountComponent @ runtime-core.esm-bundler.js:6294
unmount @ runtime-core.esm-bundler.js:6195
patch @ runtime-core.esm-bundler.js:4991
render2 @ runtime-core.esm-bundler.js:6332
mount @ runtime-core.esm-bundler.js:3824
app.mount @ runtime-dom.esm-bundler.js:1431
(anonymous) @ main.js?t=1688563145513:50
Show 20 more frames

هل يمكنك تجريب ذلك و ينجح معك

هناك مشكلة تحدث عند إزالة العنصر من DOM، جرب تعديل الكود في ملف directives.js واستخدام الخاصية beforeUnmount بدلاً من unmounted في كود الـ custom directive.

أي في ملف directives.js، قم بتعديل الكود ليصبح كالتالي:

// directives.js

import { createApp } from 'vue'
import App from './App.vue'

const app = createApp(App)

// global Custom Directive 
app.directive('globalexternal', {
  beforeUnmount: function (el) {
    el.placeholder = ''
  },
  mounted: function (el) {
    el.placeholder = 'Global Custom Directive from external file'
  }
})

console.log('Global Custom Directive from external file')

export default app

 

  • 0
نشر
بتاريخ الآن قال Mustafa Suleiman:

هناك مشكلة تحدث عند إزالة العنصر من DOM، جرب تعديل الكود في ملف directives.js واستخدام الخاصية beforeUnmount بدلاً من unmounted في كود الـ custom directive.

أي في ملف directives.js، قم بتعديل الكود ليصبح كالتالي:

// directives.js

import { createApp } from 'vue'
import App from './App.vue'

const app = createApp(App)

// global Custom Directive 
app.directive('globalexternal', {
  beforeUnmount: function (el) {
    el.placeholder = ''
  },
  mounted: function (el) {
    el.placeholder = 'Global Custom Directive from external file'
  }
})

console.log('Global Custom Directive from external file')

export default app

 

نفس الخطأ لم يتغير شيء

بتاريخ 37 دقائق مضت قال Adnane Kadri:

لا أظن أن هنالك تغيير من حيث استعمال الموجهات directives ما بين vue 3 و vue 2 .

يحتمل أن يكون ذلك بسبب استعمال الخطاف mounted، جرب استعمال beforeMount أو created: 

app.directive('globalexternal', {
     created: function (el) {

أيضا قد تكون المشكلة بسبب طريقتك في الوصول الى الخاصية placeholder، فالعنصر المستقبل كمعامل أول el هو عنصر DOM الذي يتم ربطه بالموجه bound element. جرب استعمال السياق التالي: 

mounted: function (el) {
    el.setAttribute('placeholder' ,'Global Custom Directive from external file')
}

لا يوجد أخطاء من هذه النواحي فالكود نفسه يعمل عندما أكتبه في ملف main.js

  • 0
نشر
بتاريخ الآن قال Hadi255:

نفس الخطأ لم يتغير شيء

من الأفضل قراءة المستند الرسمي وتطبيق الشرح على مشروعك:

https://vuejs.org/guide/reusability/custom-directives.html

وأيضًا هناك دليل عن كيفية الإنتقال من vue 2 إلى vue 3 :

  • 0
نشر
بتاريخ الآن قال Mustafa Suleiman:

من الأفضل قراءة المستند الرسمي وتطبيق الشرح على مشروعك:

https://vuejs.org/guide/reusability/custom-directives.html

وأيضًا هناك دليل عن كيفية الإنتقال من vue 2 إلى vue 3 :

لقد درست هذا كله  منذ يومين و طبقته بسهولة لكنه لا يحتوي الإجابة على سؤالي 

  • 0
نشر

ممتاز شكراً لك 

أي مثل طريقة تعريفه ك directive  في <script setup> تقريبا (ما عدا أن المتغير ليس بالضرورة Camel case )

مع أنني حاولت هذه الطريق البارحة لا أعلم لماذا لم تنجح يبدو كان هناك خطأ .

نجح الأمر الآن شكر اً لك

  • 0
نشر
بتاريخ الآن قال Hadi255:

ممتاز شكراً لك 

أي مثل طريقة تعريفه ك directive  في <script setup> تقريبا (ما عدا أن المتغير ليس بالضرورة Camel case )

مع أنني حاولت هذه الطريق البارحة لا أعلم لماذا لم تنجح يبدو كان هناك خطأ .

نجح الأمر الآن شكر اً لك

مشكلتك تحديدا كانت في أنك قد أنشات نموذج Vue في حين أنك قد قمت بتهيئة الموجه directive في Vue instance آخر تماما. 

// directives.js
// first vue instance
const app = createApp(App)

و:

import glob from './directives'
glob()

// main.js
// second vue instance
const app = createApp(App)

وبما أن الثاني هو ما يتم عمل mount له مع المكون الجذر app# فلن يتم بطبيعة الحال التعرف على الأول، وبالتالي لن يتم تسجيل الموجه أبدا. 

  • 0
نشر (معدل)
بتاريخ منذ ساعة مضت قال Adnane Kadri:

مشكلتك تحديدا كانت في أنك قد أنشات نموذج Vue في حين أنك قد قمت بتهيئة الموجه directive في Vue instance آخر تماما. 

// directives.js
// first vue instance
const app = createApp(App)

و:

import glob from './directives'
glob()

// main.js
// second vue instance
const app = createApp(App)

وبما أن الثاني هو ما يتم عمل mount له مع المكون الجذر app# فلن يتم بطبيعة الحال التعرف على الأول، وبالتالي لن يتم تسجيل الموجه أبدا. 

تماماً لأن تعريف الموجه كان app.directive 

لكن سؤالي الآن أين يوجد جوابك لم أجده في مكان ؟ هل استنتجته استنتاجاً أم يوجد شبيه له في مكان ما ؟

تم التعديل في بواسطة Hadi255
  • 0
نشر
بتاريخ الآن قال Hadi255:

تماماً لأن تعريف الموجه كان app.directive 

و جربت قبلها طريقة  const vGlobalexternal المستخدمة في <script setup> فلم تنجح لأن الربط لن يطابقها :

v-globalexternal

لكن سؤالي الآن أين يوجد جوابك لم أجده في مكان ؟ هل استنتجته استنتاجاً أم يوجد شبيه له في مكان ما ؟

هل تقصد بحسب التوثيق الرسمي؟ لا يتوفر ذلك. هي مجرد طريقة لاستعمال التابع directive وللتعامل مع واجهة التطبيق البرمجية لكائن Vue فقط، ابحث عن how to register global directive in vue js وستجد أمثلة مشابهة. 

  • 0
نشر

في Vue 3، هناك تغييرات في كيفية تعريف واستخدام Custom Directives بالمقارنة مع Vue 2. في Vue 3، تم تعديل الطريقة التي يتم بها استدعاء الدالة المستخدمة لتعريف الـ Custom Directive.

في ملف directives.js، يمكنك تعديل التصدير بالشكل التالي:

// directives.js

import { app } from './main'

export default function setupDirectives() {
  app.directive('globalexternal', {
    mounted: function (el) {
      el.placeholder = 'Global Custom Directive from external file'
    }
  })
  console.log('Global Custom Directive from external file')
}

ثم في ملف main.js، يمكنك تعديل الاستيراد وإنشاء التطبيق بالشكل التالي:

// main.js

import { createApp } from 'vue'
import App from './App.vue'

export const app = createApp(App)
import setupDirectives from './directives'
setupDirectives()

app.mount('#app')

تأكد من استيراد app و setupDirectives في الملف main.js واستدعاء setupDirectives() قبل استدعاء app.mount('#app'). هذا يضمن تعريف الـ Custom Directive قبل تجميع التطبيق.

بعد هذه التعديلات، يجب أن يعمل <input v-globalexternal style="width: 370px" /> كما هو متوقع. يتم تعريف الـ Custom Directive في الملف directives.js ويتم تطبيقه في الملف App.vue باستخدام الـ v-globalexternal.

 

انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أجب على هذا السؤال...

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.

  • إعلانات

  • تابعنا على



×
×
  • أضف...