(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方法,用于返回当前项目中的路由器对象
import {useRouter} from 'vue-router'
export default {
name: 'App',
methods: {
gotoBj(){
// 注意:之前在vue-router3中,这样需要写一个if保护一下,
// 在vue-router4中这个bug已经修复了
this.$router.push('/about/2')
}
},
setup() {
// 返回当前项目中的路由器对象
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库里面导入createRouter方法,用于创建路由器对象
// createWebHashHistory方法,返回的是hash路由模式
// createWebHistory方法,返回的是history路由模式
import {createRouter,createWebHashHistory,createWebHistory} from 'vue-router'
// 定义一个数组,配置路由信息
const routes = [
{
path:'/',
name:'Home',
component:()=>import('../views/Home.vue')
},
{
// 路由定义参数
path:'/about/:id',
name:'About',
component:()=>import('../views/About.vue')
}
]
// createRouter方法的执行结果返回一个路由器对象
// 该方法需要传一个配置对象
const router = createRouter({
//指定路由模式
history:createWebHashHistory(),
//指定具体的路由信息
routes
})
// 导出路由器
export default router
(src/view/Home.vue)
<template>
<div class="home">
<h1>首页</h1>
<One></One>
<!-- suspense内置组件,用于加载异步组件,添加loading效果 -->
<suspense>
<!-- default插槽里面放置异步组件 -->
<template #default>
<Two></Two>
</template>
<!-- fallback插槽里面制作loading效果 -->
<template #fallback>
Loading...
</template>
</suspense>
<!-- 异步组件,可以不用suspense,
但是如果异步组件内部的setup函数返回的是一个Promise对象,
此时的异步组件就必须要使用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'
// 异步导入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>关于</h1>
<h3>{{city.name}}</h3>
<div>{{city.content}}</div>
</div>
</template>
<script>
import {computed, onMounted, ref, watch} from 'vue'
// 从路由中导入useRoute方法
// useRoute方法,用于返回当前路由信息
import {useRoute} from 'vue-router'
export default {
setup() {
// 执行useRoute()方法,返回当前路由信息
let $route = useRoute()
// 城市id
let cityId = ref(0)
// 城市数组
let citys = [
{
id:1,
name:'南京',
content:'南京的鸭血粉丝真好吃!'
},
{
id:2,
name:'北京',
content:'北京的烤鸭真好吃!'
},
{
id:3,
name:'广州',
content:'广州的小吃真好吃!'
}
]
// 当前城市
let city = computed(()=>{
return citys.find(c=>c.id==cityId.value) || {}
})
// 页面挂载完成后的生命周期函数
onMounted(() => {
let {id} = $route.params
cityId.value = id
})
// 监视路由参数的变化
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">关闭</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:'蓝色'
}
])
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;
}
/* 进入时和离开时 */
.fade-enter-active,.fade-leave-active {
transition: all 0.5s ease;
}
/* 进入前和离开后 */
.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个",
},
{
id: 3,
name: "豆腐",
count: "3块",
},
]);
// 组件的setup方法,返回出去的是一个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库里面导入createApp方法,用于创建Vue实例
import { createApp } from 'vue'
import App from './App.vue'
// 导入当前项目中的路由器对象
import router from './router'
// Vue实例对象,通过use方法使用指定的路由器对象
createApp(App).use(router).mount('#app')
(vue.config.js)
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
transpileDependencies: true,
lintOnSave:true
})