--- 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) * 但若有第二層選單時要如何解決