置顶
type
status
slug
summary
tags
category
icon
password
URL
date
前端介绍
什么是前端?
前端是软体系统中直接和用户交互的部分。简而言之就是
我们肉眼可见的页面与操作
通过 HTML/CSS/Javascript 三剑客展示页面的过程。
- HTML 用于描述页面内容
- CSS 用于描述内容样式
- Javascript 用于将描述静态内容的操作(按钮、输入框、与后端交互等)
用画龙点睛来形容三者的关系: HTML = 龙的骨架 、CSS = 龙的皮肤、Javascript = 龙的眼睛
HTML+CSS+Javascript = 龙
前端页面加载过程
前端交互
当我们在前端进行交互改变了页面变化时(例如弹出一个弹框),逻辑上我们要通过 js 对 HTML的内容(DOM 树)进行更改,手动更新页面的内容,需要维护一大堆的 HTML 和变量拼接的动态内容。
后面出现了 jQuery 框架,提升了 DOM 元素的操作性,但依然难以避免代码的可读性、可维护性上存在的一些问题。
流程大概如下:
监听操作 -> 获取数据变量 -> 使用数据拼接成 HTML 模板 -> 将 HTML 内容塞到页面对应的地方 -> 将 HTML 片段内需要监听的点击等事件进行绑定。
VUE 介绍
VUE 渲染内容过程
- 解析语法生成 AST。
AST是指抽象语法树(abstract syntax tree),或者语法树(syntax tree),是源代码的抽象语法结构的树状表现形式。Vue在mount过程中,template会被编译成AST语法树。然后,经过generate(将AST语法树转化成render function字符串的过程)得到render函数,返回VNode。VNode是Vue的虚拟DOM节点,里面包含标签名、子节点、文本等信息
例如 HTML 中的 <div> 标签会变成 一个 js 类型的 div 对象。该对象记录了 <div> 大部分信息,例如需要绑定哪些变量、怎样的方式来拼接(v-if、v-for)、绑定了怎样的事件监听事件等。(不是包含所有信息的原因是,生成过程中会删除掉无效信息。)
- 根据 AST 结果,完成 data 数据初始化。
- 根据 AST 结果和 data 数据绑定情况,生成虚拟 DOM。
- 排除无效 DOM 元素,并在构建过程可进行报错。
- 使用自定义组件的时候,可匹配出来。
- 可方便地实现数据绑定、事件绑定等功能。
- 为虚拟 DOM Diff 过程打下铺垫。
- HTML 转义(预防 XSS 漏洞)。
4. 将虚拟 DOM 生成真正的 DOM 插入到页面中,此时页面会被渲染。
- 比较新旧两棵虚拟 DOM 树的差异,得道差异
- 如果DOM 内容发生变化,把差异重新渲染到页面。
- 最终注销清空页面内容,移除绑定事件、监听等
数据绑定(响应式数据)
数据绑定过程
- 解析语法生成 AST。
- 根据 AST 结果生成 DOM。
- 将数据绑定更新至模板。(添加数据绑定)
数据监听
依赖Getter/Setter。
每个组件实例都对应一个 watcher
实例,它会在组件渲染的过程中把“接触”过的数据 property 记录为依赖。之后当依赖项的 setter 触发时,会通知 watcher,从而使它关联的组件重新渲染。
Vue2.0 不能检测数组和对象的变化
vue 在在源码中对数组做了忽略
- 通过索引访问或设置对应元素的值时,可以触发
getter
和setter
方法
- 通过
push
或unshift
会增加索引,对于新增加的属性,需要再手动初始化才能被observe
。
- 通过
pop
或shift
删除元素,会删除并更新索引,也会触发setter
和getter
方法。
绑定对象或者数组的时候,需要注意以下问题
-
data
中的对象:Vue 无法检测到对象属性的添加或删除,当实例被创建时就已经存在于data
中的属性才是响应式的,新增的属性等都不会触发视图的更新。
-
data
中的数组:除了特殊的数组操作如push()
、pop()
、shift()
、unshift()
、splice()
、sort()
、reverse()
这些方法之外,数组中某个元素被替换、更新这种操作是无法触发视图更新的
生命周期
- 解析语法生成 AST。
- 根据 AST 结果,完成 data 数据初始化。
- 根据 AST 结果和 data 数据绑定情况,生成虚拟 DOM。
- 将虚拟 DOM 生成真正的 DOM 插入到页面中,此时页面会被渲染。
当我们绑定的数据进行更新的时候,又会产生以下这些过程:
- 框架接收到数据变更的事件,根据数据生成新的虚拟 DOM 树。比较新旧两棵虚拟 DOM 树,得到差异。
- 把差异应用到真正的 DOM 树上,即根据差异来更新页面内容。
当我们清空页面内容时,还有:
- 注销实例,清空页面内容,移除绑定事件、监听器等。
生命周期钩子 | 说明 | 对应上述步骤 |
beforeCreate | 初始化实例前, data 、methods 等不可获取 | vue实例初始化之前调用 |
created | 实例初始化完成,此时可获取 data 里数据和methods 事件,无法获取 DOM | vue实例初始化之后调用 |
beforeMount | 虚拟 DOM 创建完成,此时未挂载到页面中, vm.$el 可获取未挂载模板 | 挂载到DOM树之前调用 |
mounted | 数据绑定完成,真实 DOM 已挂载到页面, vm.$el 可获取真实 DOM | 挂载到DOM树之后调用 |
beforeUpdate | 数据更新,DOM Diff 得到差异,未更新到页面 | 数据更新之前调用 |
updated | 数据更新,页面也已更新 | 数据更新之后调用 |
beforeUnmount | 实例销毁前 | vue实例销毁之前调用 |
unmounted | 实例销毁完成 | vue实例销毁之后调用 |
VUE 路由
前端路由一般有两种模式
- History 模式
- 使用
window.history.back()
、window.history.forward()
和window.history.go()
方法来完成在用户历史记录中向后和向前的跳转。 history.pushState()
和history.replaceState()
方法,它们分别可以添加和修改历史记录条目
结合
popstate
事件、pushState()
和replaceState()
来完成完整的路由监听和修改能力。- Hash 模式
主要依赖 Location 对象的 hash 属性(
location.hash
)和hashchange
事件类似于后端 url 的匹配?
Vue Router 实现
在 Vue Router 中路由模式的使用方式被抹平了,不管是 History 模式还是 Hash 模式,最终暴露出来的都是通用的
go(
、push()
、replace()
、ensureURL()
、getCurrentLocation()
这几种方法。路由模式 | 说明 | 示例 |
hash | 使用 URL hash 值来作路由(支持所有浏览器,包括不支持 HTML5 History Api 的浏览器) | |
history | 充分利用 history.pushState API 来完成 URL 跳转而无须重新加载页面 | |
abstract | 支持所有 JavaScript 运行环境,如 Node.js 服务器端(在 Node.js 端会自动设置该模式为默认值)如果发现没有浏览器的 API,路由会自动强制进入这个模式 |