---
# System prepended metadata

title: 動態網址實做
tags: [Mike課程]

---

---
tags:  Mike課程
---


# 動態網址實做

### 串接api

* 串接api後端資料 以get方式取回並做迴圈動作

> 取回api
```javascript=
import axios from "axios";
import { onMounted, reactive } from "vue";

export default {
  setup() {
    const reslist = reactive({ data: {} });
    onMounted(() => {
      axios
        .get("https://vue-lessons-api.herokuapp.com/courses/list")
        .then((res) => {
           //取得api 後，存入變數
          reslist.data = res.data;
          console.log(reslist.data);
        });
    });
    return { reslist };
  },
};
```
> 渲染至頁面

```htmlembedded=
<template>
  <div id="courses">
    <a class="card" v-for="item in reslist.data" :key="item.id">
      <img :src="item.photo" alt="" />
      <div class="content">
        <h1></h1>
        <div class="teacher-box">
          <div class="teach-img">
            <img class="teacher" :src="item.teacher.img" alt="" />
            <p></p>
          </div>
          <h2>NTD:{{ item.money }}</h2>
        </div>
      </div>
    </a>
  </div>
</template>
```

### router 動態載入內頁

* 當列表要點選內頁時我們可透過id來做變化，可先新增_id.vue頁面、來進行點選時透過id進行轉跳

> router設定

```javascript=
  {
    path: "/courses/:id",
    name: "Courses_id",
    component: () => import("../views/Courses/_id.vue"),
  },
```
> a連結改為 router-link連結、:to需要綁定雙冒號:、在網址後面加入動態id變數

```htmlembedded=
<router-link
      class="card"
      v-for="item in reslist.data"
      :key="item.id"
      :to="`/courses/${item.id}`"
    >
      <img :src="item.photo" alt="" />
      <div class="content">
        <h1></h1>
        <div class="teacher-box">
          <div class="teach-img">
            <img class="teacher" :src="item.teacher.img" alt="" />
            <p></p>
          </div>
          <h2>NTD:{{ item.money }}</h2>
        </div>
      </div>
    </router-link>
```
### useRoute 取得內頁參數
* 我們點選內頁時，需要取得內頁的參數例如id以及資料等，一般js會用到locationc取得、但這邊會用到 vue的useRoute實做。

> 載入套件

```javascript=
import { onMounted } from "vue";
```
> onMounted生命週期後取得

```javascript=
export default {
  setup() {
    const route = useRoute();
    onMounted(() => {
      console.log(route);
    });

    return {};
  },
};
```
![](https://i.imgur.com/3BMTtqN.png)

>在使用axios取回 內頁api資料

```javascript=
import { useRoute } from "vue-router";
import { onMounted, reactive } from "vue";
import axios from "axios";
export default {
  setup() {
    const route = useRoute();
    const getcontent = reactive({ data: {} });
    onMounted(() => {
      axios
        // 取得當前的id
        .get(`https://vue-lessons-api.herokuapp.com/courses/${route.params.id}`)
        .then((res) => {
          // 回傳結果 塞入 getcontent.data中
          getcontent.data = res.data.data[0];
          console.log(getcontent.data);
        });
    });

    return { getcontent };
  },
};
```
>回傳至畫面中

```htmlembedded=
<template>
  <div>
    <div>
      <h1>{{ getcontent.data.name }}</h1>
      <h2>NTD: {{ getcontent.data.money }}</h2>
      <img :src="getcontent.data.photo" alt="" />
      <div v-if="Object.keys(getcontent.data).length !== 0">
        <img :src="getcontent.data.teacher.img" alt="" />
        <p></p>
      </div>
    </div>
    <!-- error_message -->
    <h1></h1>
  </div>
</template>
```

<div class="alert alert-danger text-center" role="alert">
  因為從login時 getcontent.data.teacher.img 是空值，讀不到得所以會造成錯誤
</div>

![](https://i.imgur.com/wo8OI9R.png)

* 所以必須加上判斷顯示

```htmlembedded=
v-if="Object.keys(getcontent.data).length !== 0"
```

### API 錯誤訊息製作

* 當我們api製作時有可能user使用操作錯誤這時就會出現

![](https://i.imgur.com/saW5O5y.png)

* 定義一個顯示錯誤的判斷

```javascript=
 const isArray = ref(false);
