search: Prepare for Vue 3 migration
Port the initialization code for the Vue search to use Vue.createMwApp() instead of new Vue( ... ). The former mimicks Vue 3's API for mounting components. Without this change, this code breaks in Vue 3 (even in compatibility mode) because the compat support for new Vue(...) is imperfect. By the time renderFn is called, the searchForm container has already been emptied by Vue's internal mounting code. Instead, inspect searchForm and generate the prop list before mounting, then pass the props to createMwApp() and mount the component. Bug: T294476 Depends-On: I1fcdcf7bf87f5af2deb9763a231f2c360ea45b23 Change-Id: I5b6e66051d97e75f8f03b8258894daba22525797
This commit is contained in:
parent
04ff34bd0c
commit
5dee570cb2
|
@ -1,17 +1,15 @@
|
|||
/** @module search */
|
||||
|
||||
var
|
||||
Vue = require( 'vue' ).default || require( 'vue' ),
|
||||
App = require( './App.vue' ),
|
||||
config = require( './config.json' );
|
||||
|
||||
/**
|
||||
* @param {Function} createElement
|
||||
* @param {Element} searchForm
|
||||
* @return {Vue.VNode}
|
||||
* @throws {Error} if the searchForm does not
|
||||
* contain input[name=title] and input[name="search"] elements.
|
||||
* @return {void}
|
||||
*/
|
||||
function renderFn( createElement, searchForm ) {
|
||||
function initApp( searchForm ) {
|
||||
var
|
||||
titleInput = /** @type {HTMLInputElement|null} */ (
|
||||
searchForm.querySelector( 'input[name=title]' )
|
||||
|
@ -23,8 +21,9 @@ function renderFn( createElement, searchForm ) {
|
|||
throw new Error( 'Attempted to create Vue search element from an incompatible element.' );
|
||||
}
|
||||
|
||||
return createElement( App, {
|
||||
props: $.extend( {
|
||||
// @ts-ignore
|
||||
Vue.createMwApp(
|
||||
App, $.extend( {
|
||||
id: searchForm.id,
|
||||
autofocusInput: search === document.activeElement,
|
||||
action: searchForm.getAttribute( 'action' ),
|
||||
|
@ -33,27 +32,10 @@ function renderFn( createElement, searchForm ) {
|
|||
searchTitle: search.getAttribute( 'title' ),
|
||||
searchPlaceholder: search.getAttribute( 'placeholder' ),
|
||||
searchQuery: search.value
|
||||
},
|
||||
// Pass additional config from server.
|
||||
config
|
||||
)
|
||||
} );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {NodeList} searchForms
|
||||
* @return {void}
|
||||
*/
|
||||
function initApp( searchForms ) {
|
||||
searchForms.forEach( function ( searchForm ) {
|
||||
// eslint-disable-next-line no-new
|
||||
new Vue( {
|
||||
el: /** @type {Element} */ ( searchForm ),
|
||||
render: function ( createElement ) {
|
||||
return renderFn( createElement, /** @type {Element} */ ( searchForm ) );
|
||||
}
|
||||
} );
|
||||
} );
|
||||
}, config )
|
||||
)
|
||||
.mount( searchForm );
|
||||
}
|
||||
/**
|
||||
* @param {Document} document
|
||||
|
@ -63,6 +45,8 @@ function main( document ) {
|
|||
var
|
||||
searchForms = document.querySelectorAll( '.vector-search-box-form' );
|
||||
|
||||
initApp( searchForms );
|
||||
searchForms.forEach( function ( searchForm ) {
|
||||
initApp( searchForm );
|
||||
} );
|
||||
}
|
||||
main( document );
|
||||
|
|
Loading…
Reference in New Issue