Vue路由的分类与使用

watchEffect

立即运行一个函数,同时响应式的追踪其依赖,并重新执行函数

<template>
  <div>
    <h1>{{ num1 }} + {{ num2 }} = {{ num1 + num2 }}</h1>
    <button @click="changeNum1">num1++</button>
    <button @click="changeNum2">num2++</button>
  </div>
</template>
<script lang="ts" setup name="Person">
import {ref, watch, watchEffect} from "vue";
let num1 = ref(1);
let num2 = ref(3);

const changeNum1 = () => {
  num1.value += 1;
}

const changeNum2 = () => {
  num2.value += 1;
}
/*watch([num1, num2], (value) => {
  const [newNum1, newNum2] = value;
  console.log(newNum1, newNum2)
  if (newNum1 == 5 || newNum2 == 7) {
    console.log("数据到达");
  }
})*/
const stopWatch = watchEffect(() => {
  console.log(num1.value,num2.value)
  if (num1.value == 5 || num2.value == 7) {
    console.log("数据到达,停止监视");
    stopWatch();
  }
})


</script>

<style scoped>

</style>

标签ref属性

作用 在普通的DOM上 获取DOM节点,用在组件上 获取组件实例
用于DOM 获取节点

 <h1 ref="title1">猿究院</h1>
 <h1 ref="title2">北大街</h1>
 <h1 ref="title3">Vue</h1>
 <input type="text" value="默认值" ref="ipt"/>
 
let title1 = ref();
let title2 = ref();
let title3 = ref();
let ipt = ref();

const showLog = () => {
  console.log(title1.value)
  console.log(title2.value)
  console.log(title3.value)
  //ipt  > RefImpl >value <input 对象 .value
  console.log(ipt.value.value)
}

ref作用于组件上

<Message ref="msg"></Message>

********* 子组件中
//使用defineExpose将组件的数据交给外部组件
defineExpose({title, desc})
*********
let msg = ref();
const getMessage = () => {
  console.log(msg.value.title)
  console.log(msg.value.desc)

}

props

<template>
  <Person :list="persons"></Person>
</template>
<script lang="ts" setup name="App">
import Person from "@/components/Person.vue";
import {reactive} from "vue";
import type {Persons} from "@/assets/IPersonInter";
import {nanoid} from "nanoid";

let persons = reactive<Persons>([
  {id: nanoid(), name: '张三', age: 20},
  {id: nanoid(), name: '李四', age: 19},
  {id: nanoid(), name: '王五', age: 25}
])

</script>
<style lang="scss" scoped>
</style>

<template>
  <ul v-if="list != undefined">
    <li v-for="(p,index) in list" :key="p.id">
      {{ p.name }} - {{ p.age }}
    </li>
  </ul>
  <div v-else>
    暂无数据
  </div>
</template>

<script lang="ts" setup name="Person">
import type {Persons} from "@/assets/IPersonInter";
//第一种写法
// const props = defineProps(['list']);

//第二种写法  接收 + 限制类型
// const props =defineProps<{list:Persons}>();

//第三种写法 接收 + 限制类型 + 指定默认值+限制必要性 (? 可以传 可不传)
const props = withDefaults(defineProps<{ list?: Persons }>(), {
  list: () => [{id: "001", name: '默认值', age: 0}]
});

//在setup中使用 接收到的数据时  需要通过 props对象 .
console.log(props.list)
</script>
<style scoped>
</style>

自定义的hook

本质是一个函数,把setup中的 组合式 API进行封装。

hook 优势:让代码复用 ,让setup中的逻辑更清楚。

useDog.ts
import {onMounted, reactive} from "vue";
import axios, {AxiosError} from "axios";

export default function () {

    let dogList = reactive<string[]>([])

    async function getDog() {
        //发送请求
        try {
            let {data} = await axios.get("https://dog.ceo/api/breed/weimaraner/images/random");
            console.log("请求的结果:", data);
            dogList.push(data.message)
        } catch (error) {
            const err = <AxiosError>error;
            console.log(err.message)
        }
    }
    onMounted(() => {
        getDog();
    })
    return {dogList, getDog}
}
useSum.ts
import {ref, onMounted} from 'vue'
export default function () {

    let sum = ref(0);

    const increment = () => {
        sum.value += 1;
    }
    const decrement = () => {
        sum.value -= 1;
    }

    onMounted(() => {
        console.log("执行了useSum的onMounted")
        increment();
    })

    //向外暴露数据
    return {sum, increment, decrement}
}
Person.vue
<template>
  <h2>当前求和:{{ sum }}</h2>
  <button @click="increment">点我+1</button>
  <button @click="decrement">点我-1</button>
  <hr/>
  <button @click="getDog">再来一直狗子</button>
  <img style="width: 200px;" :src="(dog as string)" v-for="(dog,index) in dogList" :key="index">
</template>

<script lang="ts" setup name="Person">
import useSum from "@/assets/useSum";
import {onMounted} from "vue";
import useDog from "@/assets/useDog";

let {sum, increment, decrement} = useSum();
let {dogList, getDog} = useDog();

onMounted(() => {
  console.log("我是person组件的onMounted")
})

</script>
<style scoped>
</style>

路由

1.安装 npm install vue-router@4
2.使用 在 src/router/index.ts文件

import {createRouter, createWebHistory} from 'vue-router'

//被路由的组件
import Home from "@/components/Home.vue";
import About from "@/components/About.vue";


