最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

關于頁面刷新vuex數(shù)據(jù)消失問題解決方案

 更新時間:2017年07月03日 15:22:00   作者:-云-  
本篇文章主要介紹了關于頁面刷新vuex數(shù)據(jù)消失問題解決方案 ,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

VBox持續(xù)進行中,哀家苦啊,有沒有誰給個star。

vuex是vue用于數(shù)據(jù)存儲的,和redux充當同樣的角色。

最近在VBox開發(fā)的時候遇到的問題,頁面刷新或者關閉瀏覽器再次打開的時候數(shù)據(jù)歸零。這是頭疼的問題。

網(wǎng)上搜,大家的方案都是把數(shù)據(jù)轉移到 localStorage或者其他持久化存儲(例如indexDB)。

這倒是可以,我在設計之初因為匆忙,沒有考慮周全,這下好,然不成每個 mutation都去存一下。

這個弄的我很不開心,周六在公司,本來就困的要死,又想不到合理的解決方案,昏昏沉沉睡著了。

醒了后,最初想采用 柯里化和高階函數(shù)來解決這個問題,很可惜,沒有正解。

最小化修改,又不想動現(xiàn)有代碼,代理二字最為不過。記得上次我寫IBook之初,也用Proxy來攔截修改,同時存數(shù)據(jù)到磁盤文件。

沒錯方案就是 ES6的Proxy,嘗試之后,確實是可以的。

源碼地址:https://github.com/xiangwenhu/vbox/tree/master/src/utils

 這里有兩個問題

1. 初始值的問題。

2. 我要可以配置哪些字段需要持久化,store里面的數(shù)據(jù),不代表我都需要持久化。

首先解決是 localStorage存儲的問題,因為需要轉換字符串,簡單封裝一個 LStorage.js,當然你也可以用 https://github.com/tsironis/lockr , https://github.com/nbubna/store 或者你喜歡的,小輪子我就自己寫了。

const ls = window.localStorage
// https://github.com/tsironis/lockr
export default {
 getItem(key) {
  try {
   return JSON.parse(ls.getItem(key))
  } catch (err) {
   return null
  }
 },
 setItem(key, val) {
  ls.setItem(key, JSON.stringify(val))
 },
 clear() {
  ls.clear()
 },
 keys() {
  return ls.keys()
 },
 removeItem(key) {
  ls.removeItem(key)
 }
}

其次就是代理的簡單封裝,LSproxy.js

這個版本還是有問題的,現(xiàn)在只能代理二級屬性,對現(xiàn)在的我而言已經(jīng)是夠用了的。

createHanlder 創(chuàng)建二級屬性的代理

copy 復制對象,當然你可以寫更加兼容優(yōu)雅的方法

proxy  創(chuàng)建state的代理

import LStorage from './LStorage'

/**
 * 代理二級屬性
 * @param {*} lsKey 存在localStorage的key
 * @param {*} pk  一級屬性的key
 */
function createHanlder(lsKey, pk) {
 return {
  set: function (target, key, value, receiver) {
   let item = LStorage.getItem(lsKey)
   if (item && item[pk]) {
    item[pk][key] = value
    LStorage.setItem(lsKey, item)
   }
   return Reflect.set(target, key, value, receiver)
  }
 }
}

/**
 * 僅僅存需要存放的數(shù)據(jù)
 * @param {*} source 
 * @param {*} keys 
 */
function copy(source, keys = []) {
 if (!source) {
  return source
 }
 let d = Object.create(null)
 keys.forEach(k => { d[k] = source[k] })
 return d
}

/**
 * 代理state
 * @param {*} initState 初始化的值
 * @param {*} lsKey localStorage的key
 * @param {*} keys  需要存儲的鍵
 */
const proxy = function (initState, lsKey, keys = []) {
 let ks = keys, obj = Object.assign({}, initState, LStorage.getItem(lsKey))

 // 代理二級屬性
 keys.forEach(k => {
  obj[k] = new Proxy(obj[k], createHanlder(lsKey, k))
 })
 // 存入合并的值
 LStorage.setItem(lsKey, copy(obj, keys))
 return new Proxy(obj, {
  set: function (target, key, value, receiver) {
   ks.indexOf(key) >= 0 && LStorage.setItem(lsKey, copy(target, keys))
   return Reflect.set(target, key, value, receiver)
  }
 })
}

export { proxy }

調用這邊,基本就沒有什么變化, 就多了一句  state = proxy(state, 'playing', ['list'])

import { proxy } from '../utils/LSProxy'
let state = {
 list: [],
 current: null
}
state = proxy(state, 'playing', ['list'])

const mutations = {

 /**
  * 添加歌曲
  * @param {*} state 
  * @param {*} song 歌曲信息 
  */
 addSong(state, song) {
  let index = state.list.findIndex(s => s.songmid === song.songmid)
  if (index < 0) {
   state.list.push(song)
  }
 },

 /**
  * 添加歌曲
  * @param {*} state 內置
  * @param {*} songs 歌曲列表
  */
 addSongs(state, songs) {
  let index = -1
  songs.forEach(song => {
   index = state.list.findIndex(s => s.songmid === song.songmid)
   if (index < 0) {
    state.list.push(song)
   }
  })
 },

 /**
  * 刪除歌曲
  * @param {*} state 
  * @param {*} songmid 歌曲媒體id 
  */
 removeSong(state, songmid) {
  let index = state.list.findIndex(s => s.songmid === songmid)
  index >= 0 && state.list.splice(index, 1)
 },

 /**
  * 批量刪除歌曲
  * @param {*} state 
  * @param {*} songmids 歌曲媒體列表 
  */
 removeSongs(state, songmids = []) {
  let index = -1
  songmids.forEach(songmid => {
   index = state.list.findIndex(s => s.songmid === songmid)
   index >= 0 && state.list.splice(index, 1)
  })
 },

 /**
  * 播放下一首,
  * @param {*} state 
  * @param {*} song 為空
  */
 next(state, song) {
  // 如果song不為空,表示是插放,(前提是已經(jīng)添加到playing)
  if (song) {
   let index = state.list.findIndex(s => s.songmid === song.songmid)
   if (index >= 0) {
    state.current = state.list[index]
    return
   }
   return
  }
  // 如果current為空,表示沒有播放的歌曲
  if (!state.current && state.list && state.list.length > 0) {
   state.current = state.list[0]
   return
  }
  // 如果不是插放,并且current不為空
  if (!song && state.current) {
   // 播放的歌曲是不是在當前的列表
   let index = state.list.findIndex(s => s.songmid === state.current.songmid)
   // 如果在歌曲列表里面,接著播放下首
   if (index >= 0) {
    state.current = (index === state.list.length - 1 ? state.list[0] : state.list[index + 1])
   } else {
    state.current = state.list[0]
   }
  }
 }
}

