Skip to content

Commit 40a3920

Browse files
committed
Revert Vue in DevDependencies, improve CSR\SSR support
1 parent bec1857 commit 40a3920

File tree

3 files changed

+56
-26
lines changed

3 files changed

+56
-26
lines changed

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "vue-component-media-queries",
3-
"version": "1.0.0-alpha.5",
3+
"version": "1.0.0-alpha.6",
44
"description": "Component-based media query matcher for Vue",
55
"main": "dist/index.js",
66
"module": "dist/index.es.js",
@@ -33,7 +33,8 @@
3333
"rollup-plugin-terser": "^5.1.3",
3434
"rollup-plugin-typescript2": "^0.25.3",
3535
"tslib": "^1.10.0",
36-
"typescript": "^3.7.4"
36+
"typescript": "^3.7.4",
37+
"vue": "^2.6.0"
3738
},
3839
"peerDependencies": {
3940
"vue": "^2.6.0"

src/MatchMedia.ts

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1-
import Vue, { PropType } from 'vue';
1+
import Vue, { PropType, VNode } from 'vue';
22
import { MediaQueriesProvision } from './MediaQueryProvider'
33
import { renderWrappedNodes } from "./utils";
44

55
type SlotProps = { matches: boolean } | MediaQueriesProvision
66
type Data = {
77
matches: boolean,
88
matcher: null | MediaQueryList,
9-
mediaQueries?: null | MediaQueriesProvision
9+
mediaQueries?: null | MediaQueriesProvision,
10+
$nuxt?: any
1011
}
1112

1213
export const MatchMedia = Vue.extend({
@@ -26,6 +27,9 @@ export const MatchMedia = Vue.extend({
2627
wrapperTag: {
2728
type: String as PropType<string>,
2829
default: 'span'
30+
},
31+
ssr: {
32+
type: Boolean as PropType<boolean>,
2933
}
3034
},
3135
data(): Data {
@@ -34,11 +38,14 @@ export const MatchMedia = Vue.extend({
3438
matches: this.fallback,
3539
};
3640
},
41+
beforeMount() {
42+
if (!this.ssr && !this.$nuxt) {
43+
this.bootstrap();
44+
}
45+
},
3746
mounted() {
38-
if (this.query) {
39-
const matcher = this.matcher = window.matchMedia(this.query);
40-
matcher.addListener(this.onMedia);
41-
this.matches = matcher.matches;
47+
if (this.ssr || this.$nuxt) {
48+
this.bootstrap();
4249
}
4350
},
4451
beforeDestroy() {
@@ -48,6 +55,13 @@ export const MatchMedia = Vue.extend({
4855
}
4956
},
5057
methods: {
58+
bootstrap() {
59+
if (this.query) {
60+
const matcher = this.matcher = window.matchMedia(this.query);
61+
matcher.addListener(this.onMedia);
62+
this.matches = matcher.matches;
63+
}
64+
},
5165
onMedia(event: MediaQueryListEvent) {
5266
this.matches = event.matches;
5367
},
@@ -66,7 +80,7 @@ export const MatchMedia = Vue.extend({
6680
return this.mediaQueries as MediaQueriesProvision;
6781
},
6882
},
69-
render(h): any {
83+
render(h): VNode {
7084
return renderWrappedNodes(h, this.$scopedSlots.default!(this.slotProps)!, this.wrapperTag);
7185
},
7286
});

src/MediaQueryProvider.ts

Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1-
import Vue, { PropType } from 'vue';
1+
import Vue, { PropType, VNode } from 'vue';
22
import { renderWrappedNodes } from "./utils";
33

44
type MediaQueriesConfig = Record<string, string>;
55
type MediaEventListener = () => void;
66
type Fallback = string | string[];
77
type Data = {
88
mediaQueries: MediaQueriesProvision,
9-
matchers: [MediaQueryList, MediaEventListener][]
9+
matchers: [MediaQueryList, MediaEventListener][],
10+
$nuxt?: any
1011
}
1112

1213
export type MediaQueriesProvision = Record<string, boolean>;
@@ -23,6 +24,9 @@ export const MediaQueryProvider = Vue.extend({
2324
type: String as PropType<string>,
2425
default: 'span'
2526
},
27+
ssr: {
28+
type: Boolean as PropType<boolean>,
29+
},
2630
},
2731
provide(): { mediaQueries: MediaQueriesProvision } {
2832
return { mediaQueries: this.mediaQueries };
@@ -43,21 +47,14 @@ export const MediaQueryProvider = Vue.extend({
4347

4448
return { mediaQueries, matchers: [] };
4549
},
46-
// Matching on mounted to avoid hydration errors
50+
beforeMount() {
51+
if (!this.ssr && !this.$nuxt) {
52+
this.bootstrap();
53+
}
54+
},
4755
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();
6158
}
6259
},
6360
beforeDestroy() {
@@ -66,7 +63,25 @@ export const MediaQueryProvider = Vue.extend({
6663
});
6764
delete this.matchers;
6865
},
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 {
7085
return renderWrappedNodes(h, this.$slots.default!, this.wrapperTag);
7186
}
7287
});

0 commit comments

Comments
 (0)