Vue3 使用嵌套路由、以及遇到的 Property ‘xxx‘ does not exist on type
Vue3 与 vue2 Router中的使用,以及 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;
- 最简单的就是 先定义再使用
let _this : number = 1
_this = _this + 1
4.使用字符获取对象属性
_this[“xxx”] = 1;
以上如有错误或其他方法,可在评论区探讨,探讨即可提高学习效率,respect!!!!!
更多推荐
所有评论(0)