Web 设计模式
MVC
Model-View-Controller
- M 就是 Model,即数据层。数据相关的操作,包括数据的增删改查
- V 就是 View,即视图层。用户界面渲染逻辑,即用户能看得到的界面
- C 就是 Controller,即控制器。M 和 V 之间通信的桥梁,负责处理事件,然后调用 M 和 V 更新数据和视图
MVP
Model-View-Presenter
- M 就是 Model,即数据层。数据相关的操作,包括数据的增删改查
- V 就是 View,即视图层。用户界面渲染逻辑,即用户能看得到的界面
- P 就是 Presenter,即响应视图指令,同时进行相关业务处理,必要时候获调用 Model 获取底层数据,返回指令结果到视图,驱动视图渲染
MVVM
Model-View-ViewModel
- M 就是 Model,即数据层。数据相关的操作,包括数据的增删改查
- V 就是 View,即视图层。用户界面渲染逻辑,即用户能看得到的界面
- VM 就是 ViewModel,同步 M 和 V 之间的关联,其实现同步关联的核心是
DOM Listeners
和Data Bindings
两个工具。DOMListeners
用于监听 V 中DOM
的变化,并会选择性的传给 M;Data Bindings
工具用于监听 M 数据变化,并将其更新给 V。
vue 的生命周期
vue实例从创建到销毁的过程
钩子 | 描述 | 使用场景 |
---|---|---|
beforeCreate 创建前 | 刚开始初始化实例,拿不到实例里的任何东西 | 添加 loading 事件 |
created 创建后 | 实例创建完成,已完成数据观测,属性和方法初始化,$data 有了。然而,挂载阶段还没开始,$el 还没有。 | 请求数据 |
beforeMount 挂载前 | 在挂载之前被调用,相关的render 函数首次被调用。$el 初始化完成,但还没挂载 | |
mounted 挂载后 | 已完成挂载和数据渲染,可以拿到dom 节点 | 操作组件 dom ,请求和修改数据 |
beforeUpdate 更新前 | 数据更新之前,数据已改变,但 dom 未更新 | 在更新前访问现有的dom ,如手动移除添加的事件监听器 |
updated 更新后 | 完成虚拟 dom 的重新渲染和打补丁; 组件 dom 已完成更新, | 执行依赖的 dom 操作,注意:不要在此函数中操作数据,会陷入死循环的 |
beforeDestroy 销毁前 | 实例销毁前,实例仍然可用 | 清楚一些的资源,比如定时器、事件绑定等等 |
destroyed 销毁后 | 实例销毁后,这时组件已经没有了,无法操作里面的任何东西 |
beforeMount
执行顺序是先父后子
mounted
执行顺序是先子后父
组件通信
vuex
eventBus
父子组件通信
props
、 $emit
、 $parent
、 $children
、 provide inject
、 $refs
vue 双向绑定原理
简说:数据劫持结合“发布-订阅”模式的方式,通过 Object.defineProperty()
的 set
和 get
,在数据变动时发布消息给订阅者触发监听
细说:vue 每个组件实例都对应一个 watcher
(订阅者) 实例,会把组件实例渲染过程中的数据记录为依赖(也就是 Object.defineProperty
的 get
),当依赖项的 set
触发时,会通知 watcher
,从而使它关联的组件重新渲染
v-if 和 v-show 区别
v-if
直接对标签进行创建或销毁
v-show
对标签的 display 属性进行切换
v-if
的性能开销会比 v-show
大,切换频繁的标签更适合使用 v-show
。
v-for 中 key 的作用
key
的作用主要是为了高效的更新虚拟 DOM
key
是节点标识。v-for
默认使用就地复用策略,列表数据修改的时候,他会根据 key
值去判断某个值是否修改,如果修改,则重新渲染这一项,否则复用之前的元素。
v-if 和 v-for 不能同时使用
v-for
比 v-if
优先级高,一起使用的话,每次 v-for
都会执行 v-if
,造成不必要的计算,影响性能,尤其是当之需要渲染很小一部分的时候
computed、 watch、methods的区别
名称 | 描述 | 使用场景 |
---|---|---|
computed 计算属性 | 支持缓存,只有依赖数据发生变化时,才会重新进行计算;不支持异步操作。开销小 | 当一个属性需要依赖多个data 中的属性时 |
watch 侦听属性 | 不支持缓存,只要数据发生变化,就会执行侦听函数,支持异步操作。开销大 | 当需要在数据变化时执行异步或开销较大的操作时 |
methods 方法 | 函数调用,不支持缓存,只要页面重新渲染,就会重新执行 | 封装工具类函数、处理业务逻辑等 |
$nextTick
接受一个回调函数,延迟到下次 DOM
更新循环之后执行
keep-alive
内置抽象组件。
包裹动态组件时,会缓存不活动的组件实例。而不是销毁它们。 其主要用于保留组件状态(保留在内存中),避免重新渲染。
include
- 字符串或正则表达式。只有名称匹配的组件会被缓存。
exclude
- 字符串或正则表达式。任何名称匹配的组件都不会被缓存。
max
- 数字。最多可以缓存多少组件实例。
Vuex
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式
核心 | 描述 | 组件类使用 | 辅助函数 |
---|---|---|---|
state | 数据源,状态 | $store.state | mapState |
getters | 计算属性 | $store.getters | mapGetters |
mutations | 改变状态的唯一方法 | $store.commit | mapMutations |
actions | 提交 mutation ,支持异步 | store.dispatch | mapActions |
modules | 子模块,命名空间:namespaced | 路劲访问(name/ ) | createNamespacedHelpers |
vue-router 导航钩子
全局钩子
beforeEach((to, from, next) => { })
挂载到进入路由之前,在进入路由之前执行afterEach((to, from) => { })
挂载到进入路由之后,在进入路由之后执行
路由独享钩子
beforeEnter(to, from, next) { }
进入之前调用
组件内的钩子
beforeRouteEnter(to, from, next) { }
进入之前调用beforeRouteLeave (to, from, next) { }
进入之后调用beforeRouteUpdate(to, from, next) { }
在当前路由改变,但是该组件被复用时调用,比如:动态路由
$route 和 $router 的区别
router
是全局路由对象,VueRouter
的实例,包含了路由跳转的方法、钩子函数等route
是局部路由信息对象,包含path
、params
、query
、name
等路由信息参数
vue-router 传参
params
只能使用name
,不能使用path
,参数不会显示在路径上,浏览器强制刷新参数会被清空query
参数会显示在路径上,浏览器强制刷新不会被清空
vue-router 模式
hash
原理是hashchage
事件,带#
符号,不会被包括在HTTP请求中,用来指导浏览器动作的,不会重新加载页面history
利用了 HTML5 History Interface 中新增的pushState
和replaceState
方法。需要后台配置支持,如果服务器没有响应的资源,会返回404
Vue-cli 常用配置选项
pages
页面配置,可以多页面应用配置,默认为单页应用
entry
: 页面入口template
: 模板来源filename
: 输出文件
configureWebpack
接受一个函数或者一个对象,合并到最终的 webpack 配置
// 页面中引入 'babel-polyfill'
configureWebpack: (config) => {
config.entry[page].unshift('babel-polyfill')
},
chainWebpack
接受一个函数,更细粒度的控制其内部配置,支持链式操作
css
一些样式相关的配置
loaderOptions
:向 CSS 相关的 loader 传递选项。比如全局sass样式文件
loaderOptions: {
sass: {
data: '@import "@/assets/scss/globle.scss";'
}
}
devServer
所有 webpack-dev-server 的选项都支持
hot
:热更新port
:端口open
:自动打开浏览器proxy
:请求api代理,跨域
Vue3.0 新特性
- setup:组合式 API。去除了
beforeCreate
、created
钩子,使用setup
代替。setup
在创建组件之前执行,一旦props
被解析,并充当合成API
的入口点。ref
:响应式变量onMounted
:生命周期钩子computed
:计算属性
- 片段:组件支持多个根节点
- teleport:传送,将dom元素放置在指定容器内
- createApp:全局API,调用
createApp
返回一个根实例 - v-model:支持多个值