---
# System prepended metadata

title: 前提

---

#Vue JS 前端問題

# 前提

網站URL
https://starrocket-cms-staging.starrocket.io/

登入帳號：
scott.hsiao@starrocket.io
Ss111111

問題網頁
https://starrocket-cms-staging.starrocket.io/course/list

# 問題
資料表的標題目前是跳轉使用者前端的預覽，想改成跳轉行動的編輯

節錄 index.js
標題欄位
```
 data() {
    return {
      columns: [
        {
          name: 'id',
          label: 'ID',
          align: 'center',
          format: (val) => val,
          sortable: true,
        },
        ...
        {
          name: 'title',
          label: '標題',
          align: 'left',
          format: (val) =>
            `<a href="${process.env.URL}/course/${val.category.id}/${val.id}" target="_blank" rel="noreferrer noopener">${val.title}</a>`,
          html: true,
          fullData: true,
          sortable: true,
        },
```

跳轉編輯的部分
```
    dataView(row) {
      this.$router.push({
        name: 'course/content',
        params: {
          id: row.id,
        },
      });
    },
```

完整內容
index.js
```
import moment from 'moment';
import MyTable from '@/components/MyTable/index.vue';
export default {
  name: 'PageCourseList',
  components: {
    MyTable,
  },
  data() {
    return {
      columns: [
        {
          name: 'id',
          label: 'ID',
          align: 'center',
          format: (val) => val,
          sortable: true,
        },
        {
          name: 'image',
          label: '圖片',
          align: 'center',
          format: (val) => `<img src="${val}" width="80" height="45">`,
          html: true,
          sortable: false,
        },
        {
          name: 'category',
          label: '分類',
          align: 'left',
          format: (val) => (val ? val.name : ''),
          sortable: true,
        },
        {
          name: 'title',
          label: '標題',
          align: 'left',
          format: (val) =>
            `<a href="${process.env.URL}/course/${val.category.id}/${val.id}" target="_blank" rel="noreferrer noopener">${val.title}</a>`,
          html: true,
          fullData: true,
          sortable: true,
        },
        {
          name: 'created_at',
          label: '課程建立時間',
          align: 'left',
          format: (val) => val,
          sortable: true,
        },
        {
          name: 'sale_start_at',
          label: '售票開始時間',
          align: 'left',
          format: (val) => moment(val).format('YYYY-MM-DD HH:mm'),
          sortable: true,
        },
        {
          name: 'sale_end_at',
          label: '售票結束時間',
          align: 'left',
          format: (val) => moment(val).format('YYYY-MM-DD HH:mm'),
          sortable: true,
        },
        {
          name: 'start_at',
          label: '課程開始時間',
          align: 'left',
          format: (val) => moment(val).format('YYYY-MM-DD HH:mm'),
          sortable: true,
        },
        {
          name: 'end_at',
          label: '課程結束時間',
          align: 'left',
          format: (val) => moment(val).format('YYYY-MM-DD HH:mm'),
          sortable: true,
        },
        {
          name: 'frontend_status',
          label: '前台狀態',
          align: 'left',
          format: (val) => ['上架', '下架'][val],
          sortable: true,
        },
        {
          name: 'sale_status',
          label: '售票狀態',
          align: 'left',
          format: (val) =>
            ['即將上線', '報名中', '額滿', '停止售票', '結束'][val],
          sortable: true,
        },
      ],
      data: [],
      filter: {
        sort_by: 'id',
        descending: true,
        page: 1,
        rows_per_page: 50,
        category: null,
        keyword: '',
        sale_status: null,
      },
      actions: [
        {
          color: 'accent',
          label: (row) => {
            return row.is_top ? '下置頂' : '上置頂';
          },
          show: (row) => {
            return this.canEdit;
          },
          click: this.dataIsTopChange,
        },
      ],
      total: 0,
      categoryData: [],
      categoryOption: [
        {
          value: null,
          label: '全部',
        },
      ],
      StatusOption: [
        {
          value: null,
          label: '全部',
        },
        {
          value: 0,
          label: '即將上線',
        },
        {
          value: 1,
          label: '報名中',
        },
        {
          value: 2,
          label: '額滿',
        },
        {
          value: 3,
          label: '停止售票',
        },
        {
          value: 4,
          label: '結束',
        },
      ],
      keywordInputTimer: null,
      // * 0: 即將上線  / 前台: 不會出現
      // * 1: 報名中    / 前台: 立刻報名
      // * 2: 額滿      / 前台: 額滿
      // * 3: 停止售票  / 前台: 停止售票
      // * 4: 結束      / 前台: 結束
      // * 5: 下線(下架) / 前台: 不會出現
    };
  },
  computed: {},
  mounted() {
    if (!this.canView) {
      return;
    }
    const listFilterStr = sessionStorage.getItem('listFilter');
    if (listFilterStr) {
      const listFilter = JSON.parse(listFilterStr);
      if (listFilter.name === this.$route.name) {
        this.filter = listFilter.filter;
      }
    }
    this.getData();
    this.getTypeData();
  },
  methods: {
    async getData() {
      const resp = await this.$services.admin.course.getList(this.filter);
      this.total = resp.data.total;
      this.data = resp.data.data;
      if (this.data.length === 0 && this.filter.page > 1) {
        this.filter.page--;
        this.getData();
        return;
      }
      sessionStorage.setItem(
        'listFilter',
        JSON.stringify({
          name: this.$route.name,
          filter: this.filter,
        }),
      );
    },
    async addCourse() {
      const resp = await this.$services.admin.course.post();
      this.$router.push({
        name: 'course/content',
        params: {
          id: resp.data.id,
        },
      });
    },
    onRowsPerPageChange() {
      this.filter.page = 1;
      this.getData();
    },
    dataView(row) {
      this.$router.push({
        name: 'course/content',
        params: {
          id: row.id,
        },
      });
    },
    async dataStatusChange(row) {
      await this.$services.admin.course.edit(row.id, {
        frontend_status: !row.frontend_status ? 1 : 0,
      });
      this.$lib.notify.success('儲存成功');
      this.getData();
    },
    async dataIsTopChange(row) {
      await this.$services.admin.course.edit(row.id, {
        is_top: !row.is_top ? 1 : 0,
      });
      this.$lib.notify.success('儲存成功');
      this.getData();
    },
    async dataDelete(row) {
      await this.$services.admin.course.delete(row.id);
      this.$lib.notify.success('刪除成功');
      this.getData();
    },
    async dataOffline(row) {
      await this.$services.admin.course.edit(row.id, {
        status: 5,
      });
      this.$lib.notify.success('下線成功');
      this.getData();
    },
    async getTypeData() {
      const resp = await this.$services.admin.course.type.getList();
      this.categoryData = resp.data;
      this.categoryData.forEach((item, index, array) => {
        this.categoryOption.push({ label: item.name, value: item.id });
      });
    },
    async onSelectCategory() {
      const resp = await this.$services.admin.course.getList(this.filter);
      this.total = resp.data.total;
      this.data = resp.data.data;
    },
    async onSelectStatus() {
      const resp = await this.$services.admin.course.getList(this.filter);
      this.total = resp.data.total;
      this.data = resp.data.data;
    },
    onKeywordInput() {
      if (this.keywordInputTimer) {
        clearTimeout(this.keywordInputTimer);
      }
      this.keywordInputTimer = setTimeout(() => {
        this.filter.page = 1;
        this.getData();
      }, 500);
    },
  },
};

```

