1
- import Vue , { PropType } from 'vue' ;
1
+ import Vue , { PropType , VNode } from 'vue' ;
2
2
import { renderWrappedNodes } from "./utils" ;
3
3
4
4
type MediaQueriesConfig = Record < string , string > ;
5
5
type MediaEventListener = ( ) => void ;
6
6
type Fallback = string | string [ ] ;
7
7
type Data = {
8
8
mediaQueries : MediaQueriesProvision ,
9
- matchers : [ MediaQueryList , MediaEventListener ] [ ]
9
+ matchers : [ MediaQueryList , MediaEventListener ] [ ] ,
10
+ $nuxt ?: any
10
11
}
11
12
12
13
export type MediaQueriesProvision = Record < string , boolean > ;
@@ -23,6 +24,9 @@ export const MediaQueryProvider = Vue.extend({
23
24
type : String as PropType < string > ,
24
25
default : 'span'
25
26
} ,
27
+ ssr : {
28
+ type : Boolean as PropType < boolean > ,
29
+ } ,
26
30
} ,
27
31
provide ( ) : { mediaQueries : MediaQueriesProvision } {
28
32
return { mediaQueries : this . mediaQueries } ;
@@ -43,21 +47,14 @@ export const MediaQueryProvider = Vue.extend({
43
47
44
48
return { mediaQueries, matchers : [ ] } ;
45
49
} ,
46
- // Matching on mounted to avoid hydration errors
50
+ beforeMount ( ) {
51
+ if ( ! this . ssr && ! this . $nuxt ) {
52
+ this . bootstrap ( ) ;
53
+ }
54
+ } ,
47
55
mounted ( ) {
48
- const { queries, mediaQueries } = this ;
49
-
50
- for ( const key in queries ) {
51
- const query = queries [ key ] ;
52
-
53
- const matcher = window . matchMedia ( query ) ;
54
- const handler = ( event : MediaQueryListEvent ) => {
55
- Vue . set ( mediaQueries , key , event . matches ) ;
56
- } ;
57
- // using deprecated method because of Safari's poor support for addEventListener
58
- matcher . addListener ( handler ) ;
59
- Vue . set ( mediaQueries , key , matcher . matches ) ;
60
- this . matchers . push ( [ matcher , handler as MediaEventListener ] ) ;
56
+ if ( this . ssr || this . $nuxt ) {
57
+ this . bootstrap ( ) ;
61
58
}
62
59
} ,
63
60
beforeDestroy ( ) {
@@ -66,7 +63,25 @@ export const MediaQueryProvider = Vue.extend({
66
63
} ) ;
67
64
delete this . matchers ;
68
65
} ,
69
- render ( h ) : any {
66
+ methods : {
67
+ bootstrap ( ) {
68
+ const { queries, mediaQueries } = this ;
69
+
70
+ for ( const key in queries ) {
71
+ const query = queries [ key ] ;
72
+
73
+ const matcher = window . matchMedia ( query ) ;
74
+ const handler = ( event : MediaQueryListEvent ) => {
75
+ Vue . set ( mediaQueries , key , event . matches ) ;
76
+ } ;
77
+ // using deprecated method because of Safari's poor support for addEventListener
78
+ matcher . addListener ( handler ) ;
79
+ Vue . set ( mediaQueries , key , matcher . matches ) ;
80
+ this . matchers . push ( [ matcher , handler as MediaEventListener ] ) ;
81
+ }
82
+ } ,
83
+ } ,
84
+ render ( h ) : VNode {
70
85
return renderWrappedNodes ( h , this . $slots . default ! , this . wrapperTag ) ;
71
86
}
72
87
} ) ;
0 commit comments