Vue的基础概念

栏目 Vue

MVVM #

MVC #

传统的mvc,使用控制器更新模型,视图从模型中获取数据。用户生成数据通过控制器更新模型,通知视图更新。 m-model 本地数据,数据库数据 v-view 视图 模板 问题,c承担的责任太大

VM #

一般的产品都是先通过接口从数据库读取数据,然后数据处理后展示到视图上。 用户产生数据,然后通过接口写入数据库。

vm-viewmodel ,这里的vm值关心数据和业务处理,不管view如何处理数据。 这样view和model 就独立了。把一些逻辑放到vm里,让其他view使用这个vm

vue里,vm就是组件实例,v是模板。model在引入vuex的情况下可以和组件分离。

mvvm,通过vm把视图状态和用户状态分离成一个抽象。

那你自己实现一个 mvvm? 这里应该放一个地址,还真有。

Virtual dom #

这个在《深入浅出 vue》里看过。 dom操作很耗资源。我们把dom映射成对象,这个对象里有很多细节来描述dom结构。 我们平时操作js对象,然后再通过判断哪些变了,然后局部更新。

vdom 核心库这块,vue好像是拿 snabbdom 改的,这是地址 https://zhuanlan.zhihu.com/p/35674318

  • h() render渲染node节点,把js对象解析为node节点
  • patch(oldNode, newNode) 进行对比,找出差异

借助 snabbdom 我们可以自己实现一个 vdom,实现局部渲染的效果。

难点是区分差异,这就是diff算法了。

  1. 建立 virtualDOM树
  2. diff
  3. 差异更新

diff算法 #

diff常见,对比文件变化。这里是为了找到js对象的区别。

两个核心函数:

  • patch(container, vnode) 从js编程dom节点,递归实现dom节点渲染。
  • patch(vnode, newVnode) 第一步算法需要判断tagName是否相同,如果不同就是被换了。如果没换就判断是否有子元素。

创建和更新。

diff的过程不能完整遍历,这样太麻烦。考虑到很少跨越层次移动DOM,只需要对比同层的节点,而不是跨层对比。

  • 从上到下,从左到右递归遍历对象,给节点添加索引,方便以后对比差异
  • 一旦节点有子元素,就判断元素是否不同

比如一个数据发生了变化,这就用到key了。

https://github.com/livoras/blog/issues/13 https://juejin.im/post/59bfbd736fb9a00a52065ec7

总结 #

virtual DOM 优势

  • 提供性能。当然了静态变化还是 InnerHTML 更好
  • 作为兼容层,可以跨端,反正都是对象的映射
  • 高度抽象,从此之后不再需要操作dom了

vue三大技术核心 #

  • 响应式。如何监听到data发生变化
  • 模板。模板被解析
  • 渲染。如何渲染成页面

响应式 #

如何监听js对象的变化,那就是 Object.defineProperty 或者 proxy 在js中如何侦测一个对象的变化?

  • Objecct.defineProperty
  • Proxy

vue用的是前者,有些缺陷如果改为proxy会解决,但后者有兼容问题,还是主要讲原理。


路由 #

监听url变化,然后匹配规则。

  • hash
  • history

hash #

网址#参数发生变化,监听 hashchange 事件。 兼容性好

histroy #

通过 history.pushStatehistory.replaceState 也就是直接操作历史记录。 监听的是popstate事件

哪种好?看情况。

vue配置路由:

  • 引入 vue vueRouter
  • 引入 pages
  • vue使用router插件
  • 定义路由
  • 导出

生命周期 #

  • beforeCreate 拿不到 props 和 data
  • created 可以访问数据了
  • beforeMount开始创建 vdom
  • monted渲染
  • beforeUpdateupdate

keep-alive独有的生命周期

  • activated

  • deactivated 切换不销毁,会缓存,然后执行后者。恢复缓存时候执行前者

  • beforeDestroy

  • destoryed

组件通信 #

父子组件通信 #

props-emit v-model 会解析成 prop和 input,语法糖。 .sync是语法糖,简单实现子向父组件通信。

兄弟组件通信 #

通过查找父组件 this.$parent.$children通过name查询

跨多层次组件通信 #

provide/inject一般不推荐使用

  • A组件,provide对象数据
  • B组件, inject 能收到传来的数据

父组件A,跨多层次的子组件B

任意组件 #

vuex 和 event-bus 了

computed watch #

计算属性,依赖其他属性计算值,有缓存 监听,可以执行回调

为什么模板里data是函数 #

如果是对象,那就随便改了,如果是函数,每次都是新的。

响应式原理 #

这个书里面很详细了,可以单独开一篇 Object.defineProperty 有 了对象的操作,还差数组,所以有了第二章的内容

NxtTick 原理分析 #

vue2.4之前,都是 microtask 但 microtask 优先级高,可能会比事件冒泡还快。如果使用macrotask 会太慢,渲染问题。 所以,默认 microtask ,特殊情况下macrotask 比如 v-on

推荐了一本书 https://ustbhuangyi.github.io/vue-analysis/

vuex #

还是要看文档vuex

使用过程:

  • 引入 vue vuex
  • vue使用插件 vuex
  • 定义 store
    • 定义 state
    • mutations
    • actions
    • getters

初始化main.js 里,记得导入 store 根组件new Vue注册store