1、二级路由配置 #2、路由守卫
router/index.js
// hash模式:createWebHashHistory
// import { createRouter, createWebHistory,createWebHashHistory } from 'vue-router'
import { createRouter, createWebHistory } from 'vue-router'
// 我们要想给页面 增加路由管理,就需要把页面引入进来
// import 引入页面文件,也可以用方法来引入
// / 代表根目录,根页面
import HomeView from '../views/HomeView.vue'
import Index from '../views/Index.vue'
import User from '../views/User.vue'
import Course from '../views/Course.vue'
import Lists from '../views/Lists.vue'
import Order from '../views/Order.vue'
import Config from '../views/User/config.vue'
// 注意大小写
import Info from '../views/User/info.vue'
const routes = [
// {
// path: '/',
// name: 'home',
// component: HomeView
// },
// {
// path: '/about',
// name: 'about',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
// component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue')
// },
{
path: '/', // 路由地址配置,就是浏览器上的url
alias : '/home', //起别名 多一个访问入口
name: 'index', // 是页面的名称,自定义,但是不要重复
component: Index, // 这个是页面文件的路径
beforeEnter:(to, from) =>{ //独享的
console.log(to);
console.log(to,from);
}
},
{
path: '/lists', // 列表页面
name: 'lists', // 是页面的名称,自定义,但是不要重复
component: Lists // 这个是页面文件的路径
},
{
path: '/order', // 列表页面
name: 'order', // 是页面的名称,自定义,但是不要重复
// component: Order // 这个是页面文件的路径
redirect : "/lists" //页面重定向
// redirect : (to) =>{
// console.log(to);
// }
},
{
path: '/course', // 课程页面
name: 'course', // 是页面的名称,自定义,但是不要重复
component: Course // 这个是页面文件的路径
},
{
path: '/user', // 用户页面
name: 'user', // 是页面的名称,自定义,但是不要重复
component: User, // 这个是页面文件的路径
children :[ //配置子路由
{
// 实现路由二级
path: 'info', // 用户页面
name: 'info', // 是页面的名称,自定义,但是不要重复
component: Info // 这个是页面文件的路径
},
{
//实现了 页面二级
path: '/config', // 用户页面
name: 'config', // 是页面的名称,自定义,但是不要重复
component: Config // 这个是页面文件的路径
}
]
},
]
const router = createRouter({
// hash模式:createWebHashHistory
// 访问路径就会多个#号 localhost:8080/#/user、localhost:8080/#/course
history: createWebHistory(process.env.BASE_URL),
routes
})
// 导航守卫
router.beforeEach ( (to,from)=>{
if(to.path =='/user'){
// 判断是否登录等
// 主要用来通过跳转或取消的方式守卫导航
// 有 前置守卫 和 后置钩子
// 植入路由导航位置:全局导航、路由独享、组件级守卫
alert('不能跳转');
return false;
}
console.log(to); //到达页面
console.log(from); //来源页面
})
// 导出路由
export default router
App.vue
<template>
<router-link to="/">我是首页</router-link>|
<router-link to="/lists">我是列表</router-link>|
<router-link to="/course?id=1&name=xiaomi">我是课程</router-link>|
<router-link to="/user?id=1&name=xiaomi">我是用户</router-link>|
<router-link to="/order">我是订单</router-link>|
<br>
<!-- <router-link to="/config">用户配置</router-link>|
<router-link to="/info">用户信息</router-link>| -->
<br><hr>
{{url()}}
<hr>
<!-- Hash路由,带#号的,用a标签跳转的时候,要增加上#号 -->
<a class="router-link-exact-active" href="/user">登录1 {{$route.path}}</a>
<br>
<!-- {} 是对象,里面是配置项, red 代表key,如果值等于true,就是red1 -->
<a class="{red1:$route.path == '/user'}" href="/user">登录2 {{$route.path}}</a>
<br>
<a href="/user" :class="{red1:$route.path=='/user'}">登录 3{{$route.path}}</a>
<br>
<a href="user" :class="{red1:$route.path=='/user'}">登录 4{{$route.path}}</a>
<br>
<hr>
{{url()}}
<hr>
<button @click="url1()">按钮跳转</button>
<hr>
<button @click="url1('/lists')">列表按钮</button>
<br>
<!-- js传值 -->
<button @click="url2('/course',200)">课程按钮</button>
<!-- app.vue页面没有刷新,刷新的是router-view 标签里的内容 -->
<router-view></router-view>
</template>
<script>
export default {
methods :{
url ( ) {
// $route 路由全局变量,在js里,不能直接使用。要this.
// $route 是url信息,路由页面信息
console.log(this.$route);
console.log(this.$router);
},
url1( url1) {
// this.$router.push(url);push 可以跳转
this.$router.push(url1);
this.$router.push({
path:url1,
query:{id:id},
});
},
url2( url2,id) {
// this.$router.push(url);push 可以跳转
this.$router.push(url2);
this.$router.push({
path:url2,
query:{id:id},
});
},
}
}
</script>
<style >
/* router-link标签会默认渲染为a标签
当router-link被点击时候的样式
.router-link-exact-active
router-link-active
区别
https://blog.csdn.net/qq_41633597/article/details/109194275
*/
a.router-link-exact-active,a.router-link-active {
color: gold;
}
.red1{
color: red;
}
</style>
User.vue
<template>
<div>这是用户页面</div>
<!-- 页面二级 -->
<router-link to="/config">用户配置</router-link>|
<!-- 路由二级 -->
<router-link to="/user/info">用户信息</router-link>|
<!-- app.vue页面没有刷新,刷新的是router-view 标签里的内容 -->
<router-view></router-view>
{{url()}}
</template>
<script>
export default {
methods :{
url(){
// console.log(this.$route);
console.log(this.$route.query.id);
console.log(this.$route.query.name);
},
}
}
</script>
user/config.vue
<template>
<div>这是用户配置页面</div>
</template>
user/info.vue
<template>
<div>这是用户信息页面</div>
</template>
3、组合API
props:
App.vue
<template>
<div>
<Props></Props>
<hr>
<Props :titel="title"></Props>
</div>
</template>
<script>
import { ref } from 'vue'
import Props from './components/Props';
export default {
components : {
Props
},
setup(){
const title = ref('百度');
return {
title
}
}
}
</script>
components/Props.vue
<template>
<!-- 组件
组件Props它也是vue后缀名文件,它也有setup -->
<li>你好</li>
<li>再见</li>
<div class="red">
{{title}}
</div>
</template>
<script>
export default ({
// 组件它也是vue后缀名文件,它也有setup
// props 之前props接收参数,是跟setup、data同一级的
// 有setup,就调用不到props里的数据了,因为不能用this
props : {
title:{
type : String
} },
setup(props,context) {
// setup 在组件里使用了,接收的 传值props,就在setup里不能使用
// 所有想在setup使用传值,要在setup接收参数
console.log(props);
console.log(context);
return {
title : props.title
}
}
})
</script>
响应:reactive
<template>
{{data}}
{{fun()}}
<!-- <div @click="fun">{{data}}--{{num}}</div> -->
<hr>
<div>{{data.num}}</div>
<hr>
<button @click="fun">添加</button>
</template>
<!-- <script>
export default {
setup(props) {
const data = '小牛';
const fun = ()=>{
alert('这是方法')
}
return {
data,
fun,
}
}
}
</script> -->
<script >
import {reactive} from 'vue';
// 3.2 新增 的功能,组合api功能
// 在 Script 标签上增加的setup参数
// 新增加的不需要retrun返回了,更加像js代码了
// 这两写法 更加推荐下面的写法
export default {
setup(){
// setup里的数据不是响应式,是因为setup最早执行的,没有this
const data = reactive ({
num : 1
})
const fun =( ) =>{
data.num = data.num+1;
}
return {
data,
fun,
}
}
}
</script>
插槽
<template>
<div>123</div>
<hello>自定义标签</hello>
<OneOne></OneOne>
<!-- <two></two> -->
<!-- 3组件传值 -->
<OneOne title="热门课程"></OneOne>
<!-- 4、 动态绑定 增加冒号可以动态传值,值可以动态绑定 -->
<OneOne :title="title"></OneOne>
<!-- 4.2 多个传值 - 传值的 key {title arr}-> -->
<OneOne :title="title" :arr="arr"></OneOne>
<hr>
<!-- 组件向页面传值 -->
<!-- fun5 跟引入组件事件名称一致 -->
<three @fun5 = "fun4"></three>
<div>{{sc_sum}}</div>
<hr>
<!-- 多组件 多层相互访问 -->
<!-- <four></four> -->
<two>哈哈</two>
<hr>
<five>
<a href="http://www.baidu.com">跳转页面</a>
</five>
<five>
<img style="width:200px;" src="https://img1.baidu.com/it/u=2218815005,3124653454&fm=253&fmt=auto&app=138&f=JPEG?w=889&h=500" alt="">
</five>
<five>
<template #img>
<img src="https://img1.baidu.com/it/u=2204132179,643663242&fm=253&fmt=auto&app=120&f=JPEG?w=1200&h=800" alt="">
</template>
</five>
<five>
<!-- v-slot:img2 语法糖 #img2 -->
<template #img2>
<a href="http://www.baidu.com">你好</a>
</template>
</five>
</template>
<script>
// 组件导入。哪个页面使用哪个页面导入
// import from 格式
// 名称 路径
// import moduleName from 'module';
// import HelloWorld from './components/HelloWorld.vue'
import hello from "./components/HelloWorld";
// import One from './components/One.vue';
import OneOne from "./components/OneOne";
import Two from "./components/Two.vue"
// import Three from './components/Three.vue';
// import two from './components/Two.vue';
import three from "./components/Three.vue";
// import Four from "./components/Four.vue";
import Five from "./components/Five.vue";
import Four from './components/Four.vue';
export default {
components: {
// 后面的值是引入的文件
// 前面的lkey是给这个文件下标的名称
hello: hello,
OneOne: OneOne,
three:three,
Two:Two,
Five:Five,
Four,
// Four:Four,
// two:two
},
data() {
return {
arr :{
lh : "小蛇",
hui : "小龙",
},
titel : "www.baidu.com",
sc_sum:0,
php:"百度",
}
},
methods: {
fun4(e){
this.sc_sum =this.sc_sum+ 2;
},
fun3(){
console.log("这是方法三");
},
fun5(){
console.log("这是方法5");
},
},
beforeCreate() {
console.log("1在创建组件之前调用");
},
created() {
console.log("2组件创建完成调用");
},
beforeMount() {
console.log("3模版挂载之前调用");
},
mounted() {
console.log("4模版挂载完成调用");
},
// name: 'App',
// components: {
// HelloWorld
// }
};
</script>
<style scoped >
/* scoped 防止样式穿透 */
div {
color: aqua;
}
</style>
插槽scoped样式穿透
<template>
<router-link to="/">我是首页</router-link>|
<router-link to="/lists">我是列表</router-link>|
<router-link to="/course">我是课程</router-link>|
<router-link to="/user">我是用户</router-link>|
<br><hr>
<!-- app.vue页面没有刷新,刷新的是router-view 标签里的内容 -->
<router-view></router-view>
<hr>
<br>
<br>
<six v-slot:img="data">
<div class="red">小马---{{data.php1}}---{{data.a}}---{{data}}</div>
</six>
<hr>
<six #img>
<div>小猴</div>
</six>
</template>
<script>
import Six from"./components/Six.vue"
export default {
components :{
Six,
}
}
</script>
<style scoped>
.red {
color: red;
}
</style>
监听:watch
<template>
<div>{{data.num}}</div>
<hr>
<button @click="fun">添加</button>
<br>
{{str}}
<br>
{{str1}}
<hr>
<div>a:{{a}}---b:{{b}}</div>
<button @click="add">按钮</button>
<hr>
<div>倒计时:{{b}}</div>
</template>
<script setup >
// reactive,ref 响应 watch vue 下的监听模块
import {reactive,ref, watch} from 'vue';
// import {ref} from 'vue';
const data = reactive ({
num : 1
})
const fun =( ) =>{
data.num = data.num+1;
console.log(str);
// console.log(str1);
console.log(str1.value);
}
const str ='小伙';
const str1 = ref('小孩');
// js 跟php 执行顺序不一样
const add = ()=>{
a.value++;
b.value--;
}
let a = ref(0);
let b = ref(60);
// watch ( ()=>{
// console.log(a.value);
// })
watch (a,(new_a,old_a)=>{
console.log(a.value);
// 变量是为了获取改变的值,new_a,获取改变的值
console.log(new_a);
// 第二参数, 获取未改变之前的值
console.log(old_a);
});
</script>
生命周期:onBeforeMount
<template>
<div>{{data.num}}</div>
<hr>
<button @click="fun">添加</button>
<br>
{{str}}
<br>
{{str1}}
<hr>
<div>a:{{a}}---b:{{b}}</div>
<button @click="add">按钮</button>
<hr>
<div>倒计时:{{b}}</div>
</template>
<script setup >
// reactive,ref 响应 watch vue 下的监听模块
// 生命周期 使用前要引入 onBeforeMount 模版挂载之前调用
import {reactive,ref, watch,onBeforeMount} from 'vue';
onBeforeMount( ()=>{
console.log('onBeforeMount');
} )
// import {ref} from 'vue';
const data = reactive ({
num : 1
})
const fun =( ) =>{
data.num = data.num+1;
console.log(str);
// console.log(str1);
console.log(str1.value);
}
const str ='小伙';
const str1 = ref('小孩');
// js 跟php 执行顺序不一样
const add = ()=>{
a.value++;
b.value--;
}
let a = ref(0);
let b = ref(60);
// watch ( ()=>{
// console.log(a.value);
// })
watch (a,(new_a,old_a)=>{
console.log(a.value);
// 变量是为了获取改变的值,new_a,获取改变的值
console.log(new_a);
// 第二参数, 获取未改变之前的值
console.log(old_a);
});
</script>
引入路由
<template>
</template>
<script >
// 需要引入路由模块 vue-router
import { useRoute, useRouter } from 'vue-router';
// 获取页面的信息
const route = useRoute();
// 在setup里不能使用了
// console.log(this.$route.path);
console.log(route.path);
// 页面跳转,传值
const router = useRouter();
</script>