所以,在用vue进行项目开发的时候,什么时候用到vuex呢?
- 当一个组件需要多次派发事件时。例如购物车数量加减。
- 跨组件共享数据、跨页面共享数据。例如订单状态更新。
- 需要持久化的数据。例如登录后用户的信息。
- 当您需要开发中大型应用,适合复杂的多模块多页面的数据交互,考虑如何更好地在组件外部管理状态时。
当应用遇到多个组件共享状态时候,即:多个视图依赖于同一个状态,不同视图的行为需要变更同一状态。
vuex的官网也说了,对于页面之间的传参对于多层嵌套组件将会很繁琐,而且对于兄弟组件之间的状态传递无能为力。所以就将这些组件的共享状态抽取出来,以一个全局单例模式管理,即vuex。
vuex:不能直接修改store里面的变量,由统一的方法修改数据,每个组件可以根据自己的vuex变量名引用不受影响,解决了多组件之间的通信问题,适用于多模块,业务关系复杂的中大型项目;
全局变量:可以任意修改,全局变量可能操作命名污染,跨页面数据共享,适用于demo或者小型项目
使用 Vuex 需要遵守的规则:
- 应用层级的状态应该集中到单个 store 对象中。
- 提交 mutation 是更改状态的唯一方法,并且这个过程是同步的。
- 异步逻辑都应该封装到 action 里面。
2、vuex的底层实现原理
全局单例模式,vuex实际上就是一个重新封装的new Vue对象,它的动态响应数据就是data属性,而commit这些方法都只是回调而已。观察订阅模式?
3、vuex页面刷新数据丢失问题?
一般在登录成功的时候需要把用户信息,菜单信息放置vuex中,作为全局的共享数据。但是在页面刷新的时候vuex里的数据会重新初始化,导致数据丢失。因为vuex里的数据是保存在运行内存中的,当页面刷新时,页面会重新加载vue实例,vuex里面的数据就会被重新赋值。
办法一:将vuex中的数据直接保存到浏览器缓存中(sessionStorage、localStorage、cookie)
办法二:在页面刷新的时候再次请求远程数据,使之动态更新vuex数据
办法三:在父页面向后台请求远程数据,并且在页面刷新前将vuex的数据先保存至sessionStorage(以防请求数据量过大页面加载时拿不到返回的数据)
选择存储到sessionStorage,选择的原因是由于vue是单页面应用,操作都是在一个页面跳转路由,另一个原因是sessionStorage可以保证打开页面时sessionStorage的数据为空,而如果是localStorage则会读取上一次打开页面的数据
所以该解决方案就是,监听浏览器刷新前事件,在浏览器刷新之前就把vuex里的数据保存至sessionStorage中,刷新成功后如果异步请求的数据还没返回则直接获取sessionStorage里的数据,否则获取vuex里的数据。(只有刷新后还没取到后台数据,才会从sessionStorage里取。确保数据的安全性,就算获取sessionStorage里的数据也是安全的,因为每次刷新都会重新赋值,不必担心数据被篡改问题,其次就是对sessionStorage里的数据做了加密操作)
vuex-persistedstate
将vuex的state存在localStorage或sessionStorage或cookie中一份
刷新页面的一瞬间,vuex数据消失,vuex会去sessionStorage中拿回数据,变相的实现了数据刷新不丢失~
3、cookie、localstorage、sessionstorage的区别?使用过吗?
使用:
1.写入:document.cookie='username=xxxx';
2.读取:document.cookie;
使用:
1.存储:localStorage.setItem('username','alex');
2.获取:localStorage.getItem('username');
3.单独删除:localStorage.removeItem('username');
4.全部删除:localStorage.clear();
5.自动填充:一般是用在form表单,在表单提交的时候把需要填充的数据保存在localStorage,下次输入前取到对应的值进行填充即可。
4、http请求一般都会携带cookie,这个携带需要设置吗?是所有http都会携带cookie吗?
ajax请求不会携带cookie,需要设置,默认情况下不会, 只有当设置了 credentials 时才会带上与请求同域的cookie, 并且服务端需要设置响应头 Access-Control-Allow-Credentials: true, 否则浏览器会报错, 拿不到响应
fecth请求不会携带cookie,需要设置credentials:true
http请求携带cookie必须满足下面几个条件
拿一个Http POST请求来说 http://aaa.www.com/xxxxx/list
- 浏览器端某个Cookie的domain字段等于http://aaa.www.com或者http://www.com (在同一个域内)
- 都是http或者https,或者不同的情况下Secure属性为false
- 要发送请求的路径,即上面的xxxxx跟浏览器端Cookie的path属性必须一致,或者是浏览器端Cookie的path的子目录,比如浏览器端Cookie的path为/test,那么xxxxxxx必须为/test或者/test/xxxx等子目录(如果cookie设置在http://www.com/list中,那么请求http://aaa.www.com/xxxxx/list可以携带)
cookie的一些字段(name,value,domain,path,expires/max-age,httpOnly,secure,samesite)
Domain: cookie的域。如果设成.deepred.com,那么a.deepred.com和b.deepred.com域名下,都可以使用.deepred.com的cookie。
Path: cookie的路径。请求资源的路径一定要包含这个path才能携带cookie。一般设置成/即可。
Expires/Max-Age: cookie过期时间。默认不设置,则是Session会话,关闭页面后,该cookie立即失效。
HttpOnly: 设成true后,JS使用document.cookie则访问不到。常用于避免XSS攻击。
Secure: 标记为Secure的cookie只应通过被HTTPS协议加密过的请求发送给服务端。
SameSite: 用来限制第三方Cookie
Cookie携带的场景
我们假设有一个名字为sessionId的cookie,domain设置成了.demo.com。
1.在a.demo.com域名下,ajax在该域名下的所有请求,都会自动带上sessionId
ajax.get('/api/data') // 自动带上sessionId
2.在b.demo.com域名下,ajax在该域名下的所有请求,都会自动带上sessionId
ajax.post('/api2/data2') // 自动带上sessionId
3.在b.demo.com域名下,ajax请求a.demo.com的api,需要设置withCredentials才能带上sessionId
https://a.demo.com/api/data
需要支持cors跨域,并且Access-Control-Allow-Origin
不能设成*
,要设置成https://b.demo.com
,只有这样,withCredentials
才有用
5、如何检查请求是否为同站、同源、或者跨站???
这个 HTTChrome 发送请求时会附带一个 Sec-Fetch-Site HTTP Header 。这个http-header会有以下值
-
cross-site
-
same-site
-
same-origin
-
none
通过检查 Sec-Fetch-Site 的值,您可以确定请求是 “同站”,“同源” 还是 “跨站”。
6、组件中样式如何避免污染,
在vue中使用scoped,避免污染进行独享,scoped的原理:为组件实例生成一个唯一标识,给组件中每个标签对应的dom元素添加一个标签属性,data-v-xxxx,生成随机编号,再给每个选择器的最后一个选择器添加该属性选择器
css模块化,解决类名冲突问题,思路就是产生一个独一无二的class的名字,不会与其他的选择器重名;实现原理,开启了css module后,构建工具webpack的css-loader会将样式中的类名进行转换,转换为唯一的hash值;因此由于hash值是根据模块路径和类名生成的,因此,在不同的css模块中,哪怕有相同的类名,hash值也是不一样的
7、css in js
8、vue2与vue3的区别,使用中有没有vue2比较难以实现的地方,使用vue3就可以很好的实现