Vue--爬坑
1.路由变化页面数据不刷新问题;
出现这种情况是因为依赖路由的params参数获取写在created生命周期里面,因为相同路由二次甚至多次加载的关系 没有达到监听,退出页面再进入另一个文章页面并不会运行created组件生命周期,导致文章数据还是第一次进入的数据。
解决方法:watch监听路由是否变化
解决方法:watch监听路由是否变化
watch: {
// 方法1
'$route' (to, from) { //监听路由是否变化
if(this.$route.params.articleId){// 判断条件1 判断传递值的变化
//获取文章数据
}
}
//方法2
'$route'(to, from) {
if (to.path == "/page") { /// 判断条件2 监听路由名 监听你从什么路由跳转过来的
this.message = this.$route.query.msg
}
}
2.通过this发起http请求,返回值是premise
get或post请求 返回promise
若某个方法的返回值是promise,可用await简化操作,await只能用在被async修饰的范围中,把紧挨着await的方法修饰成异步的async方法.await只能放在async中,只能修饰promise对象
3.v-for,动态生成DOM节点的报错问题
原因是一块内存里有相同的key,而导致发生了冲突,存放数据的是一个数组,那么在通过请 求获取的数据时,先把存放是这个数组初始化 —> this.data = [ ] ,最后再赋值
4.动态绑定src不显示图片解决方法
图片链接是需要通过 require包裹的
5.解决vuex在页面刷新后数据丢失的问题
一、原因
js代码是运行在内存中的,代码运行时的所有变量、函数也都是保存在内存中的。
刷新页面,以前申请的内存被释放,重新加载脚本代码,变量重新赋值,所以这些数据要想存储就必须存储在外部,例如:Local Storage、Session Storage、Index DB等。这些都是浏览器提供的API,让你可以将数据存储在硬盘上,做持久化存储。具体选择哪一个就根据你实际需求来选择。
二、解决方案
在客户端存储数据:
HTML5提供了2种在客户端存储数据的新方法:localStorage没有时间期限,除非将它移除,sessionStorage即会话,当浏览器关闭时会话结束,有时间期限,具有自行百度。
之前,这些都是由cookie完成的,但是cookie不适合大量数据的存储,因为它们由每个对服务器的请求来传递,这使得cookie速度很慢,而且效率不高。
web存储分为localStorage个sessionStorage。
区别在于存储的有效期和作用域不同。
通过localStorage存储的数据是永久性的,除非web应用刻意删除存储的数据,或者用户通过设置浏览器配置(浏览器提供的特定的UI)来删除,否则数据将一直保存在用户的电脑上,永不过期。
localStorage的作用域是限定在文档源级别的。同源的文档间共享同样的localStorage数据(不论该源的脚本是否真正的访问localStorage)。他们可以互相读取对方的数据,甚至可以覆盖对方的数据。但是,非同源的文档间互相都不能读取或者覆盖对方的数据。(即使他们运行的脚本是来自同一台第三方的服务器也不行)。
sessionStorage存储数据的有效期和存储数据的脚本所在的最顶层的窗口或者是浏览器标签页是一样的,一旦窗口或者标签页被永久关闭了,那么所有通过sessionStorage存储的数据也都被删除了。
我这里使用sessionStorage,这里需要注意的是vuex中的变量是响应式的,而sessionStorage不是,当你改变vuex中的状态,组件会检测到改变,而sessionStorage就不会了,页面要重新刷新才可以看到改变,所以应让vuex中的状态从sessionStorage中得到,这样组件就可以响应式的变化
三、具体实现
应用背景是用户登入后保存状态,退出后移除状态
//mutations
ADD_LOGIN_USER (state,data) { //登入,保存状态
sessionStorage.setItem("username", data); //添加到sessionStorage
sessionStorage.setItem("isLogin",true);
state.username=data, //同步的改变store中的状态
state.isLogin=true
},
SIGN_OUT (state) { //退出,删除状态
sessionStorage.removeItem("username"); //移除sessionStorage
sessionStorage.removeItem("isLogin");
state.username='' //同步的改变story中的状态
state.isLogin=false
}
//getters
isLogin (state) {
if (!state.isLogin) {
state.isLogin=sessionStorage.getItem('isLogin'); //从sessionStorage中读取状态
state.username=sessionStorage.getItem('username');
}
return state.isLogin
}
总体的实现思路是让vuex中store的状态从sessionStorage取值,并和sessionStorage保持一致
getters:{
userInfo(state){
if(!state.userInfo){
state.userInfo = JSON.parse(sessionStorage.getItem('userInfo'))
}
return state.userInfo
}
},
mutations:{
LOGIN:(state,data) => {
state.userInfo = data;
sessionStorage.setItem('userInfo',JSON.stringify(data));
},
LOGOUT:(state) => {
state.userInfo = null;
sessionStorage.removeItem('userInfo');
}
},
需要注意的是state里的userInfo初始化一定要是null,而不是{},否则那个判断就一直为true啦(个人遇到的一个小问题)
6.上传图片无效token:
原因:
用axios发请求的时候,会自动追加token 说明在调用upload组件传图片的时候,它在发ajax期间, 没有用到axios,而是组件内部自己封装了一套ajax,自己封装的ajax没有携带Authorization这个字段,所以无效token。
解决:
为上传组件手动绑定headers请求头,在请求头中包含验证的Authorization 值在seesionStorage 存着 从Windows获取 这样的话就为每次上传ajax请求进行了token验证
</el-tab-pane>
<el-tab-pane label="商品图片" name="3">
<!-- active表示图片上传到的后台API地址 -->
<el-upload action="uploadURL"
:on-preview="handlePreview"
:on-remove="handleRemove"
:file-list="fileList2"
list-type="picture" :headers="headerObj">
<el-button size="small" type="primary">点击上传</el-button>
</el-upload>
</el-tab-pane>
data() { //上传图片url地址 uploadURL:'http://127.0.0.1:8888/api/private/v1/upload',
//图片上传组件的headers
headerObj: {
Authorization:window.sessionStorage.getItem('token')
}
}
6.路由懒加载
当打包构建项目时,JavaScript 包会变得非常大,影响页面加载。如果我们能把不同路由对应的组件分割成
不同的代码块,然后当路由被访问的时候才加载对应组件,这样就更加高效了。
具体需要 3 步:
① 安装 @babel/plugin-syntax-dynamic-import 包。
② 在 babel.config.js 配置文件中声明该插件。
③ 将路由改为按需加载的形式,示例代码如下:
const Foo = () => import(/* webpackChunkName: "group-foo" */ './Foo.vue')
const Bar = () => import(/* webpackChunkName: "group-foo" */ './Bar.vue')
const Baz = () => import(/* webpackChunkName: "group-boo" */ './Baz.vue')
关于路由懒加载的详细文档,可参考如下链接:
https://router.vuejs.org/zh/guide/advanced/lazy-loading.html