Lala Code

Lala 的前端大補帖,歡迎一起鑽研前端技術😊

0%

Vue 動態路由設定

設定動態網址

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", // 加上: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]; // 移除斜線
// substr() 方法返回一個字符串中從指定位置開始到指定字符數的字符。
// split() 指定的字串分割,返回一個新Array
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:{} }); // 儲存API回來的data
const router = useRouter();
const goNewRouter = (id)=>{
router.push({path: `/courses/${id}`});
}
// 滑鼠中鍵沒辦法讓router.push跳出視窗
const openNewTab = (id) => {
const saveUrl = router.resolve({ path: `/courses/${id}` }); // router.resolve可儲存路徑
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'});
// router.push('/courses')
// router.go(-1); // 回上一頁
}, 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>
<!-- error_message -->
<h1 v-if="isError">{{ courses.data.errorMsg }}</h1>
</div>

以上是我的學習筆記,希望也有幫助到你哦 😀



Hey!想學習更多前端知識嗎?

最近 Lala 開了前端課程 👉【實地掌握RWD - 12小時新手實戰班】👈
無論您是 0 基礎新手,又或是想學 RWD 的初學者,
我們將帶你從零開始,深入了解並掌握 RWD 響應式網頁設計的核心技術,快來一起看看吧 😊



🚀線上課程分享

線上課程可以加速學習的時間,省去了不少看文件的時間XD,以下是我推薦的一些課程
想學習更多關於前後端的線上課程,可以參考看看。

Hahow

Hahow 有各式各樣類型的課程,而且是無限次數觀看,對學生或上班族而言,不用擔心被時間綁住



六角學院

如果你是初學者,非常推薦六角學院哦!
剛開始轉職也是上了六角的課,非常的淺顯易懂,最重要的是,隨時還有線上的助教幫你解決問題!


Udemy

Udemy 裡的課程非常的多,品質普遍不錯,且價格都滿實惠的,CP值很高!
也是很多工程師推薦的線上課程網站。
❤️