@@ -10,110 +10,116 @@ import { customEmit } from './customEvent';
10
10
* @param componentDefinition
11
11
* @param props
12
12
* @param options
13
+ * @returns {Promise } true if vue instance was created, false if instance already existed
13
14
*/
14
15
export default function createVueInstance ( element , Vue , componentDefinition , props , options ) {
15
- if ( ! element . __vue_custom_element__ ) {
16
- const ComponentDefinition = Vue . util . extend ( { } , componentDefinition ) ;
17
- const propsData = getPropsData ( element , ComponentDefinition , props ) ;
18
- const vueVersion = ( Vue . version && parseInt ( Vue . version . split ( '.' ) [ 0 ] , 10 ) ) || 0 ;
16
+ if ( element . __vue_custom_element__ ) {
17
+ return Promise . resolve ( element ) ;
18
+ }
19
+ const ComponentDefinition = Vue . util . extend ( { } , componentDefinition ) ;
20
+ const propsData = getPropsData ( element , ComponentDefinition , props ) ;
21
+ const vueVersion = ( Vue . version && parseInt ( Vue . version . split ( '.' ) [ 0 ] , 10 ) ) || 0 ;
19
22
20
- // Auto event handling based on $emit
21
- function beforeCreate ( ) { // eslint-disable-line no-inner-declarations
22
- this . $emit = function emit ( ...args ) {
23
- customEmit ( element , ...args ) ;
24
- this . __proto__ && this . __proto__ . $emit . call ( this , ...args ) ; // eslint-disable-line no-proto
25
- } ;
26
- }
27
- ComponentDefinition . beforeCreate = [ ] . concat ( ComponentDefinition . beforeCreate || [ ] , beforeCreate ) ;
23
+ // Auto event handling based on $emit
24
+ function beforeCreate ( ) { // eslint-disable-line no-inner-declarations
25
+ this . $emit = function emit ( ...args ) {
26
+ customEmit ( element , ...args ) ;
27
+ this . __proto__ && this . __proto__ . $emit . call ( this , ...args ) ; // eslint-disable-line no-proto
28
+ } ;
29
+ }
30
+ ComponentDefinition . beforeCreate = [ ] . concat ( ComponentDefinition . beforeCreate || [ ] , beforeCreate ) ;
28
31
29
- if ( ComponentDefinition . _compiled ) { // eslint-disable-line no-underscore-dangle
30
- let constructorOptions = { } ; // adjust vue-loader cache object if necessary - https://github.com/vuejs/vue-loader/issues/83
31
- const constructor = ComponentDefinition . _Ctor ; // eslint-disable-line no-underscore-dangle
32
- if ( constructor ) { // eslint-disable-line no-underscore-dangle
33
- constructorOptions = Object . keys ( constructor ) . map ( key => constructor [ key ] ) [ 0 ] . options ; // eslint-disable-line no-underscore-dangle
34
- }
35
- constructorOptions . beforeCreate = ComponentDefinition . beforeCreate ;
32
+ if ( ComponentDefinition . _compiled ) { // eslint-disable-line no-underscore-dangle
33
+ let constructorOptions = { } ; // adjust vue-loader cache object if necessary - https://github.com/vuejs/vue-loader/issues/83
34
+ const constructor = ComponentDefinition . _Ctor ; // eslint-disable-line no-underscore-dangle
35
+ if ( constructor ) { // eslint-disable-line no-underscore-dangle
36
+ constructorOptions = Object . keys ( constructor ) . map ( key => constructor [ key ] ) [ 0 ] . options ; // eslint-disable-line no-underscore-dangle
36
37
}
38
+ constructorOptions . beforeCreate = ComponentDefinition . beforeCreate ;
39
+ }
37
40
38
- let rootElement ;
39
-
40
- if ( vueVersion >= 2 ) {
41
- const elementOriginalChildren = element . cloneNode ( true ) . childNodes ; // clone hack due to IE compatibility
42
- // Vue 2+
43
- rootElement = {
44
- propsData,
45
- props : props . camelCase ,
46
- computed : {
47
- reactiveProps ( ) {
48
- const reactivePropsList = { } ;
49
- props . camelCase . forEach ( ( prop ) => {
50
- typeof this [ prop ] !== 'undefined' && ( reactivePropsList [ prop ] = this [ prop ] ) ;
51
- } ) ;
41
+ let rootElement ;
52
42
53
- return reactivePropsList ;
54
- }
55
- } ,
56
- /* eslint-disable */
57
- render ( createElement ) {
58
- const data = {
59
- props : this . reactiveProps
60
- } ;
43
+ if ( vueVersion >= 2 ) {
44
+ const elementOriginalChildren = element . cloneNode ( true ) . childNodes ; // clone hack due to IE compatibility
45
+ // Vue 2+
46
+ rootElement = {
47
+ propsData,
48
+ props : props . camelCase ,
49
+ computed : {
50
+ reactiveProps ( ) {
51
+ const reactivePropsList = { } ;
52
+ props . camelCase . forEach ( ( prop ) => {
53
+ typeof this [ prop ] !== 'undefined' && ( reactivePropsList [ prop ] = this [ prop ] ) ;
54
+ } ) ;
61
55
62
- return createElement (
63
- ComponentDefinition ,
64
- data ,
65
- getSlots ( elementOriginalChildren , createElement )
66
- ) ;
56
+ return reactivePropsList ;
67
57
}
68
- /* eslint-enable */
69
- } ;
70
- } else if ( vueVersion === 1 ) {
71
- // Fallback for Vue 1.x
72
- rootElement = ComponentDefinition ;
73
- rootElement . propsData = propsData ;
74
- } else {
75
- // Fallback for older Vue versions
76
- rootElement = ComponentDefinition ;
77
- const propsWithDefault = { } ;
78
- Object . keys ( propsData )
79
- . forEach ( ( prop ) => {
80
- propsWithDefault [ prop ] = { default : propsData [ prop ] } ;
81
- } ) ;
82
- rootElement . props = propsWithDefault ;
83
- }
58
+ } ,
59
+ /* eslint-disable */
60
+ render ( createElement ) {
61
+ const data = {
62
+ props : this . reactiveProps
63
+ } ;
84
64
85
- const elementInnerHtml = vueVersion >= 2 ? '<div></div>' : `<div>${ element . innerHTML } </div>` . replace ( / v u e - s l o t = / g, 'slot=' ) ;
86
- if ( options . shadow && element . shadowRoot ) {
87
- element . shadowRoot . innerHTML = elementInnerHtml ;
88
- rootElement . el = element . shadowRoot . children [ 0 ] ;
89
- } else {
90
- element . innerHTML = elementInnerHtml ;
91
- rootElement . el = element . children [ 0 ] ;
92
- }
65
+ return createElement (
66
+ ComponentDefinition ,
67
+ data ,
68
+ getSlots ( elementOriginalChildren , createElement )
69
+ ) ;
70
+ }
71
+ /* eslint-enable */
72
+ } ;
73
+ } else if ( vueVersion === 1 ) {
74
+ // Fallback for Vue 1.x
75
+ rootElement = ComponentDefinition ;
76
+ rootElement . propsData = propsData ;
77
+ } else {
78
+ // Fallback for older Vue versions
79
+ rootElement = ComponentDefinition ;
80
+ const propsWithDefault = { } ;
81
+ Object . keys ( propsData )
82
+ . forEach ( ( prop ) => {
83
+ propsWithDefault [ prop ] = { default : propsData [ prop ] } ;
84
+ } ) ;
85
+ rootElement . props = propsWithDefault ;
86
+ }
93
87
94
- reactiveProps ( element , props ) ;
88
+ const elementInnerHtml = vueVersion >= 2 ? '<div></div>' : `<div>${ element . innerHTML } </div>` . replace ( / v u e - s l o t = / g, 'slot=' ) ;
89
+ if ( options . shadow && element . shadowRoot ) {
90
+ element . shadowRoot . innerHTML = elementInnerHtml ;
91
+ rootElement . el = element . shadowRoot . children [ 0 ] ;
92
+ } else {
93
+ element . innerHTML = elementInnerHtml ;
94
+ rootElement . el = element . children [ 0 ] ;
95
+ }
95
96
96
- if ( typeof options . beforeCreateVueInstance === 'function' ) {
97
- rootElement = options . beforeCreateVueInstance ( rootElement ) || rootElement ;
98
- }
97
+ if ( options . shadow && options . shadowCss && element . shadowRoot ) {
98
+ const style = document . createElement ( 'style' ) ;
99
+ style . type = 'text/css' ;
100
+ style . appendChild ( document . createTextNode ( options . shadowCss ) ) ;
101
+
102
+ element . shadowRoot . appendChild ( style ) ;
103
+ }
104
+
105
+ reactiveProps ( element , props ) ;
99
106
107
+ if ( typeof options . beforeCreateVueInstance === 'function' ) {
108
+ rootElement = options . beforeCreateVueInstance ( rootElement ) || rootElement ;
109
+ }
110
+
111
+ return Promise . resolve ( rootElement ) . then ( ( vueOpts ) => {
100
112
// Define the Vue constructor to manage the element
101
- element . __vue_custom_element__ = new Vue ( rootElement ) ;
113
+ element . __vue_custom_element__ = new Vue ( vueOpts ) ;
102
114
element . __vue_custom_element_props__ = props ;
103
115
element . getVueInstance = ( ) => {
104
116
const vueInstance = element . __vue_custom_element__ ;
105
117
return vueInstance . $children . length ? vueInstance . $children [ 0 ] : vueInstance ;
106
118
} ;
107
119
108
- if ( options . shadow && options . shadowCss && element . shadowRoot ) {
109
- const style = document . createElement ( 'style' ) ;
110
- style . type = 'text/css' ;
111
- style . appendChild ( document . createTextNode ( options . shadowCss ) ) ;
112
-
113
- element . shadowRoot . appendChild ( style ) ;
114
- }
115
120
element . removeAttribute ( 'vce-cloak' ) ;
116
121
element . setAttribute ( 'vce-ready' , '' ) ;
117
122
customEmit ( element , 'vce-ready' ) ;
118
- }
123
+ return element ;
124
+ } ) ;
119
125
}
0 commit comments