export default {
 namespaced: true,
 state,
 mutations
}

這種方案的缺點也是很明顯的,

1. 代碼只能代理二級,對我一般情況應該是夠用了,扁平化state

2. 代理二級屬性和數(shù)組,要是屬性平凡修改的時候,代理是會重復觸發(fā)的,比如,添加30首歌曲的時候,是發(fā)生了30次存儲。 當然我覺得也是有方案可以優(yōu)化的。

優(yōu)點我覺得是,

1. state的數(shù)據(jù)與localStorage的同步過程分離開

2. 對現(xiàn)有代碼的注入是相當少的。

當然我上面代碼本身也還是存在問題的

1. 二級監(jiān)聽不能在proxy執(zhí)行的時候返回,因為如果屬性默認值為null/undefined,或者初始化就沒有設置默認值,是不會被監(jiān)聽到的,應該是放到一級屬性監(jiān)聽里面, 進行一個判斷

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

參考文章:

解決VUEX刷新的時候出現(xiàn)數(shù)據(jù)消失

相關文章

  • vue路由守衛(wèi)+登錄態(tài)管理實例分析

    vue路由守衛(wèi)+登錄態(tài)管理實例分析

    這篇文章主要介紹了vue路由守衛(wèi)+登錄態(tài)管理,結合實例形式分析了vue路由守衛(wèi)與登錄態(tài)管理相關操作步驟與實現(xiàn)技巧,需要的朋友可以參考下
    2019-05-05
  • vue表單中遍歷表單操作按鈕的顯示隱藏示例

    vue表單中遍歷表單操作按鈕的顯示隱藏示例

    今天小編就為大家分享一篇vue表單中遍歷表單操作按鈕的顯示隱藏示例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-10-10
  • 茶余飯后聊聊Vue3.0響應式數(shù)據(jù)那些事兒

    茶余飯后聊聊Vue3.0響應式數(shù)據(jù)那些事兒

    這篇文章主要介紹了茶余飯后聊聊Vue3.0響應式數(shù)據(jù)那些事兒,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-10-10
  • 通過vue刷新左側菜單欄操作

    通過vue刷新左側菜單欄操作

    這篇文章主要介紹了通過vue刷新左側菜單欄操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-08-08
  • vue搜索高亮popsearch組件的實現(xiàn)示例

    vue搜索高亮popsearch組件的實現(xiàn)示例

    有時候給頁面內容添加一個關鍵詞搜索功能,如果搜索結果能夠像瀏覽器搜索一樣高亮顯示,那找起來就會很明顯體驗會好很多,本文就來介紹一下vue搜索高亮popsearch組件的實現(xiàn)示例,感興趣的可以了解一下
    2023-09-09
  • Vue-CLI多頁分目錄打包的步驟記錄

    Vue-CLI多頁分目錄打包的步驟記錄

    這篇文章主要給大家介紹了關于Vue-CLI多頁分目錄打包的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-04-04
  • vue3 定義使用全局變量的示例詳解

    vue3 定義使用全局變量的示例詳解

    全局變量(函數(shù)等)可以在任意組件內訪問,可以當組件間的傳值使用,這篇文章給大家介紹vue3 定義使用全局變量的示例詳解,感興趣的朋友跟隨小編一起看看吧
    2023-10-10
  • vue從使用到源碼實現(xiàn)教程詳解

    vue從使用到源碼實現(xiàn)教程詳解

    這篇文章主要介紹了vue從使用到源碼實現(xiàn)的相關資料,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2016-09-09
  • Vue.js實現(xiàn)一個SPA登錄頁面的過程【推薦】

    Vue.js實現(xiàn)一個SPA登錄頁面的過程【推薦】

    本篇文章主要介紹了Vue.js寫一個SPA登錄頁面過程的相關知識,具有很好的參考價值。下面跟著小編一起來看下吧
    2017-04-04
  • Vue3中使用ref標簽對組件進行操作方法

    Vue3中使用ref標簽對組件進行操作方法

    這篇文章主要介紹了Vue3中使用ref標簽對組件進行操作方法,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-04-04

最新評論

盐源县| 宁武县| 海晏县| 涪陵区| 朔州市| 宜宾市| 南丹县| 满城县| 道真| 庄河市| 北海市| 石景山区| 东乡县| 海宁市| 阿坝县| 凤山市| 育儿| 台中市| 成安县| 乌鲁木齐市| 阿图什市| 固阳县| 洛隆县| 凤庆县| 博白县| 新乡市| 方正县| 高要市| 宁都县| 雅江县| 新疆| 东莞市| 双城市| 利辛县| 石首市| 内丘县| 鲁甸县| 河北省| 沁源县| 丰镇市| 齐河县|