Vue3 使用嵌套路由、以及遇到的 Property ‘xxx‘ does not exist on type

一、在Vue3中路由和Vue2的使用区别

首先如果你习惯性的使用this.$router那你肯定会得到一个报错,因为Vue3中是没有了this,使用的是全新的API,所以这时候我们需要引入 Router 中 useRouter 的这个函数

import { defineComponent, reactive} from "vue"
import { useRouter } from "vue-router"
export default defineComponent({
	setup() {
    const router = useRouter()
    console.log("router----",router)
    console.log("当前路由的信息",router.currentRoute.value)
    return {}
    }
})

二、Vue3使用嵌套路由实现同一按钮随着路由变化而变化

在这里插入图片描述
实现根据路由切换底下的信息
在这里插入图片描述
如果是Vue2 你可能会想这不就是 直接在路由中定义一个 mate 属性, 标签根据{{$router.xxx}} 直接响应就完事了吗 ?
只能说: 那雀食

可这是Vue3,并不能直接使用$router,只能通过引入router 来实现

------- router.js -----

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

const routes: Array<RouteRecordRaw> = [

  {
    path: '/',
    name: 'Index',
    redirect: '/index/home', // 使用重定向默认选中第一个子路由
    component: () => import(/* webpackChunkName: "index" */ '../views/Index.vue'),
    children: [
      {
        path: 'index/home',
        name: 'indexHome',
        meta: { title: '信息广场', toGo: {name:'发布信息',pathName:'/index/release'}},
        component: () => import(/* webpackChunkName: "index" */ '../views/home/home.vue')
      },
      {
        path: 'index/release',
        name: 'Release',
        meta: {title:'发布信息',toGo: {name:'信息广场',pathName:'/index/home'}},
        component: () => import(/* webpackChunkName: "index" */ '../views/home/release.vue')
      }
    ]
  }
]

const router = createRouter({
  history: createWebHashHistory(),
  routes
})

export default router

页面头部公共组件 核心片段

import { defineComponent, reactive, watch } from "vue"
import { useRouter } from "vue-router"

export default defineComponent({
  setup() {
    const router = useRouter()

    let btnObj = reactive({ ...router.currentRoute.value })

    watch(
      () => router.currentRoute.value,
      (newValue, oldValue) => {
        console.log("watch", newValue);
        btnObj.meta = newValue.meta;
      },
      { immediate: true }
    )

    const goRouter = (val: string) => {
      router.push(val);
    }

    return {
      goRouter,
      btnObj,
    }
  },
})

上面是正常能使用的写法

三、错误示范以及问题

import { defineComponent, reactive, watch } from "vue"
import { useRouter } from "vue-router"

export default defineComponent({
  setup() {
    const router = useRouter()

    let btnObj = reactive({ router.currentRoute.value })

    watch(
      () => router.currentRoute.value,
      (newValue, oldValue) => {
        console.log("watch", newValue);
        btnObj= newValue
      },
      { immediate: true }
    )

    return {
      btnObj
    }
  },
})

咋这么一看写惯了vue2的 可能诶 好像没什么毛病,需要添加成为响应式的 reactive 我也加了,后面监听到就把它替换一下就行,没毛病。
这个时候一运行你会发现,这怎么还报错了呢

let btnObj = reactive({ router.currentRoute.value });

说这一行不行,这时候你就会想怎么回事呢,虽然我也不能非常的标准化的说出错误,但是我猜测就几个 纯属自己猜想:因为router里面的本身就自带 reactive 或者其他的属性 / router的地址给了 btnObj 这就导致了 btnObj会影响到router 这是不行的。(这不就是一个深浅克隆嘛)
好了 这边用es6的结构赋值来

let btnObj = reactive({ ...router.currentRoute.value })

这就好了嘛,一运行,可以是可以 怎么没了反应呢?这里其实就要说到vue3的写法导致了

你原本的写法 在 data中直接写属性 就默认成响应式的,但是这里:

watch(
      () => router.currentRoute.value,
      (newValue, oldValue) => {
        console.log("watch", newValue);
        btnObj= newValue
      },
      { immediate: true }
    )

这里的 btnObj= newValue 相当于把一整个代理的过的btnObj 覆盖掉了 这就造成了 你的btnObj在标签上的值没办法响应式的改变,所以这里只能要改变 btnObj 里面的 mete对象就完全没问题。

四、Property ‘xxx‘ does not exist on type

这个是因为TS觉得你复制类型不存在 或者 你定义的类型不匹配、不符合要求导致的,可以使:
如:
vue2中的 this.xxx 可以直接给 this中添加一个xxx ,但是在Vue3的TS中 必须要先定义再用不然就会出现 检测不到该属性的情况

1.将对象类型设置为any

let _this: any = null;

2.使用as 断言

(_this as any).xxx = null;

  1. 最简单的就是 先定义再使用

let _this : number = 1
_this = _this + 1

4.使用字符获取对象属性

_this[“xxx”] = 1;

以上如有错误或其他方法,可在评论区探讨,探讨即可提高学习效率,respect!!!!!
在这里插入图片描述

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值