1.2.1 • Published 3 years ago

vuex-viewport v1.2.1

Weekly downloads
12
License
MIT
Repository
github
Last release
3 years ago

vuex-viewport

npm GitHub license package hits Vuex extension that allows making window size as computed property.

NOTE: If you use Vue 3, Vuex 4 and TypeScript, see the section below.

Requirement

  • Vuex 2.3.0+ (up to 4.x)

Installation

CDN

<script src="https://cdn.jsdelivr.net/npm/vuex-viewport@1.2.1/dist/vuex-viewport.js"></script>

NPM

npm install vuex-viewport

Yarn

yarn add vuex-viewport

Usage

Outline

  1. Add a module and plugin to your store.
  2. Use computed property where necessary.

with CDN

See example code here.

<script>
var store = new Vuex.Store({
  modules: {
    viewport: vuexViewport.storeModule
  },
  plugins: [
    vuexViewport.createPlugin()
  ]
});

new Vue({
  el: '#app',
  store: store,
  computed: {
    windowWidth: function () {
      return this.$store.state.viewport.width;
    },
    windowHeight: function () {
      return this.$store.state.viewport.height;
    },
    layoutType: function () {
      // NOTE: This getter is supported in 1.1.0+
      return this.$store.getters['viewport/mediaName'];
    }
  }
});
</script>

without CDN

See example code here or another example code using with Nuxt.js.

// main.js

import Vue from 'vue';
import Vuex from 'vuex';
import { storeModule, createPlugin } from 'vuex-viewport';
import App from './App.vue';

Vue.use(Vuex);

const store = new Vuex.Store({
  modules: {
    viewport: storeModule
  },
  plugins: [
    createPlugin()
  ]
});

new Vue({
  store,
  render: (h) => h(App)
}).$mount('#app');
// App.vue

<template>
  <div id="app">
    <p>Layout type: {{ layoutType }}</p>
    <p>Window size: {{ windowWidth }} x {{ windowHeight }}</p>
  </div>
</template>

<script>
export default {
  name: 'App',
  computed: {
    windowWidth: function () {
      return this.$store.state.viewport.width;
    },
    windowHeight: function () {
      return this.$store.state.viewport.height;
    },
    layoutType: function () {
      // NOTE: This getter is supported in 1.1.0+
      return this.$store.getters['viewport/mediaName'];
    }
  }
};
</script>

Configuration

The createPlugin has some options (supported in 1.1.0+):

NameTypeDefaultDescription
delayNumber200The number of milliseconds to delay to measure the window size. (see debounce)
maxDelayNumber1000The maximum number of milliseconds to wait without measuring the size of the window if a series of resizing events does not end. (see debounce)
breakpointsObject{  tablet: 768,  desktop: 992}A set of key-value pairs whose key is the mediaName and whose value is the minimum width of the window.

TypeScript Support

You'll probably use one of these three examples.

Using neither Class-style Component nor Composition API

  1. Add a declaration file in your project directory.
// vuex.d.ts
import { ComponentCustomProperties } from 'vue';
import { Store } from 'vuex';
import { ModuleState } from 'vuex-viewport';

declare module '@vue/runtime-core' {
  // declare your own store states
  interface State {
    viewport: ModuleState;
  }

  // provide typings for `this.$store`
  interface ComponentCustomProperties {
    $store: Store<State>;
  }
}
  1. Create a store instance.
// store.ts
import { createStore } from 'vuex';
import { storeModule, createPlugin } from 'vuex-viewport';

export const store = createStore({
  modules: {
    viewport: storeModule,
  },
  plugins: [
    createPlugin(),
  ],
});
  1. Install the store instance.
// main.ts
import { createApp } from 'vue';
import { store } from 'PATH_OF_YOUR_store.ts';
import App from 'PATH_OF_YOUR_App.vue';

const app = createApp(App);

app.use(store);

app.mount('#app');
  1. Use store states and getters in Vue component.
// App.vue
<template>
  <div>
    <p>Layout type: {{ layoutType }}</p>
    <p>Window size: {{ windowWidth }} x {{ windowHeight }}</p>
  </div>
</template>

<script lang="ts">
import { defineComponent } from 'vue';

export default defineComponent({
  name: 'App',
  computed: {
    windowWidth(): number {
      return this.$store.state.viewport.width;
    },
    windowHeight(): number {
      return this.$store.state.viewport.height;
    },
    layoutType(): string {
      return this.$store.getters['viewport/mediaName'];
    },
  },
});
</script>

Using with Class-style Component

NOTE: This example is using Vue Class Component 8, which is still in beta as of July 2021.

  1. No declaration file is required.

  2. The process of creating and installing a store is the same as the above example.

  3. Use store states and getters in Vue component.

// App.vue
<template>
  <div>
    <p>Layout type: {{ layoutType }}</p>
    <p>Window size: {{ windowWidth }} x {{ windowHeight }}</p>
  </div>
</template>

<script lang="ts">
import { Options, Vue } from 'vue-class-component';

@Options({
  computed: {
    windowWidth() {
      return this.$store.state.viewport.width;
    },
    windowHeight() {
      return this.$store.state.viewport.height;
    },
    layoutType() {
      return this.$store.getters['viewport/mediaName'];
    },
  },
})
export default class App extends Vue {}
</script>

Using with Composition API

  1. No declaration file is required.

  2. Create a store instance.

// store.ts
import { InjectionKey } from 'vue';
import { createStore, useStore as baseUseStore, Store } from 'vuex';
import { storeModule, createPlugin, ModuleState } from 'vuex-viewport';

export interface State {
  viewport: ModuleState;
}

export const key: InjectionKey<Store<State>> = Symbol();

export const store = createStore({
  modules: {
    viewport: storeModule,
  },
  plugins: [
    createPlugin(),
  ],
});

export function useStore() {
  return baseUseStore(key);
}
  1. Install the store instance.
// main.ts
import { createApp } from 'vue';
import { store, key } from 'PATH_OF_YOUR_store.ts';
import App from 'PATH_OF_YOUR_App.vue';

const app = createApp(App);

app.use(store, key);

app.mount('#app');
  1. Use store states and getters in Vue component.
// App.vue
<template>
  <div>
    <p>Layout type: {{ layoutType }}</p>
    <p>Window size: {{ windowWidth }} x {{ windowHeight }}</p>
  </div>
</template>

<script lang="ts">
import { defineComponent, computed } from 'vue';
import { useStore } from 'PATH_OF_YOUR_store.ts';

export default defineComponent({
  name: 'App',
  setup() {
    const store = useStore();

    const windowWidth = computed(() => store.state.viewport.width);
    const windowHeight = computed(() => store.state.viewport.height);
    const layoutType = computed(() => store.getters['viewport/mediaName']);

    return {
      windowWidth,
      windowHeight,
      layoutType,
    };
  },
});
</script>
1.2.1

3 years ago

1.2.0

3 years ago

1.1.5

4 years ago

1.1.4

5 years ago

1.1.3

6 years ago

1.1.2

6 years ago

1.1.1

6 years ago

1.1.0

6 years ago

1.0.1

6 years ago

1.0.0

6 years ago