vue3+ts的路由和pinia以及组件通信

vue3的路由

  1. 使用的方法和vue2相差不大
  2. 路由的跳转,使用的是router-link 实际上是一个a标签 ,to属性改变路径
  3. 跳转方式
    1. to=“/path”
    2. :to=“{name:’ name ’ }”
    3. :to=“{path:’ /path ’ }”

路由的嵌套

  1. 在vue3中,当要个路由嵌套时,在父路由的配置下 直接的写children会报错,原因应该是 定义的routes是有一定的泛型的,不允许直接的添加,需要在创建路由的时候导入 RouterRecordRaw 的方法,在给routes添加在相应的类型限制

    • const route:Array<RouterRecordRaw> = []
      

路由的传参

1.query的两种方法
  1. 第一种 query 使用比较复杂

    1. 参数在路径的后面添加,写在? 后面, 有多个的参数要使用 & 分割
    2. 同时 to要变成动态组件 添加: 参数的值需要使用模板字符串来存放变量key=${value }
    3. 获取参数的话 要导入hooks 的useRoute方法 在route.query.key 读取出值
  2. 第二种query

    1. 还是把to添加:变成动态的 传递一个query对象{path:’ ',query:{key:value}}
    2. 读取值还是和第一种一样
    <!-- 第一种-->    
    <li v-for="item in list" :key="item.id">
    <router-link :to="`/home/childid=${item.id}&title=${item.title}&detail=${item.detail}`">{{item.title }
    </router-link></li>
                  
          <!-- 第二种params -->
         <li> <router-link :to="{
            path: '/home/child',
            query: {
              id: item.id,
              title: item.title,
              detail: item.detail
            }
          }">{{ item.title }}</router-link></li>
    
     <!--参数的获取-->
     <div>
        <p>编号:{{ route.query.id }}</p>
        <p>标题:{{ route.query.title }}</p>
        <p>内容:{{ route.query.detail }}</p>
      </div>
      <div>
        <p>编号:{{ query.id }}</p>
        <p>标题:{{ query.title }}</p>
        <p>内容:{{ query.detail }}</p>
      </div>
    
    <script lang="ts" setup>
    import { useRoute } from 'vue-router';
    import { toRefs } from 'vue';
    let route = useRoute()
    // 再次的解构route 使得html中语句变的简单
    let { query } = toRefs(route)
    </script>
    
2.param传参
  1. params的第一种写法
    1. 在配置路由时先要使用 /:id/:title? 的类似参数 先在 路由的路径里面占位,后加?表示可传可不传
    2. 跳转时 也要使用模板字符串 /path/${} 的方法来写
    3. 获取参数 首先引用 useRoute的方法 再获取参数 const {router} = useRoute()
  2. params的第二种写法
    1. 在to中传递params的对象,参数的写法和query类似
    2. 但是不能使用path了 只能使用路由中配置的name才行
      <!-- <router-link :to="`/home/child/${item.id}/${item.title}/${item.detail}`">{{ item.title }}</router-link> -->
      <router-link :to="{
          name: 'detail',
          params: {
            id: item.id,
            title: item.title,
            detail: item.detail
          }
        }
        ">{{ item.title }}</router-link>
<!--路由的配置
      {
        path: "child/:id/:title/:detail",
        component: ChildParams,
        name: "detail",
      }, -->
3.路由的props配置
  1. 当我们使用的是params时 配置路由时可以添加一个属性 props:true,类似与把组件接收了父组件传过来的参数,这样的话 在获取参数的时候,就可以直接的使用变量 id,title,detail

  2. 切记展示的页面需要引入 方法 defineProps([])接收一下变量

  3. props:true 的作用是将路由接收到的params的参数作为props传递给路由组件

              params: {
                id: item.id,
                title: item.title,
                detail: item.detail,
    			props:true
              }
    
      <div>
        <p>编号:{{ id }}</p>
        <p>标题:{{ title }}</p>
        <p>内容:{{ detail }}</p>
      </div>
    
  4. 当我们想要一个query的传参时,还能使用props接收的话,我们就要写一个函数在路由中 props(route){ return route.query }

4.路由的replace模式
  1. 在router-link 添加replace时这样浏览器就不能放回上一次的页面 默认时history模式 可以返回的

编程式跳转

就是使用函数的跳转,不是使用router-link

  1. 使用的是useRouter方法 ,需要导入

  2. 在使用的时可以使用push(),跳转到指定的路径,并且to中可以写的params和query参数 都可以写在push中

    const getDetail = function (item: any) {
      router.push({
        name: 'detail',
        params: {
          id: item.id,
          title: item.title,
          detail: item.detail
        },
      })
    }
    
  3. 在这里需要传递的参数item可能会有type的报错,需要限制一下类型

路由的重定向

就是redirect,打开页面默认的页面

path:‘ ’

redriect: ‘/path’

集中式的状态管理

一般是共享的数据需要放在里面

  1. 搭建pinia环境 npm i pinia
  2. 在main.ts 中 引入pinia import {createPinia} from ‘pinia’
  3. 创建pinia const pinia = createPinial()
  4. 安装pinia use(pinia)

