vue-router 插件替代方案。像 vue-router 一样,我有两个组件 RouterLink
和
RouterView
以及一些路由表。单击
RouterLink
会使插件使用查找表来查找要渲染的新组件,该组件由
ViewRouter
渲染。我实现它的方式,
ViewRouter
有一个
ref
它应该渲染的组件,由插件中间件更新。问题是,即使调用
render()
组件的
ViewRouter
并且组件 ref 具有新值,实际呈现给浏览器的内容也不会改变。就像 Vue 运行时决定不需要重新渲染一样。我做错了什么?怎么解决?示例代码:
import { type App, type Component, defineComponent, h, type PropType, shallowRef, ref } from 'vue';
import HomeView from './HomeView.vue';
import AboutView from './AboutView.vue';
const routes = [
{
path: '/',
name: 'home',
component: HomeView
},
{
path: '/about',
name: 'about',
component: AboutView,
}
];
const currentComponent = shallowRef<Component>(() => h('div', h('h1', 'Default')));
export function createRouter() {
return (app: App) => {
app.component('router-link', RouterLink);
app.component('router-view', RouterView);
};
}
function matchTo(to: string) {
for(const route of routes) {
if(route.path === to) {
return route;
}
}
}
function setTo(to: string) {
const route = matchTo(to);
console.log('setComponentTo', to, route);
if(!route) return;
currentComponent.value = route.component;
}
export const RouterLink = defineComponent({
name: 'RouterLink',
props: {
to: {
type: String as PropType<string>,
required: true,
},
},
setup(props, { slots }) {
const click = () => {
setTo(props.to);
};
return () => {
return h(
'a',
{
onClick: click,
},
slots.default && slots.default()
);
};
},
});
export const RouterView = defineComponent({
name: 'RouterView',
setup() {
const view = currentComponent.value ? h(currentComponent.value) : [];
return () => {
console.log('View render', (currentComponent.value as any).__file);
return h('div', [view]);
};
}
});
if
的线路中失去反应性。我不太明白它的含义,但是如果你将
h(currentComponent.value)
直接传递给
h
,代码就会开始工作。这是我的 RouterView 版本:
export const RouterView = defineComponent({
name: 'RouterView',
setup() {
return () => {
console.log('View render', (currentComponent.value as any).__file);
return h('div', [h(currentComponent.value), counter.value]);
};
}
});
或者三元结构必须是 computed
...