vueはVuexとlocalStorageによりローカルストレージとステータス管理を実現し、ページリフレッシュ後もステータスは変わらない


一、需要問題:vueのプロジェクト開発では、多くの複雑なページ間の通信を実現するために、このようなニーズによく遭遇する可能性があります.従来の親子、子親、非親子コンポーネントの通信は満足できない可能性があります.この場合、Vuexステータスマネージャを使用することができます.しかし、Vuexはページリフレッシュ後に状態が失われるため、ローカルストレージ技術localStorageで解決することができる.ここをクリックして都市リストの都市を選択すると、すべてのページの都市が変換され、ページをリフレッシュした後、都市情報が保存され、失われることはありません.
二、需要分析:
  • 都市リストを選択するページでは、localStorageを用いて、現在の都市リスト情報を格納する必要がある.バックエンドで返される都市リスト情報は配列であるため、localStorageは格納配列をサポートしないが、文字列を格納することができ、JSON.stringify()を使用することができる.要求インタフェースの後にlocalStoragesetItem()メソッドとJSON.stringify()を介して都市情報を格納することができる.mounted()がロードを開始すると、localStoragegetItem()方法でローカルストレージからデータを取得できます.都市データが存在する場合、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が格納され、mutationsCITY_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と書くと、handleToCitythis.$store.commitmutationsという方法で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
    };