index.vue
```
<template>
  <div>
    <div class="row justify-between items-center q-pb-sm">
      <div class="col-auto">
        <div class="row items-center">
          <div class="col-auto">
            <div class="text-h6">課程列表</div>
          </div>
          <div class="col-auto">
            <q-btn
              no-caps
              outline
              size="md"
              color="primary"
              label="新增"
              class="q-mx-sm"
              v-if="canEdit"
              @click="addCourse"
            />
          </div>
        </div>
      </div>
      <div class="col-auto">
        <Breadcrumbs />
      </div>
    </div>
    <q-card flat>
      <q-card-section class="q-py-sm">
        <div class="row items-center justify-between">
          <div class="col-auto">
            <div class="row items-center">
              <div class="col-auto">
                <q-select
                  dense
                  outlined
                  v-model="filter.rows_per_page"
                  :options="[5, 10, 20, 30, 40, 50]"
                  @input="onRowsPerPageChange"
                >
                  <template v-slot:before>
                    <div class="text-body2">顯示</div>
                  </template>
                  <template v-slot:after>
                    <div class="text-body2">筆資料</div>
                  </template>
                </q-select>
              </div>
            </div>
          </div>
          <div class="col-auto">
            <div class="row items-center">
              <div class="col-auto q-ml-sm q-px-sm">
                <q-select
                  dense
                  outlined
                  option-value="value"
                  emit-value
                  map-options
                  v-model="filter.category"
                  :options="categoryOption"
                  @input="onSelectCategory"
                >
                  <template v-slot:before>
                    <div class="text-body2">依分類查詢</div>
                  </template>
                </q-select>
              </div>
              <div class="col-auto q-ml-sm q-px-sm">
                <q-select
                  dense
                  outlined
                  option-value="value"
                  emit-value
                  map-options
                  v-model="filter.sale_status"
                  :options="StatusOption"
                  @input="onSelectStatus"
                >
                  <template v-slot:before>
                    <div class="text-body2">依狀態查詢</div>
                  </template>
                </q-select>
              </div>
              <div class="col-auto q-ml-md">
                <q-input
                  outlined
                  dense
                  v-model="filter.keyword"
                  label="關鍵字查詢"
                  hide-bottom-space
                  @input="onKeywordInput"
                >
                  <template v-slot:before>
                    <div class="text-body2">依標題查詢</div>
                  </template>
                </q-input>
              </div>
            </div>
          </div>
        </div>
      </q-card-section>
      <q-card-section class="q-py-sm">
        <MyTable
          :columns="columns"
          :data="data"
          :actions="actions"
          :filter="filter"
          :total="total"
          :actionView="true"
          :actionStatus="false"
          :actionDelete="true"
          :actionOffline="false"
          :actionFrontendStatus="true"
          actionViewRouter="course/content"
          @getData="getData"
          @dataView="dataView"
          @dataStatusChange="dataStatusChange"
          @dataDelete="dataDelete"
          @dataOffline="dataOffline"
        />
      </q-card-section>
    </q-card>
  </div>
</template>

<script src="./index.js"></script>

```