Edited at

web制作でよく使用するVuex自作モジュール3選

ここ数ヶ月、webサイトをつくときはVueまたはVuePressを使用しています。

いくつか作ってみてほぼ必ず必要になってるVuexの自作モジュールがあるので3つほどご紹介

とりあえずこの3つをVuexつかって管理して必要なコンポーネントでmapState

などすると実装がシンプルになるような気がします。


とりあえずindex.js

store/index.jsとかつくってとりあえず置いておく。基本は用途ごとにネームスペースを切る想定。


index.js

import Vue from 'vue'

import Vuex from 'Vuex'

const state = {
}

const modules = {

}

const mutations = {

}

const actions = {

}

const store = new Vuex.Store({
state,
modules,
mutations,
actions,
})

export default store;



レスポンシブ、画面サイズに関するモジュール

レスポンシブでウェブサイトを作っているとウインドウサイズの情報が欲しくなったり、

モバイルでは必要だけどPCでは必要ないみたいなことが頻繁に起こります。

windowに関する情報はstoreで管理してます。

store/module-window.js


module-window.js

const mobileThreshold = 769;

const minWidth = 1280;

const decideIsPc = (w)=>{
if(w < mobileThreshold){
return false;
}
return true;
}

const getWindowSize = ()=>{
let w = window.innerWidth
let h = window.innerHeight
if(w >= mobileThreshold) w = Math.max(minWidth, w);
return {
w: w,
h: h
}
}

const defaultState = typeof window !== 'undefined' ? {
size: getWindowSize(),
isPc: decideIsPc(window.innerWidth)
} : {
size: {w: 999999, h: 999999},
isPc: true,
}

const state = defaultState;

const mutations = {
update(state){
const size = getWindowSize();
state.size = size
state.isPc = decideIsPc(size.w);
},
}

export default {
namespaced: true,
state,
mutations
}


VuePressでビルドする用(おそらくNuxtでも同じ)にtypeof windowとかで条件分岐しているため

やや冗長になってますが、やっていることはmutationupdateでウインドウサイズ取得して

サイズを更新、ついでにモバイルかどうかも変別して更新しているだけです。

store/index.jsにモジュールをついかするのと、(どこに書いても問題ないが)window resizeをフックする

部分もここに書いてしまっています。


index.js


~
import ModuleWindow from './module-window'

~

const modules = {
window: ModuleWindow,
}

~

if(typeof window !== 'undefined'){

window.addEventListener('resize', ()=>{
store.commit('window/update')
})

}


storeのisPcはよく使うのでなんならmixinにしてもいいかもしれません。

import {mapState} from 'Vuex'

Vue.mixin({
computed:{
...mapState('window', {$isPc: 'isPc'}),
}
})


スクロール位置に関するモジュール

ウインドウサイズと同じくスクロール位置に関してもたまに必要になるので

ほとんど同じだけれど作っておくと便利かもしれません。

store/module-scroll.js


module-scroll.js

const state = {

top: 0,
left: 0
}

const mutations = {
update(state){
const elem = document.documentElement || document.body
const top = elem.scrollTop
const left = elem.scrollLeft
state.top = top
state.left = left
}
}

const actions = {

}

const getters = {

}

export default {
namespaced: true,
state,
mutations,
actions,
getters
}


updateでスクロール位置調べてstate更新してるだけ。

updateを呼び出すのをウインドウと同じくstore/index.jsに書いておきます。


index.js


~
import ModuleScroll from './module-scroll'

~

const modules = {
scroll: ModuleScroll,
}

~

if(typeof window !== 'undefined'){

window.addEventListener('scroll', ()=>{
store.commit('scroll/update')
})

}



モーダルウインドウに関するモジュール

モーダルウインドウってつくるのめんどくさいですよね。

状態をVuexで管理すれば幾分ましな気持ちで実装できるんじゃないかと


module-modal.js

const state = {

isShow: false,
}

const mutations = {
show(state) {
document.body.style.overflow = 'hidden'
state.isShow = true

},
hide(state) {
document.body.style.overflow = 'auto'
state.isShow = false
},
}

const actions = {

}

export default {
namespaced: true,
state,
mutations,
actions
}


任意のコンポーネントでshow/hideを呼び出して、モーダルウインドウにしたいコンポーネントを

isShowとv-ifで実装するということをしています。

bodyのoverflowのスタイルを変更しているのは背景をfixさせておくためのやつです。

これだけだとios safariではカバーしきれてないのでとりあえずというところですが

この件に関しては別の話題。

modulesに追加するところは省略


おわりに

いかがだったでしょうか。特別なことをしているわけじゃないですが

なにか参考になる所があればと思います。

むしろみなさんどうしているんだろう。