vue生命周期javascript
什么是Vue生命周期?css
Vue实例从建立到销毁的过程,就是生命周期。也就是从开始建立、初始化数据、编译模版、挂载Dom ——>渲染、更新——>渲染、卸载等一系列过程,咱们称这是Vue的生命周期html
Vue生命周期的做用是什么?vue
它的生命周期中有多个事件钩子,让咱们在控制整个Vue实例的过程时更容易造成好的逻辑java
Vue生命周期总共有几个阶段?node
它能够总共分为8个阶段:建立前/后,载入前/后,更新前/后,销毁前/销毁后web
第一次页面加载会触发哪几个钩子?正则表达式
第一次页面加载时会触发beforeCreate,created,beforeMount,mounted这几个钩子vue-router
DOM渲染在哪几个周期中就已经完成?vuex
DOM渲染在mounted中就已经完成了
每一个生命周期适合哪些场景?
生命周期钩子的一些使用方法:
beforecreate:能够在这加个loading事件,在加载实例时触发
created:初始化完成时的事件写在这里,如在这结束loading事件,异步请求也适宜在这里调用
mounted:挂载元素,获取到DOM节点
updated:若是对数据统一处理,在这里写上相应函数
beforeDestroy:能够作一个确认中止事件的确认框
nextTick:更新数据后当即操做dom
v-show与v-if区别:
v-show是css切换,v-if是完整的销毁和从新建立
使用频繁切换时用v-show,运行时较少改变时用v-if
v-if = ‘false’
v-if是条件渲染,当false的时候不会渲染
开发中经常使用的指令有哪些?
v-model:通常用在表达输入,很轻松的实现表单控件和数据的双向绑定
v-html:更新元素的innerHTML
v-show与v-if:条件渲染,注意两者的区别
使用了v-if的时候,若是值为false,那么页面将不会有这个html标签生成
v-show则是无论值为true仍是false,html元素都会存在,只是css中的display显示或隐藏
v-on:click:能够简写为@click,@绑定一个事件。若是事件触发了,就能够指定事件的处理函数v-for:基于源数据屡次渲染元素或模板块v-bind:当表达式的值改变时,将其产生的连带影响,响应式地做用于DOM
语法:v-bind:title=“msg”简写::title=“msg”
绑定class的数据用法
对象方法v-bind:class = “{‘orange’:isRipe,‘green’:isNotRipe}”
数组方法 v-bind:class= “[class1,class2]”
行内v-bind:style = “{color:color,fontSize:fontSize+‘px’}”
组件之间的传值通讯
父组件给子组件传值
使用props,父组件可使用 props向子组件传递数据
//父组件vue模板father.vue: <template> <child:msg = "message"></child> </template> <script> import child from './child.vue'; export default { components: { child }, data() { return { message:'father message'; } } } </script> //子组件vue模板child.vue: <template> <div>{{msg}}</div> </template> <script> export default { props:{ msg:{ type:String, required:true } } } </script>
子组件向父组件通讯
父组件向子组件传递事件方法,子组件经过$emit触发事件,回调给父组件
//父组件vue模板father.vue: <template> <child @msgFunc="func"></child> </template> <script> import child from './child.vue'; export default { components: { child }, methods: { func(msg) { console.log(msg); } } } </script> //子组件vue模板child.vue: <template> <button @click="handleClick">点我</button> </template> <script> export default { props: { msg: { type:String, required:true } }, methods() { handleClick() { //...... this.$emit('msgFunc'); } } } </script>
非父子,兄弟组件之间通讯
能够经过实例一个vue实例Bus做为媒介,要相互通讯的兄弟组件之中,都引入Bus,而后经过分别调用Bus事件触发和监听来实现通讯和参数传递
//Bus.js能够是这样: import Vue from ‘vue’ export default new Vue() //在须要通讯的组件都引入Bus.js: <template> <button @click="toBus">子组件传给兄弟组件</button> </template> <script> import Bus from ‘../common/js/bus.js’ export default { methods: { toBus() { Bus.$emit('on','来自兄弟组件') } } } </script> //另外一个组件也import Bus.js在钩子函数中监听on事件 import Bus from '../common/js/bus.js' export default { data() { return { message:'' } }, mounted() { Bus.$on('on',(msg) => { this.message = msg }) } }
路由跳转方式
一、<router-link to = 'home'>router - link标签会渲染为<a>标签,咋填template中的跳转都是这种:
二、另外一种是编程是导航,也就是经过js跳转。好比:router.push('/home')
MVVM
M - Model,Model表明数据模型,也能够在Model中定义数据修改和操做的业务逻辑
V - View,View表明UI组件,它负责将数据模型转化为UI展示出来
VM - ViewModel,ViewModel监听模型数据的改变和控制视图行为、处理用户交互,简单理解就是一个同步View和Model的对象,链接Model和View
computed和watch有什么区别?
computed:
一、computed是计算属性,也就是计算值,它更多用于计算值的场景
二、computed具备缓存性,computed的值在getter执行后是会缓存的,只有在它依赖的属性值改变以后,下一次获取computed的值时才会从新调用对应的getter来计算
三、computed适用于计算比较消耗性能的计算场景
watch:
一、更多的是[观察]的做用,相似于某些数据的监听回调,用于观察props $emit或者本组件的值,当数据变化时来执行回调进行后续操做
二、无缓存性,页面从新渲染时值不变化也会执行
小结:
一、当咱们要进行数值计算,并且依赖于其余数据,那么把这个数据设计为computed
二、若是你须要在某个数据变化时作一些事情,使用watch来观察这个数据变化
key
key是为Vue中的vnode标记的惟一id,经过这个key,咱们的diff操做能够更准确、更快速
准确:
若是不加key,那么vue会选择复用节点(Vue的就地更新策略),致使以前节点的状态被保留下来,会产生一系列的bug
快速:
key的惟一性能够被Map数据结构充分利用
组件中的data为何是函数?
为何组件中的data必须是一个函数,而后return一个对象,而new Vue实例里,data能够直接是一个对象?
//data data() { return { message:"子组件", childName:this.name } } //new Vue new Vue({ el:'#app', router, template:'<App/>', components:{App} })
由于组件是用来复用的,JS里对象是引用关系,这样做用域没有隔离,而new Vue的实例,是不会被复用的,所以不存在引用对象问题
Class与Style如何动态绑定?
Class 能够经过对象语法和数组语法进行动态绑定:
//对象语法 <div v-bind:class="{active:isActive,'text-danger':hasError}"></div> data:{ isActive:true, hasError:false } //数组语法 <div v-bind:class="[isActive ? activeClass:'',errorClass]"></div> data:{ activeClass:'active', errorClass:'text-danger' }
Style也能够经过对象语法和数组语法进行动态绑定:
//对象语法 <div v-bind:style="{color:activeColor,fontSize:fontSize + 'px'}"></div> data: { activeColor:'red', fontSize:30 } //数组语法 <div v-bind:style="[styleColor,styleSize]"></div> data:{ styleColor:{ color:'red' }, styleSize:{ fontSize:'23px' } }
vue的单项数据流
全部的prop都使得其父子prop之间造成了一个单向下行绑定:父级prop的更新会向下流动到子组件中,可是反过来则不行。这样会防止从子组件意外改变父级组件的状态,从而致使你的应用的数据流向难以理解
额外的,每次父级组件发生更新时,子组件中全部的prop都将会刷新为最新的值。这意味着你不该该在一个子组件内部改变prop。若是你这样作了,Vue会在浏览器的控制台中发出警告。子组件想修改时,只能经过$emit派发一个自定义事件,父组件接收到后,由父组件修改
有两种常见的试图改变一个prop的情形:
这个prop用来传递一个初始值;这个子组件接下来但愿将其做为一个本地的prop数据来使用
在这种状况下,最好定义一个本地的data属性并将这个prop用做其初始值:
props:['initialCounter'], data:function() { return { counter:this.initialCounter } }
这个prop以一种原始的值传入且须要进行转换
在这种状况下,最好使用这个prop的值来定义一个计算属性
props:['size'], computed: { normalizedSize:function() { return this.size.trim().toLowerCase() } }
keep-alive
keep-alive是Vue内置的一个组件,可使被包含的组件保留状态,避免从新渲染,其有如下特性:
一、通常结合路由和动态组件一块儿使用,用于缓存组件;
二、提供include和exclude属性,二者都支持字符串或正则表达式,include表示只有名称匹配的组件会被缓存,exclude表示任何名称匹配的组件都不会被缓存,其中exclude的优先级比include高;
三、对应两个钩子函数activated和deactivated,当组件被激活时,触发钩子函数activated,当组件被移除时,触发钩子函数deactivated。
v-model的原理
vue项目中主要使用v-model指令在表单input、textarea、select等元素上建立双向数据绑定,咱们知道v-model本质上不过是语法糖,v-model在内部为不一样的输入元素使用不一样的属性并抛出不一样的事件:
text和textarea元素使用value属性和input事件;
checkbox和radio使用checked属性和change事件;
select字段将value做为prop并将change做为事件;
以input表单元素为例:
<input v-model='something'> // 至关于 <input v-bind:value="something" v-on:input="something=$event.target.value">
若是在自定义组件中,v-model默认会利用名为value的prop和名为input的事件,以下所示:
//父组件 <ModelChild v-model="message"></ModelChild> //子组件 <div>{{value}}</div> props:{ value:String }, methods:{ test1() { this.$emit('input','小红') }, },
nextTick()
在下次DOM更新循环结束以后执行延迟回调。在修改数据以后,当即使用的这个回调函数,获取更新后的DOM
//修改数据 vm.msg = "Hello" //DOM还未更新 Vue.nextTick(function() { //DOM更新 })
vue插槽
单个插槽:
当子组件模板只有一个没有属性的插槽时,父组件传入的整个内容片断将插入到插槽所在的DOM位置,并替换掉插槽标签自己
命名插槽:
solt元素能够用一个特殊的特性name来进一步配置如何分发内容。
多个插槽能够有不一样的名字。这样能够将父组件模板中slot位置和子组件slot元素产生关联,便于插槽内容对应传递
做用域插槽:
能够访问组件内部数据的可复用插槽(reusable slot)。在父级中,具备特殊特性slot-scope的<template>元素必须存在,表示它是做用域插槽的模板。slot-scope的值将被用做一个临时变量名,此变量接收从子组件传递过来的prop对象
vue-router有哪几种导航钩子
第一种:是全局导航钩子:router.beforeEach(to,from,next),做用:跳转前进行判断拦截
第二种:组件内的钩子
第三种:单独路由独享组件
vuex
vuex是什么?
vuex就是一个仓库,仓库里放了不少对象。其中state就是数据源存放地,对应于通常vue对象里面的data
state里面存放的数据是响应式的,vue组件从store读取数据,如果store中的数据发生改变,依赖这些数据的组件也会发生更新
它经过mapState把全局的state和getters映射到当前组件的computed计算属性
Vuex有5种属性:分别是state、getter、mutation、action、module;
state
Vuex使用单一状态树,即每一个应用将仅仅包含一个store实例,但单一状态树和模块化并不冲突。存放的数据状态,不能够直接修改里面的数据
mutations
mutations定义的方法动态修改Vuex的store中的状态或数据
getters
相似vue的计算属性,主要用来过滤一些数据
action
actions能够理解为经过将mutations里面处理数据的方法变成可异步的处理数据的方法,简单的说就是异步操做数据。view层经过store.dispath来分发action
总结:
vuex通常用于中大型web单页应用中对应用的状态进行管理,对于一些组件间关系较为简单的小型应用,使用vuex的必要性不是很大,由于彻底能够用组件prop属性或者事件来完成父子组件之间的通讯,vuex更多地用于解决跨组件通讯以及做为数据中心集中式存储数据。
对vue项目能够进行哪些优化?
代码层面的优化
v-if和v-show区分使用场景
computed和watch区分使用场景
v-for遍历必须为item添加key,且避免同时使用v-if
长列表性能优化
事件的销毁
图片资源懒加载
路由懒加载
第三方插件的按需引入
优化无限列表性能
服务端渲染SSR or 预渲染
Webpack层面的优化
Webpack对图片进行压缩
减小ES6转为ES5的冗余代码
提取公共代码
模板预编译
提取组件的CSS
优化SourceMap
构建结果输出分析
Vue项目的编译优化
基础的Web技术的优化
开启gzip压缩
浏览器缓存
CDN的使用
使用Chrome Performance查找性能瓶颈