const router = createRouter({
    history: createWebHistory(),
    routes: [
        {
            path: "/",  默认访问
            component: Home
        },
        {
            path: '/home',
            component: Home
        },
        {
            path: '/about',
            component: About
        }
    ]
})

export default router;


 <!--  声明式路由 -->
 <RouterLink to="/home">Home</RouterLink>
 <RouterLink to="/about">About</RouterLink>
 <hr/>
 <!--  被路由的组件 会显示在 RouterView -->
 <RouterView></RouterView>

路由的模式

​ 1.history (createWebHistory) URL地址更加美观 不带# 更加接近传统的URL。

后期上线后 需要后台配合处理路径问题 否则 刷新可能会有404错误

​ 2.createWebHashHistory 兼容性更好,后期不需要后台的处理

to属性 的两种写法

 to 字符串写法
 <RouterLink to="/home">Home</RouterLink>
 to对象写法

嵌套路由

router/index.ts

import {createRouter, createWebHashHistory, createWebHistory} from 'vue-router'

//被路由的组件
import Home from "@/components/Home.vue";
import About from "@/components/About.vue";
import News from "@/components/News.vue";
import Detail from "@/components/Detail.vue";


const router = createRouter({
    history: createWebHashHistory(),
    routes: [
        {
            path: "/",
            component: Home
        },
        {
            path: '/home',
            component: Home,
            children: [  嵌套路由
                {
                    path: "news",  路径前不加/
                    component: News,
                    children: [
                        {
                            path: "detail",
                            component: Detail
                        }
                    ]
                }
            ]
        },
        {
            path: '/about',
            component: About
        }
    ]
})

export default router;


使用 
news.vue
<!--  导航-->
to:需要写全路径
<RouterLink to="/home/news/detail">Detail</RouterLink>
<!--  展示被路由的组件-->
<RouterView></RouterView>

命名路由

在路由配置文件 新增属性(name)

  {
  path: "news",
  component: News,
  children: [
      {
      path: "detail",
      name:'xq',
      component: Detail
      }
  ]
  }

使用

<!-- 使用命名路由 需要对象写法的to属性  -->
  <RouterLink :to="{
    name:'xq'
  }">Detail
  </RouterLink>

路由懒加载

import {createRouter, createWebHashHistory, createWebHistory} from 'vue-router'

// //被路由的组件
// import Home from "@/components/Home.vue";
// import About from "@/components/About.vue";
// import News from "@/components/News.vue";
// import Detail from "@/components/Detail.vue";

const router = createRouter({
history: createWebHashHistory(),
 routes: [
     {
         path: "/",
         component: () => import('@/components/Home.vue')
     },
     {
         path: '/home',
         component: () => import('@/components/Home.vue'),
         children: [
             {
                 path: "news",
                 component: () => import('@/components/News.vue'),
                 children: [
                     {
                         path: "detail",
                         name: 'xq',
                         component: () => import('@/components/Detail.vue')
                     }
                 ]
             }
         ]
     },
     {
         path: '/about',
         component: () => import('@/components/About.vue')
     }
    ]
})

export default router;

路由重定向

 {
 path: "/",
 component: () => import('@/components/Home.vue'),
 redirect: to => {
    // 方法接收目标路由作为参数
    // return 重定向的字符串路径/路径对象
    return {
        // path:"/home/news/detail"
        name:'xq' //命名路由
    }
}
},
            
            
            
 {
 path: "/",
 component: () => import('@/components/Home.vue'),
 redirect: { // path:"/home/news/detail"
              name:'xq' //命名路由
                }
},

路由传参

1.query传参
<RouterLink to="/home/news/detail?id=1&title=测试数据A">Detail</RouterLink>

  <!--  <RouterLink :to="{name:'xq',query:{id:2,title:'测试数据B'}}">-->
  <!--    Detail-->
  <!--  </RouterLink>-->
接收
import {useRoute} from "vue-router";

const route = useRoute();

{{route.query.参数名}}-{{route.query.title}}2.
2.params传参
1.index.ts中  路由配置占位符
  {
    path: "news",
      component: () => import('@/components/News.vue'),
      children: [
          {
              path: "detail/:id/:title", 占位符
              name: 'xq',
              component: () => import('@/components/Detail.vue')
          }
      ]
  }
使用
<!--params 传参  字符串写法-->
<RouterLink to="/home/news/detail/1/测试数据A">Detail</RouterLink>
  <!-- params 传参 使用命名路由 需要对象写法的to属性  -->
<RouterLink :to="{name:'xq',params:{id:2,title:'测试数据B'}}">
      Detail
    </RouterLink>
    
接收
import {useRoute} from "vue-router";

const route = useRoute();
接收属性
route.params.属性名

简化接收参数的方式 路由的props

ruter/index.ts
  path: "detail/:id/:title",
  name: 'xq',
  component: () => import('@/components/Detail.vue'),
  
  props:{id:'0000',title:'暂无数据'} // 固定值
  //props 布尔写法 将收到的params参数作为 props传入组件
  props:true
props 函数写法
props(route) {
 return route.query;
  }

replace属性

作用:控制路由跳转是 浏览器的历史记录
push 默认值 : 追加历史记录
replace 替换当前记录

编程式路由

import router from "@/router";
// router.replace({
router.push({
    // path:''
    name: 'xq',
    params: {
      id: id,
      title: title
    }
  })
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值