mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-16 10:01:59 +08:00
fix(vue): all ionic vue components can now use router link (#22743)
This commit is contained in:
19
core/package-lock.json
generated
19
core/package-lock.json
generated
@ -17,7 +17,7 @@
|
|||||||
"@rollup/plugin-virtual": "^2.0.3",
|
"@rollup/plugin-virtual": "^2.0.3",
|
||||||
"@stencil/core": "2.1.2",
|
"@stencil/core": "2.1.2",
|
||||||
"@stencil/sass": "1.3.2",
|
"@stencil/sass": "1.3.2",
|
||||||
"@stencil/vue-output-target": "0.2.2",
|
"@stencil/vue-output-target": "0.2.3",
|
||||||
"@types/jest": "^26.0.10",
|
"@types/jest": "^26.0.10",
|
||||||
"@types/node": "^14.6.0",
|
"@types/node": "^14.6.0",
|
||||||
"@types/puppeteer": "3.0.1",
|
"@types/puppeteer": "3.0.1",
|
||||||
@ -1657,10 +1657,13 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/@stencil/vue-output-target": {
|
"node_modules/@stencil/vue-output-target": {
|
||||||
"version": "0.2.2",
|
"version": "0.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/@stencil/vue-output-target/-/vue-output-target-0.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/@stencil/vue-output-target/-/vue-output-target-0.2.3.tgz",
|
||||||
"integrity": "sha512-WBnN/8ggIVYgKbJOML1DVzjFnKv7RaQpTa+XNeY0r/EG6MbXlUjUC/4Cpkg5wQ94WNuPpphAR4oRWGsmiQDxPQ==",
|
"integrity": "sha512-jxFElPUVp56DHxLvYTvlnHMFnVQ0ITAUCLYfHvV8TY49PUbV5Gw1nYhhJQfpi5gJU2PPoWtIJjUGMsof8lmh6Q==",
|
||||||
"dev": true
|
"dev": true,
|
||||||
|
"peerDependencies": {
|
||||||
|
"@stencil/core": ">=1.8.0"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@stylelint/postcss-css-in-js": {
|
"node_modules/@stylelint/postcss-css-in-js": {
|
||||||
"version": "0.37.2",
|
"version": "0.37.2",
|
||||||
@ -16387,9 +16390,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"@stencil/vue-output-target": {
|
"@stencil/vue-output-target": {
|
||||||
"version": "0.2.2",
|
"version": "0.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/@stencil/vue-output-target/-/vue-output-target-0.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/@stencil/vue-output-target/-/vue-output-target-0.2.3.tgz",
|
||||||
"integrity": "sha512-WBnN/8ggIVYgKbJOML1DVzjFnKv7RaQpTa+XNeY0r/EG6MbXlUjUC/4Cpkg5wQ94WNuPpphAR4oRWGsmiQDxPQ==",
|
"integrity": "sha512-jxFElPUVp56DHxLvYTvlnHMFnVQ0ITAUCLYfHvV8TY49PUbV5Gw1nYhhJQfpi5gJU2PPoWtIJjUGMsof8lmh6Q==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"@stylelint/postcss-css-in-js": {
|
"@stylelint/postcss-css-in-js": {
|
||||||
|
@ -38,7 +38,7 @@
|
|||||||
"@rollup/plugin-virtual": "^2.0.3",
|
"@rollup/plugin-virtual": "^2.0.3",
|
||||||
"@stencil/core": "2.1.2",
|
"@stencil/core": "2.1.2",
|
||||||
"@stencil/sass": "1.3.2",
|
"@stencil/sass": "1.3.2",
|
||||||
"@stencil/vue-output-target": "0.2.2",
|
"@stencil/vue-output-target": "0.2.3",
|
||||||
"@types/jest": "^26.0.10",
|
"@types/jest": "^26.0.10",
|
||||||
"@types/node": "^14.6.0",
|
"@types/node": "^14.6.0",
|
||||||
"@types/puppeteer": "3.0.1",
|
"@types/puppeteer": "3.0.1",
|
||||||
|
@ -87,13 +87,6 @@ export const config: Config = {
|
|||||||
'ion-app',
|
'ion-app',
|
||||||
'ion-icon'
|
'ion-icon'
|
||||||
],
|
],
|
||||||
routerLinkComponents: [
|
|
||||||
'ion-card',
|
|
||||||
'ion-item',
|
|
||||||
'ion-button',
|
|
||||||
'ion-fab-button',
|
|
||||||
|
|
||||||
],
|
|
||||||
componentModels: [
|
componentModels: [
|
||||||
{
|
{
|
||||||
elements: ['ion-checkbox', 'ion-toggle'],
|
elements: ['ion-checkbox', 'ion-toggle'],
|
||||||
|
@ -42,10 +42,7 @@ export const IonButton = /*@__PURE__*/ defineContainer<JSX.IonButton>('ion-butto
|
|||||||
'type',
|
'type',
|
||||||
'ionFocus',
|
'ionFocus',
|
||||||
'ionBlur'
|
'ionBlur'
|
||||||
],
|
]);
|
||||||
{
|
|
||||||
"routerLinkComponent": true
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
export const IonButtons = /*@__PURE__*/ defineContainer<JSX.IonButtons>('ion-buttons', [
|
export const IonButtons = /*@__PURE__*/ defineContainer<JSX.IonButtons>('ion-buttons', [
|
||||||
@ -64,10 +61,7 @@ export const IonCard = /*@__PURE__*/ defineContainer<JSX.IonCard>('ion-card', [
|
|||||||
'routerDirection',
|
'routerDirection',
|
||||||
'routerAnimation',
|
'routerAnimation',
|
||||||
'target'
|
'target'
|
||||||
],
|
]);
|
||||||
{
|
|
||||||
"routerLinkComponent": true
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
export const IonCardContent = /*@__PURE__*/ defineContainer<JSX.IonCardContent>('ion-card-content');
|
export const IonCardContent = /*@__PURE__*/ defineContainer<JSX.IonCardContent>('ion-card-content');
|
||||||
@ -195,10 +189,7 @@ export const IonFab = /*@__PURE__*/ defineContainer<JSX.IonFab>('ion-fab', [
|
|||||||
'vertical',
|
'vertical',
|
||||||
'edge',
|
'edge',
|
||||||
'activated'
|
'activated'
|
||||||
],
|
]);
|
||||||
{
|
|
||||||
"routerLinkComponent": true
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
export const IonFabButton = /*@__PURE__*/ defineContainer<JSX.IonFabButton>('ion-fab-button', [
|
export const IonFabButton = /*@__PURE__*/ defineContainer<JSX.IonFabButton>('ion-fab-button', [
|
||||||
@ -218,10 +209,7 @@ export const IonFabButton = /*@__PURE__*/ defineContainer<JSX.IonFabButton>('ion
|
|||||||
'closeIcon',
|
'closeIcon',
|
||||||
'ionFocus',
|
'ionFocus',
|
||||||
'ionBlur'
|
'ionBlur'
|
||||||
],
|
]);
|
||||||
{
|
|
||||||
"routerLinkComponent": true
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
export const IonFabList = /*@__PURE__*/ defineContainer<JSX.IonFabList>('ion-fab-list', [
|
export const IonFabList = /*@__PURE__*/ defineContainer<JSX.IonFabList>('ion-fab-list', [
|
||||||
@ -324,10 +312,7 @@ export const IonItem = /*@__PURE__*/ defineContainer<JSX.IonItem>('ion-item', [
|
|||||||
'routerDirection',
|
'routerDirection',
|
||||||
'target',
|
'target',
|
||||||
'type'
|
'type'
|
||||||
],
|
]);
|
||||||
{
|
|
||||||
"routerLinkComponent": true
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
export const IonItemDivider = /*@__PURE__*/ defineContainer<JSX.IonItemDivider>('ion-item-divider', [
|
export const IonItemDivider = /*@__PURE__*/ defineContainer<JSX.IonItemDivider>('ion-item-divider', [
|
||||||
|
@ -17,7 +17,6 @@ interface NavManager<T = any> {
|
|||||||
interface ComponentOptions {
|
interface ComponentOptions {
|
||||||
modelProp?: string;
|
modelProp?: string;
|
||||||
modelUpdateEvent?: string;
|
modelUpdateEvent?: string;
|
||||||
routerLinkComponent?: boolean;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const getComponentClasses = (classes: unknown) => {
|
const getComponentClasses = (classes: unknown) => {
|
||||||
@ -41,7 +40,7 @@ const getElementClasses = (ref: Ref<HTMLElement | undefined>, componentClasses:
|
|||||||
* integrations.
|
* integrations.
|
||||||
*/
|
*/
|
||||||
export const defineContainer = <Props>(name: string, componentProps: string[] = [], componentOptions: ComponentOptions = {}) => {
|
export const defineContainer = <Props>(name: string, componentProps: string[] = [], componentOptions: ComponentOptions = {}) => {
|
||||||
const { modelProp, modelUpdateEvent, routerLinkComponent } = componentOptions;
|
const { modelProp, modelUpdateEvent } = componentOptions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a Vue component wrapper around a Web Component.
|
* Create a Vue component wrapper around a Web Component.
|
||||||
@ -60,24 +59,23 @@ export const defineContainer = <Props>(name: string, componentProps: string[] =
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let handleClick: (ev: Event) => void;
|
const currentInstance = getCurrentInstance();
|
||||||
if (routerLinkComponent) {
|
const hasRouter = currentInstance?.appContext?.provides[NAV_MANAGER];
|
||||||
const currentInstance = getCurrentInstance();
|
const navManager: NavManager | undefined = hasRouter ? inject(NAV_MANAGER) : undefined;
|
||||||
const hasRouter = currentInstance?.appContext?.provides[NAV_MANAGER];
|
const handleRouterLink = (ev: Event) => {
|
||||||
const navManager: NavManager | undefined = hasRouter ? inject(NAV_MANAGER) : undefined;
|
const { routerLink } = props as any;
|
||||||
handleClick = (ev: Event) => {
|
if (!routerLink) return;
|
||||||
const routerProps = Object.keys(props).filter(p => p.startsWith(ROUTER_PROP_REFIX));
|
|
||||||
if (routerProps.length === 0) return;
|
|
||||||
|
|
||||||
if (navManager !== undefined) {
|
const routerProps = Object.keys(props).filter(p => p.startsWith(ROUTER_PROP_REFIX));
|
||||||
let navigationPayload: any = { event: ev };
|
|
||||||
routerProps.forEach(prop => {
|
if (navManager !== undefined) {
|
||||||
navigationPayload[prop] = (props as any)[prop];
|
let navigationPayload: any = { event: ev };
|
||||||
});
|
routerProps.forEach(prop => {
|
||||||
navManager.navigate(navigationPayload);
|
navigationPayload[prop] = (props as any)[prop];
|
||||||
} else {
|
});
|
||||||
console.warn('Tried to navigate, but no router was found. Make sure you have mounted Vue Router.');
|
navManager.navigate(navigationPayload);
|
||||||
}
|
} else {
|
||||||
|
console.warn('Tried to navigate, but no router was found. Make sure you have mounted Vue Router.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,24 +84,24 @@ export const defineContainer = <Props>(name: string, componentProps: string[] =
|
|||||||
classes.add(value);
|
classes.add(value);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const oldClick = (props as any).onClick;
|
||||||
|
const handleClick = (ev: Event) => {
|
||||||
|
if (oldClick !== undefined) {
|
||||||
|
oldClick(ev);
|
||||||
|
}
|
||||||
|
if (!ev.defaultPrevented) {
|
||||||
|
handleRouterLink(ev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let propsToAdd = {
|
let propsToAdd = {
|
||||||
...props,
|
...props,
|
||||||
ref: containerRef,
|
ref: containerRef,
|
||||||
class: getElementClasses(containerRef, classes),
|
class: getElementClasses(containerRef, classes),
|
||||||
onClick: (routerLinkComponent) ? handleClick : (props as any).onClick,
|
onClick: handleClick,
|
||||||
onVnodeBeforeMount: (modelUpdateEvent) ? onVnodeBeforeMount : undefined
|
onVnodeBeforeMount: (modelUpdateEvent) ? onVnodeBeforeMount : undefined
|
||||||
};
|
};
|
||||||
|
|
||||||
if ((props as any).onClick) {
|
|
||||||
const oldClick = (props as any).onClick;
|
|
||||||
propsToAdd.onClick = (ev: Event) => {
|
|
||||||
oldClick(ev);
|
|
||||||
if (!ev.defaultPrevented) {
|
|
||||||
handleClick(ev);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (modelProp) {
|
if (modelProp) {
|
||||||
propsToAdd = {
|
propsToAdd = {
|
||||||
...propsToAdd,
|
...propsToAdd,
|
||||||
@ -116,14 +114,11 @@ export const defineContainer = <Props>(name: string, componentProps: string[] =
|
|||||||
});
|
});
|
||||||
|
|
||||||
Container.displayName = name;
|
Container.displayName = name;
|
||||||
Container.props = componentProps;
|
Container.props = [...componentProps, ROUTER_LINK_VALUE];
|
||||||
if (modelProp) {
|
if (modelProp) {
|
||||||
Container.props.push(MODEL_VALUE);
|
Container.props.push(MODEL_VALUE);
|
||||||
Container.emits = [UPDATE_VALUE_EVENT];
|
Container.emits = [UPDATE_VALUE_EVENT];
|
||||||
}
|
}
|
||||||
if (routerLinkComponent) {
|
|
||||||
Container.props.push(ROUTER_LINK_VALUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Container;
|
return Container;
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user