前言
本篇主要是介绍vue文件的构成,需要先有前端的常识(JavaScript,html,css方面的知识)。个人还是比较建议先学前端基础再开始学框架尤其是JavaScript。
.vue文件的构成
<template>
<div class="demo">
...
</div>
</template>
<script>
export default {
name:'Demo',
data() {
return {
demoData:'',
demoNum:0,
}
},
watch:{
demoData:{
handler(val,oldVal){
...
},
deep:true,
}
},
computed: {
getDemoNum(){
return demoNum+1;
}
},
methods: {
myDemo(){
...
},
},
beforeCreate () {
},
created() {
},
beforeMount () {
},
mounted () {
},
beforeUpdate () {
},
updated () {
},
beforeDestroy () {
},
destroyed() {
},
}
</script>
<style lang="scss" scoped>
.demo{
...
}
</style>
一个.vue文件大致分为template,script和style三个部分
- template中的内容相当于html(template里一定要有一个根标签)
- script中的内容相当于JavaScript
- style中便是css的内容
生命周期
说到vue一定要说的就是vue的生命周期。vue每个组件都是独立的,每个组件都有一个属于它的生命周期,从一个组件创建、数据初始化、挂载、更新、销毁,这就是一个组件所谓的生命周期。通常是八个(beforeCreate,created,beforeMount,mounted,beforeUpdate,updated,beforeDestroy,destroyed),但如果你开启了keep-alive那么你就会解锁activated和deactivated。
beforeCreate
实例化vue之后就会开始初始化事件和生命周期,而beforeCreate是在实例初始化后,data observer和事件配置之前调用。说人话就是beforeCreate里没办法通过vm访问data和methods里面的方法
created
beforeCreate之后开始初始化inject provide state属性(vue内部添加data和methods等),然后就是created周期,在这里data已经初始化,初始化事件监听和事件代理。这时是可以通过vm访问data里的数据和methods里的方法,但是dom树还没挂载。也就是这里vue开始解析模板,生成虚拟dom,所以页面还不能显示解析好的内容。
beforeMount
created到beforeMount之前会先判断有没有el对象,如果没有则挂载,然后判断有没有模板,如果没有则编译el外层的html作为模板,当然如果有模板的话就通过render函数去渲染创建dom树
这个时候页面呈现未经vue编译的页面,对dom的所有操作最终都不奏效 在这个周期会把内存中的虚拟dom转为真实dom插入页面
mounted
beforeMount的时候生成真实dom后创建vue实例下的$el并将其替换成真实的dom,mounted的时候dom树构建完成并且已经挂载也就是说 页面呈现经过vue编译的页面,对dom的所有操作均有效但是不建议没事就去操作dom。这个时候我们一般会开启定时器(少用定时器),发送网络请求绑定自定义事件等等的初始化操作。
beforeUpdate
数据更新的时候调用,这个时候数据是新的页面还是旧的。就是页面还没和数据保持同步,此时生成新的虚拟dom,和旧的虚拟dom进行比较。
updated
这个时候页面和数据保持同步
beforeDestroy
vue里所有的data,methods都可用,对数据进行的操作都有效,但不会渲染到页面,一般这个时候把定时器关一关,解绑自定义事件。
destroyed
beforeDestroy之后清除watcher、子组件、事件监听器。也就是说这个时候啥啥都用不了了。
activated和和deactivated
在被keep-alive包含的组件/路由中,会多出两个生命周期的钩子activated 与 deactivated。
activated
activated调用时机:第一次进入缓存路由/组件,在mounted后面,beforeRouteEnter守卫传给 next 的回调函数之前调用:
beforeMount=> 如果你是从别的路由/组件进来(组件销毁destroyed/或离开缓存deactivated)=>mounted=> activated 进入缓存组件 => 执行 beforeRouteEnter回调
因为组件被缓存了,再次进入缓存路由/组件时,不会触发这些钩子:beforeCreate created beforeMount mounted。
deactivated
deactivated调用时机:组件被停用(离开路由)时调用
使用了keep-alive就不会调用beforeDestroy(组件销毁前钩子)和destroyed(组件销毁),因为组件没被销毁,被缓存起来了。
这个钩子可以看作beforeDestroy的替代,如果你缓存了组件,要在组件销毁的的时候做一些事情,你可以放在这个钩子里。
如果你离开了路由,会依次触发: 组件内的离开当前路由钩子beforeRouteLeave => 路由前置守卫 beforeEach =>全局后置钩子afterEach => deactivated 离开缓存组件 => activated 进入缓存组件(如果你进入的也是缓存路由
vue中的内置方法及属性
data
data比较特殊是个函数(闭包),data相当于存放了我们需要用到的变量 上面提到过data在beforeCreate时初始化created时可以访问。
prop
prop一般用于父组件向子组件进行单向通信(父向子传值),传递的可以是一个对象,也可以是一个数组 prop是数组的话会有默认的数据类型,是对象的话可以设置数据类型,是否必传等
prop 是在父传子时形成一个单向下行绑定,意思是父级的更新会向下流动到子组件中,但是反过来则不行。每次父级组件发生更新时,子组件中所有的 prop 都将会刷新为最新的值。这意味着你不应该在一个子组件内部改变 prop。
methods
这里放的都是我们自定义的方法,也是在beforeCreate时初始化created时可以访问
computed
计算属性,一个数据, 依赖另外一些数据计算而来的结果
计算属性是基于它们的依赖项的值结果进行缓存的,只要依赖的变量不变, 都直接从缓存取结果
watch
监听器,虽然计算属性在大多数情况下更合适,但当需要在数据变化时执行异步操作时,监听属性更有用。
filters
过滤器,需要格式化数据的情况,比如我们需要处理 时间、价格、状态码等数据格式的输出 / 显示
filters不会修改数据,只是改变用户看到的输出
那么问题来了data、props、computed、watch、methods他们之间的生成顺序是什么呢
props => methods =>data => computed => watch(别问,问就是源码就是这个顺序)