vue进阶
2022/3/16 周三
由于最近有页面的需求,模板是用vue写的,之前没学过,所以跟着 b站秦疆老师【狂神说Java】Vue最新快速上手教程通俗易懂 入门vue(主要适用于只需要了解vue的后端同学),并参考菜鸟教程和一些优秀博客,根据自己的情况对重点内容做的笔记。
如有错误,欢迎在评论区指出,非常感谢!
一、Axios异步通信
vue.js是一个视图层框架,不包含AJAX通信功能,可以使用Axios来进行异步通信。注意JavaScript language version必须是ECMAScript6(ES6)。
异步从json文件中获取数据:
<body>
<div v-for="i in info">
<span>{{i.value}}</span> -- <span>{{i.name}}</span>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
var vm = new Vue({
el: "#app",
data(){
return{
info:{}
}
},
mounted(){
axios.get('level1Data.json').then(response=>(this.info=response.data));
}
</script>
</body>
这段代码涉及到的知识点如下:
1. data() 函数
(1)区分 data属性 data:{ } 和 data函数 data(){return{ }} :
data属性是全局的,在大型项目中data会造成数据污染。
将data封装成一个函数,我们在实例化组件的时候只是调用了这个函数生成的数据副本,这就避免了数据污染。因此在项目中我们一般都是用data()函数。
(2)data()函数里return的 info:{},相当于将拿到的数据定义为info,所以在div标签上才能用v-for="i in info"来遍历。
2. 钩子函数
mounted() 属于钩子函数,是在vue生命周期过程中自带的函数,在生命周期特定时间的会自动触发,所以不管写不写钩子函数,它都会被调用。
vue有8种生命周期函数,比如:
(1)created 触发的行为是:vue实例的数据对象data有了,$el还没有;此阶段可以做的事情:结束loading、请求数据为mounted渲染做准备。
(2)mounted 触发的行为是:vue实例挂载完成,data.filter成功渲染
(3)updated:data更新时触发
(4)destroyed:组件销毁时触发,vue实例解除了事件监听以及和dom的绑定(无响应了),但DOM节点依旧存在
剩下4个分别是beforeCreated、beforeMounted、beforeUpdated、beforeDestroyed,也就是发生在这些时间点之前的。
3. 链式编程
简单说就是调用方法用 . 一直点下去的编程写法。
这里的 then() 方法是异步执行,意思就是,当.then()前的方法执行完后再执行then()内部的方法。
另外,response 表示拿到的响应数据。
4. 箭头函数
当把一个函数的结果(返回值),作为另一个函数的参数的时,使用箭头函数 => 。
箭头函数中的 this 指向 外层调用者 。
这里的this.info=response.data表示,把从响应中拿到的数据赋值到data()函数中的info。
5. 页面闪烁问题
vue初始化时,如果网速不太给力,页面会先显示渲染数据之前的模板,类似{{i.value}} -- {{i.name}} 这种,之后闪烁一下才会显示出数据。
解决办法:在根dom上加上样式:
<div id="app" style="display: none;" :style="{display: 'block'}"></div>
这样闪烁时候只显示空白,感觉上就是还在加载,体验感至少比显示出模板要好。
二、计算属性computed
1. 概念
vue的计算属性是其一个特性,计算出来的结果保存在属性中。
好处是虚拟dom,在内存中运行,节省浏览器的成本。
可以理解为 将不经常变化的计算结果进行缓存。
2. 代码示例
将定义的currentTime1()方法和currentTime2计算属性对比:
<p>currentTime1: {{currentTime1()}}</p>
<p>currentTime1: {{currentTime2}}</p>
methods: {
currentTime1: function(){
return Date.now(); // 返回一个时间戳
}
},
computed: {
currentTime2: function(){
return Date.now(); // 返回一个时间戳
}
}
注意:
1.methods里的方法需要()括号来调用,而computed声明的计算属性直接调用属性名;
2.计算属性与methods方法重名是可以的,代码不报错,但是会忽略计算属性,只调用methods的方法,所以最好还是不要重名;
3.计算属性会与data发生冲突,不可以和data重名。
3. 对比结果
(1)在浏览器控制台输出两者结果:
>vm.currentTime1()
1647398791477
>vm.currentTime1()
1647398791872 // 与上面不同
>vm.currentTime2
1647398754040
>vm.currentTime2
1647398754040 // 与上面一样
可看到,currentTime1()方法产生的时间戳每一次输出都在刷新,而计算属性的输出则是一直不变的。
(2)但是,当计算属性中的数据被刷新时,就会重新计算。
比如先在data属性里声明一个message,再在计算属性中调用this.message,相当于给了属性可变的机会
data: {
message: "hello!"
},
computed: {
currentTime2: function(){
this.message;
return Date.now(); // 返回一个时间戳
}
}
这时在控制台修改message的值使属性改变,那么计算属性也会被刷新:
>vm.currentTime2
1647399171478
>vm.currentTime2
1647399171478
>vm.message="123"
'123'
>vm.currentTime2
1647399227259
>vm.currentTime2
1647399227259
可以发现修改message之后,计算属性的值也变了。