(app.vue)
<template>
? <div class="app">
? ? <div class="nav">
? ? ? <router-link to="/">首頁</router-link>
? ? ? <router-link to="/about/1">南京</router-link>
? ? ? <router-link to="/about/2">北京</router-link>
? ? ? <router-link to="/about/3">廣州</router-link>
? ? ? <router-link to="/about/1"><button>南京</button></router-link>
? ? ? <button @click="gotoBj">北京</button>
? ? ? <button @click="gotoGz">廣州</button>
? ? </div>
? ? <router-view></router-view>
? </div>
</template>
<script>
// useRouter方法吃既,用于返回當(dāng)前項(xiàng)目中的路由器對象
import {useRouter} from 'vue-router'
export default {
? name: 'App',
? methods: {
? ? gotoBj(){
? ? ? // 注意:之前在vue-router3中,這樣需要寫一個(gè)if保護(hù)一下,
? ? ? // 在vue-router4中這個(gè)bug已經(jīng)修復(fù)了
? ? ? this.$router.push('/about/2')
? ? }
? },
? setup() {
? ? // 返回當(dāng)前項(xiàng)目中的路由器對象
? ? let $router = useRouter()
? ? let gotoGz = ()=>{
? ? ? $router.push('/about/3')
? ? }
? ? return {
? ? ? gotoGz
? ? }
? }
}
</script>
<style>
*{
? margin: 0;
? padding: 0;
? list-style: none;
}
.app {
? border: 1px solid #ccc;
? padding: 10px;
? margin: 10px;
}
.nav{
? padding: 10px;
}
.nav a{
? padding: 0 10px;
? text-decoration: none;
}
</style>
(src/router/index.js)
// 從vue-router庫里面導(dǎo)入createRouter方法,用于創(chuàng)建路由器對象
// createWebHashHistory方法胶逢,返回的是hash路由模式
// createWebHistory方法葛碧,返回的是history路由模式
import {createRouter,createWebHashHistory,createWebHistory} from 'vue-router'
// 定義一個(gè)數(shù)組谎仲,配置路由信息
const routes = [
? {
? ? path:'/',
? ? name:'Home',
? ? component:()=>import('../views/Home.vue')
? },
? {
? ? // 路由定義參數(shù)
? ? path:'/about/:id',
? ? name:'About',
? ? component:()=>import('../views/About.vue')
? }
]
// createRouter方法的執(zhí)行結(jié)果返回一個(gè)路由器對象
// 該方法需要傳一個(gè)配置對象
const router = createRouter({
? //指定路由模式
? history:createWebHashHistory(),
? //指定具體的路由信息
? routes
})
// 導(dǎo)出路由器
export default router
(src/view/Home.vue)
<template>
? <div class="home">
? ? <h1>首頁</h1>
? ? <One></One>
? ? <!-- suspense內(nèi)置組件舞吭,用于加載異步組件幔虏,添加loading效果 -->
? ? <suspense>
? ? ? <!-- default插槽里面放置異步組件 -->
? ? ? <template #default>
? ? ? ? <Two></Two>
? ? ? </template>
? ? ? <!-- fallback插槽里面制作loading效果 -->
? ? ? <template #fallback>
? ? ? ? Loading...
? ? ? </template>
? ? </suspense>
? ? <!-- 異步組件产喉,可以不用suspense捂掰,
? ? 但是如果異步組件內(nèi)部的setup函數(shù)返回的是一個(gè)Promise對象,
? ? 此時(shí)的異步組件就必須要使用suspense -->
? ? <suspense>
? ? ? <template #default>
? ? ? ? <Three></Three>
? ? ? </template>
? ? ? <template #fallback>
? ? ? ? Loading...
? ? ? </template>
? ? </suspense>
? ? <!-- <Three></Three> -->
? </div>
</template>
<script>
// defineAsyncComponent方法曾沈,用于異步加載組件
import {defineAsyncComponent} from 'vue'
import One from '../components/One.vue'
// import Two from './components/Two.vue'
// 異步導(dǎo)入Two組件和Three
let Two = defineAsyncComponent(()=>import('../components/Two.vue'))
// 注意:如果組件中setup方法返回的是Promise對象这嚣,那么組件必須要采用異步的方式加載
// import Three from './components/Three.vue'
let Three = defineAsyncComponent(()=>import('../components/Three.vue'))
export default {
? name: 'App',
? components: {
? ? One,
? ? Two,
? ? Three
? }
}
</script>
<style scoped>
.home{
? border: 1px solid #ccc;
? padding: 10px;
}
</style>
(src/view/About.vue)
<template>
? <div class="about">
? ? <h1>關(guān)于</h1>
? ? <h3>{{city.name}}</h3>
? ? <div>{{city.content}}</div>
? </div>
</template>
<script>
import {computed, onMounted, ref, watch} from 'vue'
// 從路由中導(dǎo)入useRoute方法
// useRoute方法,用于返回當(dāng)前路由信息
import {useRoute} from 'vue-router'
export default {
? setup() {
? ? // 執(zhí)行useRoute()方法晦譬,返回當(dāng)前路由信息
? ? let $route = useRoute()
? ? // 城市id
? ? let cityId = ref(0)
? ? // 城市數(shù)組
? ? let citys = [
? ? ? {
? ? ? ? id:1,
? ? ? ? name:'南京',
? ? ? ? content:'南京的鴨血粉絲真好吃疤苹!'
? ? ? },
? ? ? {
? ? ? ? id:2,
? ? ? ? name:'北京',
? ? ? ? content:'北京的烤鴨真好吃!'
? ? ? },
? ? ? {
? ? ? ? id:3,
? ? ? ? name:'廣州',
? ? ? ? content:'廣州的小吃真好吃敛腌!'
? ? ? }
? ? ]
? ? // 當(dāng)前城市
? ? let city = computed(()=>{
? ? ? return citys.find(c=>c.id==cityId.value) || {}
? ? })
? ? // 頁面掛載完成后的生命周期函數(shù)
? ? onMounted(() => {
? ? ? let {id} = $route.params
? ? ? cityId.value = id
? ? })
? ? // 監(jiān)視路由參數(shù)的變化
? ? watch(()=>$route.params.id,(val)=>{
? ? ? cityId.value = val
? ? })
? ? return {
? ? ? city
? ? }
? }
};
</script>
<style scoped></style>
(src/components/One.vue)
<template>
? <div class="one">
? ? <h3>One</h3>
? ? <ul>
? ? ? <li v-for="(stu, index) in stus" :key="index">{{ stu }}</li>
? ? </ul>
? ? <button @click="show=true">顯示</button>
? ? <!-- teleport組件:官方起的名稱:瞬移卧土。通過to屬性確定里面的元素移動到哪 -->
? ? <teleport to="body">
? ? ? <div v-show="show" class="box">
? ? ? ? <button @click="show=false">關(guān)閉</button>
? ? ? ? <div>{{dog}}</div>
? ? ? </div>
? ? </teleport>
? </div>
</template>
<script>
import { reactive, ref } from "vue";
export default {
? setup() {
? ? let show = ref(false)
? ? let dog = {
? ? ? name:'蘭蘭',
? ? ? sex:'女生'
? ? }
? ? let stus = reactive([
? ? ? {
? ? ? ? no: 1,
? ? ? ? name: "張三",
? ? ? ? sex: "男",
? ? ? ? age: 20,
? ? ? },
? ? ? {
? ? ? ? no: 2,
? ? ? ? name: "李四",
? ? ? ? sex: "女",
? ? ? ? age: 22,
? ? ? },
? ? ? {
? ? ? ? no: 3,
? ? ? ? name: "王五",
? ? ? ? sex: "男",
? ? ? ? age: 24,
? ? ? },
? ? ]);
? ? return {
? ? ? stus,
? ? ? show,
? ? ? dog
? ? };
? },
};
</script>
<style scoped>
.one {
? border: 1px solid red;
? padding: 10px;
? /* 相對定位 */
? position: relative;
}
.box{
? width: 300px;
? height: 300px;
? border: 1px solid tomato;
? /* 絕對定位 */
? position: absolute;
? left: 0;
? top: 0;
? right: 0;
? bottom: 0;
? margin: auto;
? background-color: white;
}
</style>
(src/components/Two.vue)
<template>
? <div class="two">
? ? <h3>Two</h3>
? ? <ul>
? ? ? <li v-for="(car,index) in cars" :key="index">{{car}}</li>
? ? </ul>
? ? <button @click="show=!show">顯示/隱藏</button>
? ? <!-- 將需要過渡的元素通過transition組件包裹 -->
? ? <transition name="fade">
? ? ? <div v-show="show" class="box">你好呀!</div>
? ? </transition>
? </div>
</template>
<script>
import { reactive, ref } from "vue";
export default {
? setup() {
? ? let show = ref(true)
? ? let cars = reactive([
? ? ? {
? ? ? ? no:'蘇A1001',
? ? ? ? name:'大眾途觀L',
? ? ? ? color:'白色'
? ? ? },
? ? ? {
? ? ? ? no:'蘇A1002',
? ? ? ? name:'福特翼虎',
? ? ? ? color:'黑色'
? ? ? },
? ? ? {
? ? ? ? no:'蘇A1003',
? ? ? ? name:'JEEP自由光',
? ? ? ? color:'藍(lán)色'
? ? ? }
? ? ])
? ? return {
? ? ? cars,
? ? ? show
? ? }
? }
};
</script>
<style scoped>
.two{
? border: 1px solid green;
? padding: 10px;
? margin-top: 10px;
}
.box{
? width: 200px;
? height: 30px;
? border: 1px solid black;
? background-color: #eee;
? border: 1px solid tomato;
? margin: 5px 0;
? line-height: 30px;
? text-align: center;
}
/* 進(jìn)入時(shí)和離開時(shí) */
.fade-enter-active,.fade-leave-active {
? transition: all 0.5s ease;
}
/* 進(jìn)入前和離開后 */
.fade-enter-from,.fade-leave-to {
? opacity: 0;
? transform:translateX(10px);
}
</style>
(src/components/Three.vue)
<template>
? <div class="three">
? ? <h3>Three</h3>
? ? <ul>
? ? ? <li v-for="(food, index) in foods" :key="index">{{ food }}</li>
? ? </ul>
? </div>
</template>
<script>
import { reactive } from "vue";
export default {
? setup() {
? ? let foods = reactive([
? ? ? {
? ? ? ? id: 1,
? ? ? ? name: "大白菜",
? ? ? ? count: "5斤",
? ? ? },
? ? ? {
? ? ? ? id: 2,
? ? ? ? name: "雞腿",
? ? ? ? count: "10個(gè)",
? ? ? },
? ? ? {
? ? ? ? id: 3,
? ? ? ? name: "豆腐",
? ? ? ? count: "3塊",
? ? ? },
? ? ]);
? ? // 組件的setup方法像樊,返回出去的是一個(gè)Promise對象
? ? return new Promise((resolve, reject) => {
? ? ? setTimeout(() => {
? ? ? ? resolve({
? ? ? ? ? foods,
? ? ? ? });
? ? ? }, 2000);
? ? });
? },
};
</script>
<style scoped>
.three {
? border: 1px solid blue;
? padding: 10px;
? margin-top: 10px;
}
</style>
(main.js)
// 從vue庫里面導(dǎo)入createApp方法尤莺,用于創(chuàng)建Vue實(shí)例
import { createApp } from 'vue'
import App from './App.vue'
// 導(dǎo)入當(dāng)前項(xiàng)目中的路由器對象
import router from './router'
// Vue實(shí)例對象,通過use方法使用指定的路由器對象
createApp(App).use(router).mount('#app')
(vue.config.js)
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
? transpileDependencies: true,
? lintOnSave:true
})