我有一個 ProjectPage.vue 頁面,它在 v-data-table 中顯示問題。項目從側邊欄中的伺服器 API 呼叫中檢索並顯示在那裡。選擇一個項目後,我想使用該項目的 id 從伺服器獲取其問題。是否可以使用 Vuex 來做到這一點。
使用 Vuex 是否可以讓每個專案都可以使用相同的 .js 檔案來檢索其問題,因為可能有任意數量的專案。
我想做的是從 VerticalNavMenu.vue 將 id 和專案作為 props 傳遞給 ProjectPage,這樣我就可以將 id 作為參數傳遞給 ProjectPage 內的 mapAction 以檢索其問題。
我現在做的方法不起作用。當我打開項目的表格時,該表格沒有可用資料
我希望 Peoject_Pages.js 有助於理解我的問題。
VerticalNavMenu.vue(相關範本行為38 -> 48)
<template> <v-navigation-drawer :value="isDrawerOpen" app expand-on-hover mini-variant-width="60px" floating width="260" class="app-navigation-menu" :right="$vuetify.rtl" @input="val => $emit('update:is-drawer-open', val)" > <!-- Navigation Header --> <div class="vertical-nav-header d-flex items-center ps-6 pe-5 pt-5 pb-2"> <router-link to="/" class="d-flex align-center text-decoration-none"> <v-slide-x-transition> <h2 class="app-title text--primary">ITrackerHub</h2> </v-slide-x-transition> </router-link> </div> <!-- Navigation Items --> <v-list expand shaped class="vertical-nav-menu-items pr-5"> <nav-menu-link title="Dashboard" :to="{ name: 'dashboard' }" :icon="icons.mdiHomeOutline" ></nav-menu-link> <v-list> <v-list-group :prepend-icon="icons.mdiTelevisionGuide"> <template v-slot:activator> <v-list-item-content> <v-list-item-title v-text="'My Projects'"></v-list-item-title> </v-list-item-content> </template> <v-list-item v-for="(project, index) in ProjectList" :key="index"> <v-icon class="mx-2">{{ icons.mdiAccountGroup }}</v-icon> <v-list-item-content> <router-link class="d-flex align-center text-decoration-none black--text" :to="{ name: 'ProjectPage', params: { id: project.id, project} }" > {{ project.title }} </router-link> </v-list-item-content> </v-list-item> </v-list-group> </v-list> <nav-menu-link title="My Issues" :to="{ name: 'MyIssues' }" :icon="icons.mdiBookEditOutline"></nav-menu-link> <nav-menu-link style="position:relative; top:70px;" title="Account Settings" :to="{ name: 'pages-account-settings' }" :icon="icons.mdiAccountCogOutline" ></nav-menu-link> <nav-menu-link style="position: relative; top: 200px" title="Create Project" :to="{ name: 'CreateProject' }" :icon="icons.mdiPlusMinus" ></nav-menu-link> </v-list> </v-navigation-drawer> </template> <script> // eslint-disable-next-line object-curly-newline import { mdiHomeOutline, mdiAlphaTBoxOutline, mdiEyeOutline, mdiCreditCardOutline, mdiTable, mdiFileOutline, mdiFormSelect, mdiAccountCogOutline, mdiAccountGroup, mdiAccountMultiple, mdiTelevisionGuide, mdiBookEditOutline, mdiPlusMinus, } from '@mdi/js' // import NavMenuSectionTitle from './components/NavMenuSectionTitle.vue' import NavMenuGroup from './components/NavMenuGroup.vue' import NavMenuLink from './components/NavMenuLink.vue' import { mapGetters, mapActions } from 'vuex' export default { components: { // NavMenuSectionTitle, NavMenuGroup, NavMenuLink, }, computed: { ...mapGetters(['ProjectList']) }, methods: { ...mapActions(['fetchProjects']) }, created() { // this.getProjectList() this.fetchProjects() }, props: { isDrawerOpen: { type: Boolean, default: null, }, }, setup() { return { icons: { mdiHomeOutline, mdiAlphaTBoxOutline, mdiEyeOutline, mdiCreditCardOutline, mdiTable, mdiFileOutline, mdiFormSelect, mdiAccountCogOutline, mdiAccountGroup, mdiAccountMultiple, mdiTelevisionGuide, mdiBookEditOutline, mdiPlusMinus, }, } }, } </script> <style lang="scss" scoped> .app-title { font-size: 1.25rem; font-weight: 700; font-stretch: normal; font-style: normal; line-height: normal; letter-spacing: 0.3px; } // ? Adjust this `translateX` value to keep logo in center when vertical nav menu is collapsed (Value depends on your logo) .app-logo { transition: all 0.18s ease-in-out; .v-navigation-drawer--mini-variant & { transform: translateX(-10px); } } @include theme(app-navigation-menu) using ($material) { background-color: map-deep-get($material, 'background'); } .app-navigation-menu { .v-list-item { &.vertical-nav-menu-link { ::v-deep .v-list-item__icon { .v-icon { transition: none !important; } } } } } </style>
NavBar.js
import axios from 'axios' const state = { Projects: [], } const getters = { ProjectList: (state) => state.Projects } const actions = { async fetchProjects({ commit }) { const response = await axios.get('https://fadiserver.herokuapp.com/api/v1/my-projects/') commit('setProjects', response.data) } } const mutations = { setProjects: (state, Projects) => (state.Projects = Projects) } export default { state, getters, actions, mutations }
ProjectPage.vue
<template> <v-card> <v-card-title class="text-center justify-center py-6"> <h1 class="font-weight-bold text-h2 basil--text"> {{ project.title }} </h1> </v-card-title> <v-tabs v-model="tab" background-color="primary" dark centered> <v-tab v-for="item in items" :key="item.tab">{{ item.tab }}</v-tab> </v-tabs> <v-tabs-items v-model="tab"> <v-tab-item v-for="item in items" :key="item.tab"> <v-card flat> <v-card v-if="item.tab == 'Issues'"> <template> <div class="text-center"> <v-dialog v-model="dialog" width="500"> <template v-slot:activator="{ on }"> <v-btn class="success" dark v-on="on"> <v-icon align-self: left> mdi-plus-thick </v-icon> Add Issue </v-btn> </template> <v-card> <v-card-title> <h2>Add Issue</h2> </v-card-title> <v-card-text> <v-form class="px-3"> <v-text-field v-model="title" label="Title"></v-text-field> <v-textarea v-model="description" label="Description"></v-textarea> <v-select item-text="text" item-value="value" :items="time_est" v-model="time_estimate" label="Time Estimate" ></v-select> <v-select item-text="title" item-value="id" :items="issueType" v-model="issue_type" label="Issue Type" ></v-select> <v-select item-text="title" item-value="id" v-model="issue_status" label="Issue Status" :items="issueStatus" ></v-select> <v-select item-text="title" item-value="id" :items="issueSeverity" v-model="issue_severity" label="Issue Severity" ></v-select> <v-spacer></v-spacer> <v-btn flat @click=" postIssue() reloadPage() " class="success mx-0 mt-3" > <v-icon align-self:left>mdi-content-save-check-outline</v-icon> Save</v-btn > </v-form> </v-card-text> </v-card> </v-dialog> </div> </template> <v-card> <v-data-table :headers="headers" :items="Project_Issues" item-key="full_name" class="table-rounded" hide-default-footer enable-sort @click:row="handleClick" > </v-data-table> </v-card> </v-card> </v-card> </v-tab-item> </v-tabs-items> </v-card> </template> <script> import axios from 'axios' import { mapGetters, mapActions } from 'vuex' export default { props: ['id', 'project'], computed: { ...mapGetters(['Project_Issues']), }, data() { return { tab: null, items: [{ tab: 'Issues' }, { tab: 'Calender' }, { tab: 'About' }], title: '', description: '', time_estimate: '', issue_type: '', issue_status: '', issue_severity: '', time_est: [ { value: '1', text: '1' }, { value: '2', text: '2' }, { value: '3', text: '3' }, { value: '4', text: '4' }, { value: '5', text: '5' }, { value: '6', text: '6' }, { value: '7', text: '7' }, { value: '8', text: '8' }, ], } }, setup() { return { headers: [ { text: 'Title', value: 'title' }, { text: 'Description', value: 'description' }, { text: 'Estimate', value: 'time_estimate' }, { text: 'Assignees', value: 'user' }, { text: 'Type', value: 'issueType' }, { text: 'Status', value: 'issueStatus' }, { text: 'Severity', value: 'issueSeverity' }, ], } }, methods: { ...mapActions(['fetchProjectIssueList']), handleClick(issue) { this.$router.push({ name: 'IssuePage', params: { id: issue.id, issue }, }) }, postIssue() { axios .post('https://fadiserver.herokuapp.com/api/v1/my-issues/', { title: this.title, description: this.description, time_estimate: this.time_estimate, userid: 'f3260d22-8b5b-4c40-be1e-d93ba732c576', projectid: this.id, issueTypeId: this.issue_type, issueStatusId: this.issue_status, issueSeverityId: this.issue_severity, }) .then(response => { console.log(response) }) .catch(error => { console.log(error) }) }, reloadPage() { window.location.reload() }, }, mounted() { this.fetchProjectIssueList(this.id) }, } </script> <style scoped> .v-btn { left: 43%; } </style>
Project_Page.js
#import axios from 'axios' const state = { issuesList: [], } const getters = { Project_Issues: (state) => state.issuesList } const actions = { async fetchProjectIssueList({ commit }, {projectid}) { const response = await axios.get('https://fadiserver.herokuapp.com/api/v1/my-issues-titles/?projectid=' + projectid) commit('setProjectIssues', response.data) }, } const mutations = { setProjectIssues: (state, issuesList) => (state.issuesList = issuesList) } export default { state, getters, actions, mutations }
有兩種方法可以解決您的問題。
fetchProjectIssueList
方法中傳遞一個帶有鍵projectid
的物件fetchProjectIssueList
方法中解構該物件或