在vue项目中用vuex来做全局的状态管理, 发现当刷新网页后,保存在vuex实例store里的数据会丢失。
原因:
因为store里的数据是保存在运行内存中的,当页面刷新时,页面会重新加载vue实例,store里面的数据就会被重新赋值初始化
**解决思路:**将state的数据保存在localstorage、sessionstorage或cookie中(三者的区别),这样即可保证页面刷新数据不丢失且易于读取。
由于vue是单页面应用,操作都是在一个页面跳转路由,因此sessionStorage较为合适,原因如下:
\1. sessionStorage可以保证打开页面时sessionStorage的数据为空;
\2. 每次打开页面localStorage存储着上一次打开页面的数据,因此需要清空之前的数据。
vuex中state数据的修改必须通过mutation方法进行修改,因此mutation修改state的同时需要修改sessionstorage,问题倒是可以解决但是感觉很麻烦,state中有很多数据,很多mutation修改state就要很多次sessionstorage进行修改,既然如此直接用sessionstorage解决不就行了,为何还要用vuex多此一举呢? vuex的数据在每次页面刷新时丢失,是否可以在页面刷新前再将数据存储到sessionstorage中呢,是可以的,beforeunload事件可以在页面刷新前触发,但是在每个页面中监听beforeunload事件感觉也不太合适,那么最好的监听该事件的地方就在app.vue中。
\3. 在app.vue的created方法中读取sessionstorage中的数据存储在store中,此时用vuex.store的replaceState方法,替换store的根状态
\4. 在beforeunload方法中将store.state存储到sessionstorage中。
代码如下:
export default { name: 'App', created () { //在页面加载时读取sessionStorage里的状态信息 if (sessionStorage.getItem("store") ) { this.store.state,JSON.parse(sessionStorage.getItem("store")))) }
//在页面刷新时将vuex里的信息保存到sessionStorage里 window.addEventListener("beforeunload",()=>{ sessionStorage.setItem("store",JSON.stringify(this.$store.state)) }) } }
分类: vue
另一篇:
在实际的vue项目中,当我们的应用遇到多个组件之间的共享问题时,通常会用到Vuex(一个状态管理的插件,可以解决不同组件之间的数据共享和数据持久化),解决组件之间同一状态的共享问题。
因子:
· Vuex优势:相比sessionStorage,存储数据更安全,sessionStorage可以在控制台被看到。
· Vuex劣势:在刷新页面后,vuex会重新更新state,所以,存储的数据会丢失。
言而总之:
实际问题:在vue项目中,使用Vuex做状态管理时,调试页面时,刷新后state上的数据消失了,该如何解决?
解决思路:将state中的数据放在浏览器sessionStorage和localStorage
解决办法:
存储到localStorage
通过监听页面的刷新操作,即beforeunload前存入本地localStorage,页面加载时再从本地localStorage读取信息 在App.vue中加入下面代码
| 123456789 | created(){ //在页面刷新时将vuex里的信息保存到localStorage里 window.addEventListener("beforeunload",()=>{ localStorage.setItem("messageStore",JSON.stringify(this.$store.state)) }) //在页面加载时读取localStorage里的状态信息 localStorage.getItem("messageStore") && this.$store.replaceState(Object.assign(this.$store.state,JSON.parse(localStorage.getItem("messageStore")))); } |
|---|---|
或者使用vuex-persistedstate 插件
安装插件:npm install vuex-persistedstate --save
配置:
在store的index.js中,手动引入插件并配置
| 12345 | import createPersistedState from "vuex-persistedstate"const store = new Vuex.Store({ // ... plugins: [createPersistedState()]}) |
|---|---|
该插件默认持久化所有state,当然也可以指定需要持久化的state:
| 123456789101112 | import createPersistedState from "vuex-persistedstate"const store = new Vuex.Store({ // ... plugins: [createPersistedState({ storage: window.sessionStorage, reducer(data) { return { // 设置只储存state中的myData myData: data.myData } } })] |
|---|---|
App登录功能怎么实现?
思路: 1html+css 完成基本布局 2Ajax请求数据完成登录功能 3把登录成功后的 token和用户名传到下个页面
App如何打包发布?
小程序评论发布时图片不显示怎么处理?
什么叫原型链?
每一个实例对象上有一个proto属性,指向的构造函数的原型对象,构造函数的原型
对象也是一个对象,也有proto属性,这样一层一层往上找的过程就形成了原型链。
Vue中文件上传怎么获取属性?
Css的缺陷?
Css在各个浏览器内核有啥不足?
路由传参丢失如何保存?
this.$router.push({
name:"/admin",
query:{id:item.id}
})
//这个组件对应的路由配置
{
//组件路径
path: '/admin',
//组件别名
name: 'admin',
//组件名
component: Admin,
}
用query来传参,这种方式是可以解决页面刷新参数消失问题的,这种方式可以理解为是ajax中的get方法,参数是直接在url后面添加的,参数是可见的,所以解决页面刷新参数消失问题建议使用方法三来解决;
其实解决页面刷新参数丢失问题的方案还有很多,比如把参数存在sessionStorange或者localStorange中都是可行的,
移动与PC有什么区别?
移动端主要是Native代码(Android主要是是Java,iOS是主要是Object-C),也可以通过类似WebView组件嵌入H5
移动端更加需要考虑性能,因为移动设备的资源(主要是内存、网络、电量)有限性,涉及到很多性能优化的地方(图片缓存、耗电量优化、同步异步)
移动端通常是通过一种数据序列化格式(常见的JSON、XML)与服务器进行数据交流
移动端可以在用户授权下访问手机的文件
实现移动端的时候,你需要对同步异步、多线程、数据库、缓存有更深的理解
1、兼容性
pc端需要考虑浏览器兼容性,移动端主要考虑屏幕分辨率和不同系统的兼容性。
2、页面布局
PC端常用布局固定宽度980px居中,移动端屏幕的大小和分辨率不同,多用响应式布局,使用em(以父元素为基础)、rem(以根元素为基础)。
3、JS动画
移动端没有hover事件、增加了touch和touchSlide事件,需要处理键盘跳出与隐藏。考虑到性能,移动端使用的js库应尽量小。
4、开发调试
PC端用chrome后台调试,移动端大部分可以用chrome移动端模拟调试器,但有的功能还需要在手机上调试。
针对页面性能会做什么优化?
一、页面级优化
- 减少 HTTP请求数
减少 HTTP请求数的主要途径包括: (1). 从设计实现层面简化页面
(2) .合理设置 HTTP缓存
(3) 资源合并与压缩
(4) CSS Sprites 合并 CSS图片,减少请求数的又一个好办法。
(5) Inline Images
权限管理控制动态路由原理
登录时获取 token 保存到本地,接着前端会携带 token 再调用获取用户信息的接口获取当前用户的角色信息。
前端再根据当前的角色计算出相应的路由表拼接到常规路由表后面。
CSS3 的兼容问题怎么处理?
一般加私有前缀否则不做特殊处理,再有就是遵循 2 大原则,渐进增强和优雅降级
javascript的typeof返回哪些数据类型**
Undefined Function string boolean number symbol(ES6) Object
网站账号登录7天过期失效怎么实现的?
网站登录后,会在cookie中存入一个过期时间戳,每次请求时,网站会拦截请求并判断当前时间是否已经超过规定的时间,如果超过,则清cookie及session;如果没有,则按照失效期往后延,更新这个cookie的值
Call apply bind
实现new
移动端的兼容问题
· 给移动端添加点击事件会有300S的延迟 如果用点击事件,需要引一个fastclick.js文件,解决300s的延迟 一般在移动端用ontouchstart、ontouchmove、ontouchend
· 移动端点透问题,touchstart 早于 touchend 早于click,click的触发是有延迟的,这个时间大概在300ms左右,也就是说我们tap触发之后蒙层隐藏, 此时 click还没有触发,300ms之后由于蒙层隐藏,我们的click触发到了下面的a链接上 尽量都使用touch事件来替换click事件。例如用touchend事件(推荐)。 用fastclick,github.com/ftlabs/fast… 用preventDefault阻止a标签的click 消除 IE10 里面的那个叉号 input:-ms-clear{display:none;}
· 设置缓存 手机页面通常在第一次加载后会进行缓存,然后每次刷新会使用缓存而不是去重新向服务器发送请求。如果不希望使用缓存可以设置no-cache。
· 圆角BUG 某些Android手机圆角失效 background-clip: padding-box; 防止手机中网页放大和缩小 这点是最基本的,做为手机网站开发者来说应该都知道的,就是设置meta中的viewport
· 设置用户截止缩放,一般写视口的时候就已经写好了。
V-model的原理是什么?
Vue的双向数据绑定是由数据劫持结合发布者订阅者实现的。 数据劫持是通过Object.defineProperty()来劫持对象数据的setter和getter操作。 在数据变动时作你想做的事
· 原理 通过Observer来监听自己的model数据变化,通过Compile来解析编译模板指令,最终利用Watcher搭起Observer和Compile之间的通信桥梁,达到数据变化->视图更新 在初始化vue实例时,遍历data这个对象,给每一个键值对利用Object.definedProperty对data的键值对新增get和set方法,利用了事件监听DOM的机制,让视图去改变数据
.谈谈对生命周期的理解
· beforeCreate阶段:vue实例的挂载元素el和数据对象data都是undefined,还没有初始化。
· created阶段:vue实例的数据对象data有了,可以访问里面的数据和方法,未挂载到DOM,el还没有
· beforeMount阶段:vue实例的el和data都初始化了,但是挂载之前为虚拟的dom节点
· mounted阶段:vue实例挂载到真实DOM上,就可以通过DOM获取DOM节点
· beforeUpdate阶段:响应式数据更新时调用,发生在虚拟DOM打补丁之前,适合在更新之前访问现有的DOM,比如手动移除已添加的事件监听器
· updated阶段:虚拟DOM重新渲染和打补丁之后调用,组成新的DOM已经更新,避免在这个钩子函数中操作数据,防止死循环
· beforeDestroy阶段:实例销毁前调用,实例还可以用,this能获取到实例,常用于销毁定时器,解绑事件
· destroyed阶段:实例销毁后调用,调用后所有事件监听器会被移除,所有的子实例都会被销毁
常见的兼容问题
png24位的图片在iE6浏览器上出现背景 解决方案是做成PNG8.也可以引用一段脚本处理.
浏览器默认的margin和padding不同。 解决方案是加一个全局的*{margin:0;padding:0;}来统一。
IE6双边距bug:块属性标签float后,又有横行的margin情况下,在ie6显示margin比设置的大。
浮动ie产生的双倍距离(IE6双边距问题:在IE6下,如果对元素设置了浮动,同时又设置了margin-left或margin-right,margin值会加倍。) #box{ float:left; width:10px; margin:0 0 0 100px;}
移动端的性能优化
1、首屏加载和按需加载,懒加载
2、资源预加载
3、图片压缩处理,使用base64内嵌图片
4、合理缓存dom对象
5、使用touchstart代替click(click 300毫秒的延迟)
6、利用transform:translateZ(0),开启硬件GUP加速
7、不滥用web字体,不滥用float(布局计算消耗性能),减少font-size声明
8、使用viewport固定屏幕渲染,加速页面渲染内容
9、尽量使用事件代理,避免直接事件绑定
get/post的区别
1.get数据是存放在url之后,以?分割url和传输数据,参数之间以&相连; post方法是把提交的数据放在http包的Body中 2.get提交的数据大小有限制,(因为浏览器对url的长度有限制),post的方法提交的数据没有限制 3.get需要request.queryString来获取变量的值,而post方式通过request.from来获取变量的值 4.get的方法提交数据,会带来安全问题,比如登录一个页面,通过get的方式提交数据,用户名和密码就会出现在url上
"