גישה ל$store לקבלת ערך עבור ייבוא קומפוננט
-
בvuex,
במקרה של הפרוייקט הספציפי, הקונטיינור של תצוגת האתר משתנה בין אתר א' לאתר ב' (עד ת' והלאה).הייבוא של הקונטיינור נעשה באמצעות import ככה
import Full from '@/container/Full'
ואני רוצה שהכתובת ממנה הimport מייבא תשתנה לפי ערך שיוגדר במקו"א.
וכיון שאותו מקו"א הוא ה$store, א"כ אם מישהו יכול לכוין אותי איך לגשת אליו ( - שלא מתוך אובייקט vue - שאין אפשרות ב-this).
תודה רבה.
-
@chagold לכאורה זה לא יכול לעבוד עם import סטטי, כי import סטטי חייב שהנתיב יהיה מוגדר בזמן בנייה.
לכאורה אתה חייב להשתמש ב-import דינאמי (זה בצורה של פונקציה שמחזירה promise ככה:const Full = await import('@/container/Full')
)ולעצם השאלה, אפשר ככה:
import store from '@/store' const user = store.getters.currentUser
-
-
@yossiz הבעיה הבאה.
לכאו' הייתי אמור לקבל את הפרמטרים מתוך האקשין ואמור להפעיל את הimport ככה:
store.dispatch('get_data_project') .then( data_project => { import...... })
אבל ככה יש שגיאת
import' and 'export' may only appear at the top level (5:2)
שכמופיע כאן זה בגלל שהimport חייב להיות בסקופ העליון.
והואיל והסקופ העליון הוא לא פונקצייתasync
(ובדקתי וגם הכנסתו לasync
לא תפתור את הבעיה), אז גם אין לי אפשרות לעכב אותו בawait
עד שהפרמטר יבוא. - - -
-
@חוקר אמר בגישה ל$store לקבלת ערך עבור ייבוא קומפוננט:
אבל אולי תשקול לעשות בפונקציית הראוטינג await עד שהמידע מוכן ונטען לתוך משתנה רגיל ב store ואז יהיה לך גישה לזה בכל קומפוננטה ללא המתנה.
@חוקר אם תוכל להדגים לי איך עשית בstore.
תודה רבה. -
@chagold אמר בגישה ל$store לקבלת ערך עבור ייבוא קומפוננט:
@חוקר אמר בגישה ל$store לקבלת ערך עבור ייבוא קומפוננט:
אבל אולי תשקול לעשות בפונקציית הראוטינג await עד שהמידע מוכן ונטען לתוך משתנה רגיל ב store ואז יהיה לך גישה לזה בכל קומפוננטה ללא המתנה.
@חוקר אם תוכל להדגים לי איך עשית בstore.
תודה רבה.אני עדיין לא כ"כ הצלחתי להתרכז מה בדיוק היה שאלתך ואם מה שאני עשיתי יפתור לך את בעיותך
לי היו בעיות שבקומפוננטות השונות הייתי צריך את פרטי המשתמש המאוחסנים ב store והייתי צריך לעשות למגוון פעולות await וכו' ולדעת שיש לי את המידע לפעולות הבאות ועוד
מה שעשיתי הוא כך בקובץ src/router/index.js שיניתיrouter.beforeEach(async (to, _, next) => { const isLoggedIn = isUserLoggedIn() if (isLoggedIn) { await store.dispatch('app/getUserinfo').catch(error => { // eslint-disable-next-line no-console console.error(error) }) } if (!canNavigate(to)) { // Redirect to login if not logged in if (!isLoggedIn) return next({ name: 'auth-login' }) // If logged in => not authorized return next({ name: 'misc-not-authorized' }) } // Redirect if logged in if (to.meta.redirectIfLoggedIn && isLoggedIn) { const userData = getUserData() next(getHomeRouteForLoggedInUser(userData ? userData.role : null)) } return next() })
בקובץ src/store/app/index.js הוספתי ב actions
getUserInfo(state) { if (state.state.userData2) { return state.state.userData2 } state.state.userData2 = new Promise((resolve, reject) => { const url = '/dashboard/api/user/info' useJwt.axiosIns.get(url).then(response => { const { userData } = response.data localStorage.setItem('userData', JSON.stringify(userData)) state.state.userData = response.data.userDataUser // eslint-disable-next-line radix,no-nested-ternary state.state.selectedProject = response.data.userDataUser.length > 1 && localStorage.getItem('selectedProject') ? response.data.userDataUser.find(l => l.id === parseInt(localStorage.getItem('selectedProject'))) : (response.data.userDataUser.length > 1 ? null : response.data.userDataUser[0]) // console.log(state.state.selectedProject) this.dispatch('app/getProjectInfo').then(() => { resolve(state) }).catch(error => { reject(error) }) }).catch(error => { reject(error) }) }) return state.state.userData2 },
הפונקציה getProjectInfo מיועדת מחזירה ג"כ פרומיז עם פרטי הפרוייקט הפתוח
מה שגורם, שלפני הניתוב (וה"ה בריענון, לפני טעינת הדף הדף הפתוח, כי גם זה בעצם ניתוב) הדפדפן ישאב מהAPI את המידע המבוקש ויטען אותו לstore וכעת אני חופשי בכל הקומפננטות לגשת למידע המאוחסן
לדוגמאcomputed: { sortOptions() { // Create an options list from our fields return this.fields .filter(f => f.sortable !== false) .map(f => ({ text: f.label, value: f.key })) }, getSelectedProject: () => store.state.app.selectedProject, }, watch: { getSelectedProject(val) { this.selectedProject = val this.updateSelectedDate() }, },
מקווה שהועלתי משהו
-
כעת לאחר עיון אני מבין שהשאלה שלך הייתה שאתה רוצה לטעון את הקומפוננטה של האדמין או הקליינט לפי המידע בסטור? משהו כזה?
א"כ זה לא קשור למה שעשיתי
אני הייתי עושה טעינה של שניהם ורק עושה v-if מה להציג
אבל אולי אתה צודק במהלך שלך כי זה יחסוך ביצועים שלא לטעון קומפוננטות מיותרות
מעניין אם יש יאפשר להפעיל כמה פרוייקטים על תבנית אחת -
מה שאני בדקתי כעת זה כזה דבר
Vue.use(VueRouter) const component = () => import('@/views/dashboard/ecommerce/Ecommerce.vue') const component2 = import('@/views/dashboard/analytics/Analytics.vue') const router = new VueRouter({ mode: 'history', base: process.env.BASE_URL, scrollBehavior() { return { x: 0, y: 0 } }, routes: [ { path: '/', redirect: { name: 'dashboard' } }, { path: '/dashboard', name: 'dashboard', component: document.URL === 'http://localhost:8080/dashboard' || document.URL === 'http://mysite/dashboard' ? component2 : component, meta: { resource: 'ACL', action: 'official', title: 'ממשק הניהול', }, }, { path: '/list', name: 'list', // eslint-disable-next-line import/extensions component, meta: { resource: 'ACL', action: 'official', title: 'רשימה', }, }, { path: '*', redirect: 'error-404', }, ], })
לי היה מעניין אם אני יוכל לשלב 2 אתרים על פרוייקט אחד.
חשבתי מראש שאני יוכל לטעון את הכל מראש, דהיינו בקובץ rout/index.js אני יכול לטעון מראש את כל הניתובים = כל הקומפוננטות, ורק את התפריטים לעשות דינאמיים, והם יהיו תלויים בכתובת הדומיין, אבל הציק לי הרעיון של טעינת כמה אתרים באתר אחד שזה יגרום לכל משתמש תעבורה מיותרת.
ומכיוון שבנסיונות של @chagold היה נראה שלא ניתן לייבא מראש import עם נתיב דינאמי הנלקח ממשתנה, הבנתי שיהיה עלי לטעון תמיד את כל האתרים לכל לקוח שפותח את אחד האתרים, מה שכמובן מיותר ומסורבל.
לכן ניסיתי כעת לבדוק מה קורה עם גם את הייבוא של הקומפוננטות עצמן אנסה לבצע עם תנאים, אבדוק האם הם נטענים כבר בטעינת הראשונית של הדף או לא.
ומה שיצא לי זה כך:
אם זה היה נטען בצורה כזו:const component2 = import('@/views/dashboard/analytics/Analytics.vue')
בחיפוש הטקסט באתר זה מופיע מיד, למרות שעדיין לא עברתי לניתוב שפותח את הקומפוננטה הזו,
לעומת זאת, כאשר הייבוא מתבצע כך:const component = () => import('@/views/dashboard/ecommerce/Ecommerce.vue')
כל זמן שלא הפעלתי ניתוב (בדוגמא שלי, כל זמן שלא עברתי אל http://localhost:8080/dashboard), התוכן עוד לא ירד לאתר בכלל, ורק בעת המעבר לניתוב המבוקש זה נטען באמצעות http://mysite/js/chunk-2d332689b.92d2c0b9.js שמוריד את תוכן לדף.
מה שאומר מבחינתי שמלמעלה נראה שאני יכול להשים כמה דומיינים/אתרים בפרוייקט אחד וזה לא יכביד על משתמש באתר א' התוכן של אתר ב'
אשמח לשמוע מהמומחים אם אני צודק.
נ.ב. ההשראה של כמה אתרים בפרוייקט אחד מגיע מהפריימוורק הקודם שלי (YII2) שם יש תמיכה מובנית בזה, וזה מאוד נוח שהליבה אחידה לכולם, וכל האתרים שלי (דהיינו פרוייקטים שונים ללקוחות עם תתי דומיינים אחרים) נמצאים במקום אחד עם ליבה אחת ומבנה אחיד לכולם, וכל הוספה של פונקציה בליבת המערכת זמינה לי בכל האתרים שלי) -
@חוקר אמר בגישה ל$store לקבלת ערך עבור ייבוא קומפוננט:
כל זמן שלא הפעלתי ניתוב (בדוגמא שלי, כל זמן שלא עברתי אל http://localhost:8080/dashboard), התוכן עוד לא ירד לאתר בכלל, ורק בעת המעבר לניתוב המבוקש זה נטען באמצעות http://mysite/js/chunk-2d332689b.92d2c0b9.js שמוריד את תוכן לדף.
אמת. אתה יכול לוודא את זה לאחר הרצת הפקודה, כשתדפיס בקונסול את האובייקט
component/component2
, שבאופציה הראשונה כל הקומפוננט מודפס משא"כ באופציה השניה מודפסת פונקציה ששמורה באובייקט.
הוספה: וכמובן אפשר להריץ (לקבל את הקומפוננט) ע"י הרצת שם הקומפוננט עם סוגרייםלגופו של ענין, אכלתי ע"ז הרבה קש, אבל המסקנא לכאו' כדבריך.
-
-
-
-
-