vue 双向绑定原理
mvvm 双向绑定, 采用数据劫持结合发布者 - 订阅者模式的方式, 通过 Object.defineProperty()来劫持各个属性的 setter,getter, 在数据变动时发布消息给订阅者, 触发相应的监听回调.
几个要点:
1, 实现一个数据监听器 Observer, 能够对数据对象的所有属性进行监听, 如有变动可拿到最新值并通知订阅者
2, 实现一个指令解析器 Compile, 对每个元素节点的指令进行扫描和解析, 根据指令模板替换数据, 以及绑定相应的更新函数
3, 实现一个 Watcher, 作为连接 Observer 和 Compile 的桥梁, 能够订阅并收到每个属性变动的通知, 执行指令绑定的相应回调函数, 从而更新视图
4,mvvm 入口函数, 整合以上三者
具体步骤:
需要 observe 的数据对象进行递归遍历, 包括子属性对象的属性, 都加上 setter 和 getter
这样的话, 给这个对象的某个值赋值, 就会触发 setter, 那么就能监听到了数据变化
compile 解析模板指令, 将模板中的变量替换成数据, 然后初始化渲染页面视图, 并将每个指令对应的节点绑定更新函数, 添加监听数据的订阅者, 一旦数据有变动, 收到通知, 更新视图
Watcher 订阅者是 Observer 和 Compile 之间通信的桥梁, 主要做的事情是:
在自身实例化时往属性订阅器 (dep) 里面添加自己
自身必须有一个 update() 方法
待属性变动 dep.notice() 通知时, 能调用自身的 update() 方法, 并触发 Compile 中绑定的回调, 则功成身退.
MVVM 作为数据绑定的入口, 整合 Observer,Compile 和 Watcher 三者, 通过 Observer 来监听自己的 model 数据变化, 通过 Compile 来解析编译模板指令, 最终利用 Watcher 搭起 Observer 和 Compile 之间的通信桥梁, 达到数据变化 -> 视图更新; 视图交互变化(input) -> 数据 model 变更的双向绑定效果.
描述下 vue 从初始化页面 -- 修改数据 -- 刷新页面 UI 的过程?
当 Vue 进入初始化阶段时, 一方面 Vue 会遍历 data 中的属性, 并用 Object.defineProperty 将它转化成 getter/setter 的形式, 实现数据劫持(暂不谈 Vue3.0 的 Proxy); 另一方面, Vue 的指令编译器 Compiler 对元素节点的各个指令进行解析, 初始化视图, 并订阅 Watcher 来更新试图, 此时 Watcher 会将自己添加到消息订阅器 Dep 中, 此时初始化完毕.
当数据发生变化时, 触发 Observer 中 setter 方法, 立即调用 Dep.notify(),Dep 这个数组开始遍历所有的订阅者, 并调用其 update 方法, Vue 内部再通过 diff 算法, patch 相应的更新完成对订阅者视图的改变.
Vue 的生命周期
vue 生命周期详解 https://juejin.im/post/5c6d48e36fb9a049eb3c84ff
beforeCreate 和 created
beforeMount 和 mounted
beforeUpdate 和 updated
beforeDestory 和 destoryed
activated 和 deactivated
Vue 组件间通信有哪些方式
Vue 组件间通信六种方式 https://juejin.im/post/5cde0b43f265da03867e78d3
- props/$emit
- $emit/$on
- vuex
- $attrs/$listeners
- provide/inject
$parent/$children 与 ref
watch,methods 和 计算属性的区别
watch 为了监听某个响应数据的变化. 计算属性是自动监听依赖值的变化, 从而动态返回内容, 主要目的是简化模板内的复杂运算. 所以区别来源于用法, 只是需要动态值, 那就用计算属性; 需要知道值的改变后执行业务逻辑, 才用 watch.
methods 是一个方法, 它可以接受参数, 而 computed 不能, computed 是可以缓存的, methods 不会. computed 可以依赖其他 computed, 甚至是其他组件的 data.
vue 中怎么重置 data
使用 Object.assign(),vm.$data 可以获取当前状态下的 data,vm.$options.data 可以获取到组件初始化状态下的 data.
Object.assign(this.$data, this.$options.data())
组件中写 name 选项有什么作用?
项目使用 keep-alive 时, 可搭配组件 name 进行缓存过滤
DOM 做递归组件时需要调用自身 name
vue-devtools 调试工具里显示的组见名称是由 vue 中组件 name 决定的
vue-router 有哪些钩子函数
官方文档: vue-router 钩子函数
全局前置守卫 router.beforeEach
全局解析守卫
router.beforeResolve
全局后置钩子 router.afterEach
路由独享的守卫 beforeEnter
组件内的守卫 beforeRouteEnter,beforeRouteUpdate,beforeRouteLeave
前端路由简介以及 vue-router 实现原理 https://juejin.im/post/5b10b46df265da6e2a08a724
route 和 router 的区别是什么?
route 是 "路由信息对象", 包括 path,params,hash,query,fullPath,matched,name 等路由信息参数.
router 是 "路由实例对象", 包括了路由的跳转方法(push,replace), 钩子函数等.
说一下 Vue 和 React 的认识, 做一个简单的对比
1. 监听数据变化的实现原理不同
Vue 通过 getter/setter 以及一些函数的劫持, 能精确快速的计算出 Virtual DOM 的差异. 这是由于它在渲染过程中, 会跟踪每一个组件的依赖关系, 不需要重新渲染整个组件树.
React 默认是通过比较引用的方式进行的, 如果不优化, 每当应用的状态被改变时, 全部子组件都会重新渲染, 可能导致大量不必要的 VDOM 的重新渲染.
Vue 不需要特别的优化就能达到很好的性能, 而对于 React 而言, 需要通过 PureComponent/shouldComponentUpdate 这个生命周期方法来进行控制. 如果你的应用中, 交互复杂, 需要处理大量的 UI 变化, 那么使用 Virtual DOM 是一个好主意. 如果你更新元素并不频繁, 那么 Virtual DOM 并不一定适用, 性能很可能还不如直接操控 DOM.
为什么 React 不精确监听数据变化呢? 这是因为 Vue 和 React 设计理念上的区别, Vue 使用的是可变数据, 而 React 更强调数据的不可变.
2. 数据流的不同
Vue 中默认支持双向绑定, 组件与 DOM 之间可以通过 v-model 双向绑定. 但是, 父子组件之间, props 在 2.x 版本是单向数据流
React 一直提倡的是单向数据流, 他称之为 onChange/setState()模式.
不过由于我们一般都会用 Vuex 以及 Redux 等单向数据流的状态管理框架, 因此很多时候我们感受不到这一点的区别了.
3. 模板渲染方式的不同
在表层上, 模板的语法不同
React 是通过 JSX 渲染模板
而 Vue 是通过一种拓展的 html 语法进行渲染
在深层上, 模板的原理不同, 这才是他们的本质区别:
React 是在组件 JS 代码中, 通过原生 JS 实现模板中的常见语法, 比如插值, 条件, 循环等, 都是通过 JS 语法实现的
Vue 是在和组件 JS 代码分离的单独的模板中, 通过指令来实现的, 比如条件语句就需要 v-if 来实现
对这一点, 我个人比较喜欢 React 的做法, 因为他更加纯粹更加原生, 而 Vue 的做法显得有些独特, 会把 HTML 弄得很乱. 举个例子, 说明 React 的好处: react 中 render 函数是支持闭包特性的, 所以我们 import 的组件在 render 中可以直接调用. 但是在 Vue 中, 由于模板中使用的数据都必须挂在 this 上进行一次中转, 所以我们 import 一个组件完了之后, 还需要在 components 中再声明下, 这样显然是很奇怪但又不得不这样的做法.
Vue 的 nextTick 的原理是什么?
1. 为什么需要 nextTick
Vue 是异步修改 DOM 的并且不鼓励开发者直接接触 DOM, 但有时候业务需要必须对数据更改 -- 刷新后的 DOM 做相应的处理, 这时候就可以使用 Vue.nextTick(callback)这个 API 了.
2. 理解原理前的准备
首先需要知道事件循环中宏任务和微任务这两个概念(这其实也是面试常考点). 请阅大佬文章 -- 彻底搞懂浏览器 Event-loop https://juejin.im/post/5c947bca5188257de704121d
常见的宏任务有 script, setTimeout, setInterval, setImmediate, I/O, UI rendering
常见的微任务有 process.nextTick(Node.JS),Promise.then(), MutationObserver;
3. 理解 nextTick
而 nextTick 的原理正是 vue 通过异步队列控制 DOM 更新和 nextTick 回调函数先后执行的方式. 如果大家看过这部分的源码, 会发现其中做了很多 isNative()的判断, 因为这里还存在兼容性优雅降级的问题. 可见 Vue 开发团队的深思熟虑, 对性能的良苦用心.
如果你比较了解了前面的事件循环原理, 推荐你看看这篇文章 请阅大佬文章 -- 全面解析 Vue.nextTick 实现原理 https://mp.weixin.qq.com/s/mCcW4OYj3p3471ghMBylBw
Vuex 有哪几种属性
有五种, 分别是 State,Getter,Mutation,Action,Module
vue-cli 替我们做了哪些工作?
首先需要知道 vue-cli 是什么? 它是基于 vue.js 进行快速开发的完整系统, 也可以理解成是很多 NPM 包的集合. 其次, vue-cli 完成的功能有哪些?
.vue 文件 --> .JS 文件
ES6 语法 --> ES5 语法
Sass,Less,Stylus --> CSS
对 jpg,PNG,font 等静态资源的处理
热更新
定义环境变量, 区分 dev 和 production 模式
...
如果开发者需要补充或修改默认设置, 需要在 package.JSON 同级下新建一个 vue.config.JS 文件
最后送上一份大礼: vue 248 个知识点 (面试题) 为你保驾护航
来源: https://www.cnblogs.com/chenwenhao/p/11258895.html