1.数据的保存

  1. 把要保存的数据存放在store文件夹中,在文件夹中写文件把数据保存。一般要注意命名
  2. 先导入defineStore 方法 要传入参数和配置对象,
    1. 一般参数是文件名
    2. 配置对象有state()方法 还必须return出来
  3. 实例化出来export const useCountStore = defineStore(’ name ',{ state(){ return { } } })
  4. 导出实例化,在使用

2.读取store中的数据

  1. 在使用的页面,先导入保存了数据的文件方法 import {useCountStore} from ’ ’
  2. 需要把方法给暴露出来
    1. const useCount = useCountStore()
  3. 读取数据时 useCount.sum/useCount.$state.sum 就是保存在内部的数据

3.数据的修改

三种修改数据的方法

  1. 我们定义了 useCount 的实例,就可以直接的修改数据 useCount.sum = 1

  2. 使用$patch( { sum:2 }),和定义的一样修改成相同的格式,

  3. 使用actions函数

    1. 要使用这个的话,要先在定义store的时候就要定义actions函数,是放置用于响应式动作的方法

    2. 然后再actions定义一个方法,在这个方法里修改state中保存的数据

      actions:{
          increment(value){
              this.sum += value
          }
      }
      
    3. 然后当我们调用这个方法时,就会发生数据的改变

      useCount.incement(2)
      
  4. actions 的用法是比较复杂的,但是我们可以添加更多的函数设置

4.storeToRefs 解构数据

  1. 展示数据太复杂了,可以对useCount进行解构,使用toRefs的话会全部成功为ref的数据
  2. storeToRefs只会对store的数据进行解构,不会对方法进行ref包裹

5.getters

  1. 当对数据不满意时,可以对数据进行修改,getters定义的方法是要 有return返回的 并且参数可以传入state直接读取数据
  2. 要使用getters内部的方法的话,可以在使用的组件中使用 storeToRefs解构 ,解构出来就可以使用了

6.监视数据发生的变化

每个store的方法实例化之后,就会有$subscribe( () => { } ) 函数,当检测的数据发生变化时,就是执行内部的函数,和监测函数watch有点类似,state 是当前存储的数据

useList.$subscribe((mutate, state) => {
  console.log(state);
})

1.父子组件的通信props

1.父传子
  1. 父传子,和vue2的类似 在子组件是的标签上使用 动态的数据绑定
  2. 子组件在接收的时候 需要导入defineProps方法,并且内部只能是数组,子组件就可以接收到了
2.子传父
  1. 需要使用函数来传递,父组件接收这个函数
  2. 在子组件中,写好要传递的函数,再把函数写进 defineProps的数组中
  3. 父组件 需要在子组件的标签中,接收之后,在重新的赋值给一个函数
3.自定义事件(用来子传父)
  1. @name =function 这就创建好了一个自定义的事件,就是当我们执行了name是就会触发function,并且这个自定义的事件也是可以发送的
  2. 这个自定义事件是执行不了的,给子组件绑定上自定义事件,使用defineEmits() 方法和defineProps方法类似,处理一下name 并且 用一个emit接收 const emit = defineEmit([‘name’])
  3. 处理之后就可以使用了,只要调用 emit(‘name’) 就能调用函数了 并且还可以传递参数,这样调用时参数会传递给function的函数中
4.v-model

2.祖传孙$attrs

  1. 实现祖元素和孙元素之间的数据传递,想在祖组件中定义数据,通过动态绑定先把数据传递给子组件,可以在devtools的工具中可以看到,祖组件传递的数据 若子组件接受了 则会在 props中显示,没接收的数据会在attrs中显示
  2. 在子组件中 我们给孙子组件标签添加上 v-model=‘$attrs’ 就能把数组传递给 孙组件了
  3. 孙组件需要使用defineProps方法来接收 数据 在这里也可以使用自定义事件

3.$ r e f s 和 refs和 refs $parent

  1. $refs用于 父传子
    1. 给子组件添加refs属性,就可以在父组件中拿到子组件的实例,但是 内部的数据时获取不到的,需要在子组件中使用 defineExpose({ }),暴露出想要修改的数据
    2. 在父组件中使用$refs的话就会获取到所有的子组件的实例对象,获取到的是一个对象,
  2. $parent用于 子传父
    1. 在子组件的函数中可以使用 $parent 获取到父组件的实例,但是也需要父组件把 属性暴露出来
    2. 子组件可以在函数中修改
  3. 两个都写在在标签的函数中,传递的参数是 $ $refs $ $parent

4.provide 和 inject 祖孙直接通信

  1. 祖传孙 在祖组件导入 provide方法 provide(‘name’ , 属性) 第二个是要传递的数据 可以是多个要用对象表示,接收的时候也需要解构
  2. 在孙组件 导入inject方法 来接收数据 let x = inject( ‘name’ , default )
  3. 孙组件传递数据给祖组件的话 需要在 祖组件中定义一个函数 让后也要通过 provide发送出去,让后在孙组件中接收,孙组件再调用函数
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值