設定動態網址
main.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| import { createRouter, createWebHistory } from "vue-router"; import Home from "../views/Home.vue";
const routes = [ { path: "/", name: "Home", component: Home, }, { path: "/about", name: "About", component: () => import("../views/About.vue"), }, { path: "/courses", name: "Courses", component: () => import("../views/Courses/index.vue"), }, { path: "/courses/:id", name: "Courses_id", component: () => import("../views/Courses/_id.vue"), }, ];
const router = createRouter({ history: createWebHistory(process.env.BASE_URL), routes, });
export default router;
|
設定外層的nav
useRoute: 用來獲取網址上面的參數
useRouter: 提供處理轉址相關的操作API
點擊選單,會根據路由去加上active,由於動態選單不會被加上router-link-active,所以使用監聽的方式去綁定class
App.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| import { reactive, ref, watch } from 'vue'; import { useRoute } from 'vue-router'; export default { setup() { const route = useRoute(); const reouteArr = reactive(['', 'about', 'courses']); const index = ref(0); watch( ()=>route.path, ()=>{ reouteArr.forEach((item, idx) => { const rp = route.path.substr(1).split('/')[0]; if (item === rp) { index.value = idx; } }) } ) return { index }; }, };
|
1 2 3 4 5 6 7 8
| <div id="nav"> <router-link to="/" :class="{active:index === 0}"> Home </router-link> | <router-link to="/about" :class="{active:index === 1}"> About </router-link> | <router-link to="/courses" :class="{active:index === 2}"> Courses </router-link> </div> <router-view />
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| * { padding: 0; margin: 0; box-sizing: border-box; } html, body { width: 100%; height: 100%; } #app { width: 100%; height: 100%; font-family: Avenir, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; }
#nav { padding: 30px; a { font-weight: bold; color: #2c3e50; &.active { color: #42b983; } } }
|
內層的選單
如要切換選單時做更多的效果可以不使用router-link
router.push可以指向要去的頁面
router.push(‘/路徑’) or router.push({ path: ‘/路徑’ })
router.go(-1);回上一頁
滑鼠中鍵沒辦法讓router.push跳出視窗
可以使用router.resolve儲存路徑,再用純JS開啟路徑的視窗
/Courses/index.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| import { useRouter } from 'vue-router'; import { onMounted, reactive } from 'vue'; import axios from "axios"; export default { setup() { const coursesList = reactive({ data:{} }); const router = useRouter(); const goNewRouter = (id)=>{ router.push({path: `/courses/${id}`}); } const openNewTab = (id) => { const saveUrl = router.resolve({ path: `/courses/${id}` }); window.open(saveUrl.href); }
onMounted(()=>{ axios.get('https://vue-lessons-api.herokuapp.com/courses/list').then((res)=>{ coursesList.data = res.data; }) }) return { coursesList, goNewRouter, openNewTab }; }, };
|
如果 @click事件有兩個就要加修飾符,才知道點的是要觸發哪一個Funtion
@click.left 滑鼠左鍵 @click.middle 滑鼠中鍵
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <div id="courses"> <a class="card" v-for="item in coursesList.data" :key="item.id" @click.left="goNewRouter(item.id)" @click.middle="openNewTab(item.id)" > <img :src="item.photo" alt="" /> <div class="content"> <h1>{{ item.name }}</h1> <div class="teacher-box"> <div class="teach-img"> <img class="teacher" :src="item.teacher.img" alt="" /> <p>{{ item.teacher.name }}</p> </div> <h2>NTD: {{ item.money }}</h2> </div> </div> </a> </div>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| #courses { position: fixed; top: 50%; left: 50%; transform: translateX(-50%) translateY(-50%); } a.card { cursor: pointer; display: flex; justify-content: space-between; align-items: flex-start; width: 318px; height: auto; padding: 10px; border-radius: 5px; box-shadow: 0 0 5px rgba($color: #000000, $alpha: 0.2); margin-bottom: 20px; opacity: 0.7; transition: opacity 0.2s; background-color: rgb(231, 231, 231); &:hover { opacity: 1; } > img { margin-right: 10px; } .content { > h1 { font-size: 14px; text-align: left; } .teacher-box { display: flex; justify-content: space-between; align-items: center; margin-top: 5px; > h2 { font-size: 13px; } .teach-img { display: flex; justify-content: flex-start; align-items: center; > img { border-radius: 25px; margin-right: 10px; } } } } }
|
設定內頁
/Courses/_id.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| import { useRoute, useRouter } from 'vue-router'; import { onMounted, onUnmounted, reactive, ref } from 'vue'; import axios from 'axios'; export default { setup() { const route = useRoute(); const router = useRouter(); const courses = reactive({ data:{} }); const isError = ref(false); let timer = null;
onMounted(()=>{ axios.get(`https://vue-lessons-api.herokuapp.com/courses/${route.params.id}`) .then(res=>{ courses.data = res.data.data[0]; }).catch(error=>{ isError.value = true; courses.data['errorMsg'] = error.response.data.error_message; timer = setTimeout(()=>{ router.push({path:'/courses'}); }, 3000) }) }) onUnmounted(()=>{ clearTimeout(timer); })
return { courses, isError }; }, };
|
物件第二層初始時會是空的(undefined),用v-if包住,等有資料時才會出現
1 2 3 4 5 6 7 8 9 10 11 12 13
| <div> <div v-if="!isError"> <h1>{{ courses.data.name }}</h1> <h2>NTD: {{ courses.data.money }}</h2> <img :src="courses.data.photo" alt="" /> <div v-if="Object.keys(courses.data).length !== 0"> <img :src="courses.data.teacher.img" alt="" /> <p>{{ courses.data.teacher.name }}</p> </div> </div> <h1 v-if="isError">{{ courses.data.errorMsg }}</h1> </div>
|
以上是我的學習筆記,希望也有幫助到你哦 😀
🚀實體工作坊分享
最近時賦學苑開了實體體驗課,即使你對程式碼沒有概念也能上手!Lala 會帶你一起做出一個個人品牌形象網站,帶你快速了解前端的開發流程,快跟我們一起玩轉 Web 吧!
🚀線上課程分享
線上課程可以加速學習的時間,省去了不少看文件的時間XD,以下是我推薦的一些課程
想學習更多關於前後端的線上課程,可以參考看看。
Hahow 有各式各樣類型的課程,而且是無限次數觀看,對學生或上班族而言,不用擔心被時間綁住
如果你是初學者,非常推薦六角學院哦!
剛開始轉職也是上了六角的課,非常的淺顯易懂,最重要的是,隨時還有線上的助教幫你解決問題!
Udemy 裡的課程非常的多,品質普遍不錯,且價格都滿實惠的,CP值很高!
也是很多工程師推薦的線上課程網站。