1. 为何组件的data必须是一个函数
目的是为了防止多个组件实例对象之间共用一个data,产生数据污染
采用函数的形式,initData时会将其作为工厂函数都会返回全新data对象
组件中的data写成一个函数,数据以函数返回值形式定义,这样每复用一次组件,就会返回一份新的data,类似于给每个组件实例创建一个私有的数据空间,让各个组件实例维护各自的数据。而单纯的写成对象形式,就使得所有组件实例共用了一份data,就会造成一个变了全都会变的结果。
2. vue的常用指令
v-model 多用于表单元素实现双向数据绑定
v-for 循环数组或json
v-show 显示内容,通过display属性来控制元素的显示隐藏
v-hide 隐藏内容
v-if 显示与隐藏(dom元素的删除添加)
v-else 必须和v-if连用,不能单独使用,否则会报错,模板编译错误
v-bind 给元素绑定属性
v-on 给标签绑定事件
v-text 解析文本
v-html 解析html标签
v-clock 解决插值表达式闪烁的问题
v-pre 跨过当前标签不解析
3. v-if和v-show的区别
相同点:都可以动态的控制dom元素的显示隐藏
不同点:v-if控制dom元素的显示隐藏是讲dom元素整个添加或删除
v-show控制dom元素的显示隐藏是为dom元素添加css的样式,设置none或者是block,dom元素是还存在的`
使用场景: v-if更适合数据的筛选和初始渲染
v-show更适合元素的切换
4. vue生命周期
创建前后:beforecreate data中的数据还未定义,所以还不能使用
created 最早开始使用data和methods中数据的钩子函数
挂载前后:beforemount 指令已经解析完毕内存中已经生成dom树,还没有渲染到本地
mounted dom已经渲染完毕,最早可以操作dom元素的钩子函数
更新前后:beforeupdate 当data的数据发生改变会执行的钩子,内存更新,但是dom节点还未更新
updated 数据更新完成之后触发的方法,dom节点已经更新
销毁前后:beforedestroy 即将销毁data和methods中的数据此时还是可以使用的,可以做一些释放内存的操作
destoryed已经销毁完毕
activated keep-alive专属,组件被激活时调用
deactivated keep-alive专属,组件被销毁时调用
5. vue双向数据绑定
数据双向绑定:**是结合订阅发布模式,通过object.defineProperty来实现数据双向绑定,observer会对data里面所有的属性进行数据劫持和数据代理,给数据对象的某个值赋值,就会触发setter,那么就能监听到了数据变化,watcher是监听data里面所有的属性,当属性被改变之后才会被触发,自身必须有一个update()方法,compile 对模版进行解析,将模板中的变量替换成数据,然后初始化渲染页面视图,添加监听数据的订阅者,一旦数据有变动,收到通知,更新视图,对template模版 html指令,小胡子表达式{{}}的解析,v-model只是双向数据绑定最直观的表现形式
vue中的v-model可以实现双向绑定,其核心思想通过Object.defineProperty来对Vue的数据进行数据劫持
6.Vue中的虚拟dom
对复杂的文档DOM结构,提供一种方便的工具,进行最小化的DOM操作
Vue之所以运行高效,因为采用了虚拟dom,减少了对真实的dom操作
虚拟dom是利用js描述元素与元素的关系。 好处:是可以快速的渲染和高效的更新元素,提高浏览器的性能
创建虚拟DOM就是为了更好将虚拟的节点渲染到页面视图中,所以虚拟DOM对象的节点与真实DOM的属性一一照应
虚拟DOM 表现为一个 Object对象。并且最少包含标签名 (tag)、属性 (attrs) 和子元素对象 (children) 三个属性
创建虚拟DOM就是为了更好将虚拟的节点渲染到页面视图中,所以虚拟DOM对象的节点与真实DOM的属性一一照应
通过VNode
,vue可以对这颗抽象树进行创建节点,删除节点以及修改节点的操作,经过diff算法得出一些需要修改的最小单位,再更新视图,减少了dom操作,提高了性能
vue中虚拟 DOM 最大的优势是 diff 算法,减少 JavaScript 操作真实 DOM 的带来的性能消耗。虽然这一个虚拟 DOM带来的一个优势,但并不是全部。
createElement 创建 VNode 的过程,每个 VNode 有 children,children
每个元素也是一个VNode,这样就形成了一个虚拟树结构,用于描述真实的DOM树结构
7.vue中的diff算法
diff算法就是进行虚拟节点对比,并返回一个patch对象,用来存储两个节点不同的地方,最后用patch记录的消息去局部更新Dom。**简单来说:**diff的过程就是调用名为patch的函数,比较新旧节点,一边比较一边给真实的DOM打补丁
特点:
-
比较只会在同层级进行, 不会跨层级比较
-
在diff比较的过程中,循环从两边向中间比较
diff 算法的在很多场景下都有应用,在 vue 中,作用于虚拟 dom 渲染成真实 dom 的新旧 VNode 节点比较
Diff算法的步骤:
- 用 JavaScript 对象结构表示 DOM 树的结构;然后用这个树构建一个真正的 DOM 树,插到文 档当中
- 当状态变更的时候,重新构造一棵新的对象树。然后用新的树和旧的树进行比较(diff),记录两棵树差异
- 把第二棵树所记录的差异应用到第一棵树所构建的真正的DOM树上(patch),视图就更新了
比较方式
diff整体策略为:深度优先,同层比较
1.比较只会在同层级进行, 不会跨层级比较
2.比较的过程中,循环从两边向中间收拢
原理分析
当数据发生改变时,set方法会调用Dep.notify通知所有订阅者Watcher,订阅者就会调用patch给真实的DOM打补丁,更新相应的视图
8.Vue组件通信
父传递子如何传递
(1)在父组件的子组件标签上绑定一个属性,挂载要传输的变量 (2)在子组件中通过props来接受数据,props(铺rua铺思)可以是数组也可以是对象,接受的数据可以直接使用 props:[“属性名”] props:{属性名:数据类型}
子传递父如何传递
(1)在父组件的子组件标签上自定义一个事件,然后调用需要的方法
(2)在子组件的方法中通过 this.$emit(一没特)(“事件”)来触发在父组件中定义的事件,数据是以参数的形式进行传递的
兄弟组件如何通信
(1)在src中新建一个Bus.js的文件,然后导出一个空的vue实例
(2)在传输数据的一方引入Bus.js 然后通过Bus. e m i t ( “ 事 件 名 ” , " 参 数 " ) 来 来 派 发 事 件 , 数 据 是 以 emit(“事件名”,"参数")来来派发事件,数据是以 emit(“事件名”,"参数")来来派发事件,数据是以emit()的参数形式来传递
(3)在接受的数据的一方 引入 Bus.js 然后通过 Bus.$on(“事件名”,(data)=>{data是接受的数据})
9.vuex
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储和管理程序的所有组件的数据
1、state (思dei特) 所有的数据都存储在state中 state是一个对象
2、mutations (谬忒深)可以直接操作state中的数据
3、actions (啊k深zi) 只能调用mutations的方法 ,包含异步操作,使用dispatch(滴死拍吃)调用
4、getters (盖ter死) 类似计算属性实现对state中的数据做一些逻辑性的操作
5、Modules(妈jiou 死) 将仓库分模块存储
10.vue监听和深度监听watch
watch可以让我们监控一个值的变化,从而做出相应的反应。通过watch属性可以监控data属性中属性值的变化,定义监控时,属性值对应的是一个监控处理函数。
deep:代表深度监控,不仅监控person变化,也监控person中属性变化。
handler:就是以前的监控处理函数