```

* axios API 接收錯誤顯示的訊息

```javascript=
  .catch((error) => {
          // 若錯誤就顯示 true
          isArray.value = true;
          // 回傳response error
          getcontent.data["error_show"] = error.response.data.error_message;
          console.log(error.response.data.error_message);
        });
```
* 多加了錯誤的Html判斷

```htmlembedded=
<div v-if="!isArray">
      <h1>{{ getcontent.data.name }}</h1>
      <h2>NTD: {{ getcontent.data.money }}</h2>
      <img :src="getcontent.data.photo" alt="" />
      <div v-if="Object.keys(getcontent.data).length !== 0">
        <img :src="getcontent.data.teacher.img" alt="" />
        <p></p>
      </div>
    </div>
    <!-- error_message -->
    <h1 v-if="isArray">{{ getcontent.data.error_show }}</h1>
  </div>
```
> 整體程式碼

```javascript=
export default {
  setup() {
    const route = useRoute();
    const isArray = ref(false);
    const getcontent = reactive({ data: {} });
    onMounted(() => {
      axios
        // 取得當前的id
        .get(`https://vue-lessons-api.herokuapp.com/courses/${route.params.id}`)
        .then((res) => {
          // 回傳結果 塞入 getcontent.data中
          getcontent.data = res.data.data[0];
          console.log(getcontent.data);
        })
        .catch((error) => {
          // 若錯誤就顯示 true
          isArray.value = true;
          // 將錯誤訊息 放入 [之中] 後面使用
          getcontent.data["error_show"] = error.response.data.error_message;
          console.log(error.response.data.error_message);
        });
    });

    return { getcontent, isArray };
  },
};
```
>html
```htmlembedded=
<template>
  <div>
    <div v-if="!isArray">
      <h1>{{ getcontent.data.name }}</h1>
      <h2>NTD: {{ getcontent.data.money }}</h2>
      <img :src="getcontent.data.photo" alt="" />
      <div v-if="Object.keys(getcontent.data).length !== 0">
        <img :src="getcontent.data.teacher.img" alt="" />
        <p></p>
      </div>
    </div>
    <!-- error_message -->
    <h1 v-if="isArray">{{ getcontent.data.error_show }}</h1>
  </div>
</template>
```

### useRouter 自動轉跳網址
* 當我們user操作網址等失敗時們可以設定讓她錯誤後自動轉跳的方式。

> import 套件

```javascript=
import { useRouter } from "vue-router";
```

> 套件定義變數引入

```javascript=
 const routerget = useRouter();
```
* 以下三種方式都可以自動導回頁面

```javascript=
  routerget.push("/courses");
  routerget.push({ path: "/courses" });
  routerget.go(-1);
```

* 使用setTimeout 3秒後倒回指定頁面
```javascript=
 // 時間過了三秒後手動跳轉指定網址
          setTimeout(() => {
            routerget.push("/courses");
            routerget.push({ path: "/courses" });
            routerget.go(-1);
          }, 3000);
```

### onUpdated 取消倒數轉跳

* 當我們使用者user轉跳畫面等待時，若點選別的地方後他還是會強制轉跳指定畫面，這時我們可以運用生命週期onUpdated當資料變化後清除轉跳動作

>先給予一個空值

```javascript=
   const timer = null;
```

> 將 setTimeout 賦予變數中

```javascript=
 timer = setTimeout(() => {

            routerget.go(-1);
          }, 3000);
```

* onUpdated 搭配 clearTimeout函式清空計數器

```javascript=
 onUpdated(() => {
            clearTimeout(timer);
          });
```

### router-link-active 選單

* 當我們點選menu時、需要再active時出現狀態、這時vue router-link已經幫你準備好了、這時只要對應對了css可以作好簡單的效果

![](https://i.imgur.com/BMb83Mb.png)

* 但若有第二層選單時要如何解決