vueはVuexとlocalStorageによりローカルストレージとステータス管理を実現し、ページリフレッシュ後もステータスは変わらない
59148 ワード
一、需要問題:vueのプロジェクト開発では、多くの複雑なページ間の通信を実現するために、このようなニーズによく遭遇する可能性があります.従来の親子、子親、非親子コンポーネントの通信は満足できない可能性があります.この場合、Vuexステータスマネージャを使用することができます.しかし、Vuexはページリフレッシュ後に状態が失われるため、ローカルストレージ技術
二、需要分析:都市リストを選択するページでは、
コードは次のとおりです.選択都市リストの各都市にイベントを追加することができ、クリックすると値が伝達され、
コードは次のとおりです.
三、需要実現:
完全なコードは次のとおりです.
localStorage
で解決することができる.ここをクリックして都市リストの都市を選択すると、すべてのページの都市が変換され、ページをリフレッシュした後、都市情報が保存され、失われることはありません.二、需要分析:
localStorage
を用いて、現在の都市リスト情報を格納する必要がある.バックエンドで返される都市リスト情報は配列であるため、localStorage
は格納配列をサポートしないが、文字列を格納することができ、JSON.stringify()
を使用することができる.要求インタフェースの後にlocalStorage
のsetItem()
メソッドとJSON.stringify()
を介して都市情報を格納することができる.mounted()
がロードを開始すると、localStorage
のgetItem()
方法でローカルストレージからデータを取得できます.都市データが存在する場合、JSON.parse()
法により、格納された配列をオブジェクトに変換することができる.存在しない場合は、データリクエストを再起動します.コードは次のとおりです:mounted() {
//
var cityList = window.localStorage.getItem('cityList');
var hotList = window.localStorage.getItem('hotList');
// , cityList hotList , ,
if ( cityList && hotList ) {
// JSON.parse
this.cityList = JSON.parse(cityList);
this.hotList = JSON.parse(hotList);
this.isLoading = false;
} else {
this.axios.get('/api/cityList').then((res) => {
// console.log(res);
// : [ { index: 'A', list: [{ nm: ' ', id: 1}]}]
var msg = res.data.msg;
if( msg === 'ok') {
this.isLoading = false;
var cities = res.data.data.cities;
var {cityList, hotList} = this.formatCityList(cities);
this.cityList = cityList;
this.hotList = hotList;
// , localStorage
// localStorage , JSON.stringify()
window.localStorage.setItem('cityList', JSON.stringify(cityList));
window.localStorage.setItem('hotList', JSON.stringify(hotList));
}
});
}
},
Vuex
の状態管理において、状態はmodules
モジュール化から引き離すことができ、store
フォルダにcity
のフォルダを作成することができ、index.js
ファイルを作成することができ、最も外側のstore
の下のindex.js
においてimport
によって導入される.city
では、state
にデータソースnmおよびidが格納され、mutations
にCITY_INFO()
メソッドが書き込まれ、state
およびpayload
の値が入力され、伝達されたpayload
のnmおよびid値がstate
のデータソースのnmおよびid値に付与される.コードは次のとおりです.
index.js
import Vue from 'vue'
import Vuex from 'vuex'
import city from './city'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
},
mutations: {
},
actions: {
},
modules: {
city
}
})
city
フォルダ下のindex.js
const state = {
nm: window.localStorage.getItem('nowNm') || ' ',
id: window.localStorage.getItem('nowId') || 1
};
const actions = {
};
const mutations = {
CITY_INFO (state, payload) {
state.nm = payload.nm;
state.id = payload.id;
}
};
export default {
namespaced: true,
state,
actions,
mutations
};
@tap="handleToCity( item.nm, item.id)
にmethods
と書くと、handleToCity
にthis.$store.commit
のmutations
という方法でnmとidの値が伝達される.変更された値を取得すると、CITY_INFO
を介して最新の都市情報を格納することができ、stateでは最初にローカルから最新の都市情報が取得され、なければデフォルトの都市情報が選択される.localStorage.setItem
により、クリック後に対応するルーティングにジャンプすることができる.コードは次のとおりです.
handleToCity( nm, id) {
this.$store.commit('city/CITY_INFO', { nm, id});
window.localStorage.setItem('nowNm', nm);
window.localStorage.setItem('nowId', id);
this.$router.push('/movie/nowPlaying');
}
三、需要実現:
完全なコードは次のとおりです.
this.$router.push
<template>
<div class="city_body">
<div class="city_list">
<Loading v-if="isLoading"/>
<Scroller v-else ref="city_list">
<!-- better-scroll , -->
<div>
<div class="city_hot">
<h2> </h2>
<ul class="clearfix">
<li v-for="item in hotList" :key="item.id" @tap="handleToCity( item.nm, item.id)">{{ item.nm }}</li>
</ul>
</div>
<div class="city_sort" ref="city_sort">
<div v-for="item in cityList" :key="item.index">
<h2>{{ item.index }}</h2>
<ul>
<li v-for="itemList in item.list" :key="itemList.id" @tap="handleToCity( itemList.nm, itemList.id)">{{ itemList.nm }}</li>
</ul>
</div>
</div>
</div>
</Scroller>
</div>
<div class="city_index">
<ul>
<li v-for="(item, index) in cityList" :key="item.index" @touchstart="handleToIndex(index)">{{ item.index }}</li>
</ul>
</div>
</div>
</template>
<script>
// import func from '../../../vue-temp/vue-editor-bridge';
// import func from './vue-temp/vue-editor-bridge';
export default {
name: 'City',
data() {
return {
cityList: [],
hotList: [],
isLoading: true
}
},
mounted() {
//
var cityList = window.localStorage.getItem('cityList');
var hotList = window.localStorage.getItem('hotList');
// , cityList hotList , ,
if ( cityList && hotList ) {
// JSON.parse
this.cityList = JSON.parse(cityList);
this.hotList = JSON.parse(hotList);
this.isLoading = false;
} else {
this.axios.get('/api/cityList').then((res) => {
// console.log(res);
// : [ { index: 'A', list: [{ nm: ' ', id: 1}]}]
var msg = res.data.msg;
if( msg === 'ok') {
this.isLoading = false;
var cities = res.data.data.cities;
var {cityList, hotList} = this.formatCityList(cities);
this.cityList = cityList;
this.hotList = hotList;
// , localStorage
// localStorage , JSON.stringify()
window.localStorage.setItem('cityList', JSON.stringify(cityList));
window.localStorage.setItem('hotList', JSON.stringify(hotList));
}
});
}
},
methods: {
formatCityList(cities) {
var cityList = [];
var hotList = [];
for(var i=0;i<cities.length; i++) {
if(cities[i].isHot === 1){
hotList.push( cities[i]);
}
}
for(var i=0; i<cities.length; i++) {
var firstLetter = cities[i].py.substring(0,1).toUpperCase();
if(toCom(firstLetter)) { //
cityList.push({index: firstLetter, list: [{ nm: cities[i].nm, id: cities[i].id}]});
}else { //
for(var j=0; j<cityList.length; j++){
if(cityList[j].index === firstLetter) {
cityList[j].list.push( { nm: cities[i].nm, id: cities[i].id} );
}
}
}
}
// index
cityList.sort((n1,n2) => {
if(n1.index > n2.index) {
return 1;
}
else if (n1.index < n2.index) {
return -1;
} else {
return 0;
}
})
// index cityList
function toCom(firstLetter) {
for(var i=0;i<cityList.length;i++){
if(cityList[i].index === firstLetter) {
return false;
}
}
return true;
}
// console.log(cityList);
// console.log(hotList);
return {
cityList,
hotList
}
},
// ,
handleToIndex(index) {
var h2 = this.$refs.city_sort.getElementsByTagName('h2');
// this.$refs.city_sort.parentNode.scrollTop = h2[index].offsetTop;
this.$refs.city_list.toScrollTop( -h2[index].offsetTop);
},
//
handleToCity( nm, id) {
this.$store.commit('city/CITY_INFO', { nm, id});
window.localStorage.setItem('nowNm', nm);
window.localStorage.setItem('nowId', id);
this.$router.push('/movie/nowPlaying');
}
}
}
</script>
<style scoped>
#content .city_body{ margin-top: 45px; display: flex; width:100%; position: absolute; top: 0; bottom: 0;}
.city_body .city_list{ flex:1; overflow: auto; background: #FFF5F0;}
.city_body .city_list::-webkit-scrollbar{
background-color:transparent;
width:0;
}
.city_body .city_hot{ margin-top: 20px;}
.city_body .city_hot h2{ padding-left: 15px; line-height: 30px; font-size: 14px; background:#F0F0F0; font-weight: normal;}
.city_body .city_hot ul li{ float: left; background: #fff; width: 29%; height: 33px; margin-top: 15px; margin-left: 3%; padding: 0 4px; border: 1px solid #e6e6e6; border-radius: 3px; line-height: 33px; text-align: center; box-sizing: border-box;}
.city_body .city_sort div{ margin-top: 20px;}
.city_body .city_sort h2{ padding-left: 15px; line-height: 30px; font-size: 14px; background:#F0F0F0; font-weight: normal;}
.city_body .city_sort ul{ padding-left: 10px; margin-top: 10px;}
.city_body .city_sort ul li{ line-height: 30px; line-height: 30px;}
.city_body .city_index{ width:20px; display: flex; flex-direction:column; justify-content:center; text-align: center; border-left:1px #e6e6e6 solid;}
</style>
city.vue
下のstore
import Vue from 'vue'
import Vuex from 'vuex'
import city from './city'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
},
mutations: {
},
actions: {
},
modules: {
city
}
})
index.js
下のcity
const state = {
nm: window.localStorage.getItem('nowNm') || ' ',
id: window.localStorage.getItem('nowId') || 1
};
const actions = {
};
const mutations = {
CITY_INFO (state, payload) {
state.nm = payload.nm;
state.id = payload.id;
}
};
export default {
// namespaced
namespaced: true,·
state,
actions,
mutations
};