mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-16 01:52:19 +08:00
fix(vue): pass router-link value to href to properly render clickable elements (#29745)
Issue number: N/A --------- ## What is the current behavior? Ionic Framework Vue components using `router-link` do not apply an `href` property which causes components to render `div` or `button` elements when they should render an `a`. This is inconsistent with the way Angular and Vue handle router link. ## What is the new behavior? Updates `@stencil/vue-output-target` to latest which adds the code from the following PR: https://github.com/ionic-team/stencil-ds-output-targets/pull/446 The update in vue output target checks if `router-link` and `navManager` are defined so this fix only applies to Ionic Framework components. If both are defined then it adds the `href` property to the element with the value of `router-link`. ## Does this introduce a breaking change? - [ ] Yes - [x] No ## Other information Dev build: `8.2.7-dev.11722629362.1ac136c4`
This commit is contained in:
@ -91,8 +91,17 @@ export const defineContainer = <Props, VModelType = string | number | boolean>(
|
||||
const eventsNames = Array.isArray(modelUpdateEvent) ? modelUpdateEvent : [modelUpdateEvent];
|
||||
eventsNames.forEach((eventName: string) => {
|
||||
el.addEventListener(eventName.toLowerCase(), (e: Event) => {
|
||||
modelPropValue = (e?.target as any)[modelProp];
|
||||
emit(UPDATE_VALUE_EVENT, modelPropValue);
|
||||
/**
|
||||
* Only update the v-model binding if the event's target is the element we are
|
||||
* listening on. For example, Component A could emit ionChange, but it could also
|
||||
* have a descendant Component B that also emits ionChange. We only want to update
|
||||
* the v-model for Component A when ionChange originates from that element and not
|
||||
* when ionChange bubbles up from Component B.
|
||||
*/
|
||||
if (e.target.tagName === el.tagName) {
|
||||
modelPropValue = (e?.target as any)[modelProp];
|
||||
emit(UPDATE_VALUE_EVENT, modelPropValue);
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
@ -106,6 +115,16 @@ export const defineContainer = <Props, VModelType = string | number | boolean>(
|
||||
if (routerLink === EMPTY_PROP) return;
|
||||
|
||||
if (navManager !== undefined) {
|
||||
/**
|
||||
* This prevents the browser from
|
||||
* performing a page reload when pressing
|
||||
* an Ionic component with routerLink.
|
||||
* The page reload interferes with routing
|
||||
* and causes ion-back-button to disappear
|
||||
* since the local history is wiped on reload.
|
||||
*/
|
||||
ev.preventDefault();
|
||||
|
||||
let navigationPayload: any = { event: ev };
|
||||
for (const key in props) {
|
||||
const value = props[key];
|
||||
@ -176,6 +195,17 @@ export const defineContainer = <Props, VModelType = string | number | boolean>(
|
||||
}
|
||||
}
|
||||
|
||||
// If router link is defined, add href to props
|
||||
// in order to properly render an anchor tag inside
|
||||
// of components that should become activatable and
|
||||
// focusable with router link.
|
||||
if (props[ROUTER_LINK_VALUE] !== EMPTY_PROP) {
|
||||
propsToAdd = {
|
||||
...propsToAdd,
|
||||
href: props[ROUTER_LINK_VALUE],
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* vModelDirective is only needed on components that support v-model.
|
||||
* As a result, we conditionally call withDirectives with v-model components.
|
||||
|
Reference in New Issue
Block a user