Vue

对Vue的了解

Vue 是一个构建数据驱动的渐进性框架,指标是通过API实现 响应数据绑定视图更新

Vue的两大外围

  • 数据驱动
  • 组件零碎

    Vue生命周期

    Vue实例从创立到销毁的过程
    graph LR开始创立 --> 初始化数据-->编译模板-->挂载DOM-->渲染-->更新-->渲染;更新-->卸载

    生命周期的作用

    生命周期中有多个事件钩子,能让开发者在管制整个vue实例的过程时更容易造成良好的逻辑判断

    createdmounted

createdmounted
调用机会模板渲染成 HTML 前模板渲染成 HTML 后
常见作用初始化属性值,再渲染成视图操作DOM节点

定时器

beforeDestroy()革除

clearInterval(this.timer);this.timer = null;

v-model的应用

用于表单数据的双向绑定,其实是语法糖,背地做了两个操作:

  1. v-bind绑定value属性
  2. v-on绑定input事件

    Vue响应式(双向数据)原理

    通过 数据劫持 联合 公布订阅模式 的形式来实现

  3. Vue2:通过Object.defineProperty() 来劫持各个属性的setter、getter,在数据变动时公布音讯给订阅者,触发相应的监听回调
  4. Vue3:仅仅是将数据劫持的形式由Object.defineProperty更改为ES6的Proxy代理

    Vue3绝对Vue2的优化

  5. 双向数据绑定方面:
    Vue2的object.defineProperty一次只能劫持对象的单个属性,从而须要通过递归+遍历对每个对象的每个属性进行数据监控;如果属性值是对象的话,还须要深度遍历
    而Vue3.0中的proxy能够一次性地劫持对象的所有属性的setter、getter,还能够代理数组,也能够代理动静增加的属性,有13种劫持操作
  6. 性能方面快1.2~2倍:

(1) diff办法优化

vue2中的虚构dom是全量的比照(每个节点不管写动态还是动静的都会比拟)

vue3新增了动态标记(patchflag)与上次虚构节点比照时,只比照带有patch flag的节点(动态数据所在的节点);可通过flag信息得悉以后节点要比照的具体内容

(2) 动态晋升

vue2无论元素是否参加更新,每次都会从新创立而后再渲染
vue3对于不参加更新的元素,会做动态晋升,只会被创立一次,在渲染时间接复用即可

(3) 工夫侦听器缓存

默认状况下onClick会被视为动静绑定,所以每次都会追踪它的变动

然而因为是同一个函数,所以不必追踪变动,间接缓存起来复用即可

(4) ssr渲染

  1. 按需编译,体积比vue2.x更小
  2. 组合API(相似react hooks)
  3. 更好的Ts反对
  4. 裸露了自定义渲染API
  5. 更先进的组件
  6. Fragment:模板能够有多个根元素

    虚构DOM

    虚构DOM绝对于浏览器所渲染进去的实在 DOM,在 React,Vue 等技术呈现之前, 扭转页面展现内容只能遍历查问 DOM 树找到须要批改的 DOM,而后批改款式行为或者构造,来更新UI,然而这种形式相当耗费计算资源,每次查问DOM简直都须要遍历整棵DOM树,因而建设一个与实在DOM树对应的虚构DOM对象(JavaScript对象),以对象嵌套的形式来示意DOM树,那么每次DOM的更改就变成了对象属性的更改,这样一来就能通过diff算法查找变动要比查问实在的DOM树的性能开销小

    <template>渲染过程

    graph TD将template标签外面的内容编译成render函数 --> 挂载实例:依据render函数的根节点递归生成虚构DOM树-->通过diff算法比照虚构DOM,渲染到实在DOM-->新的DOM操作使得DOM树产生扭转-->通过diff算法比照虚构DOM,渲染到实在DOM

    key的作用

    为了高效的更新虚构DOM

给虚构DOM的每个节点 VNode 增加惟一 id,让其能够依附 key,更疾速精确地拿到 oldVnode 中对应的 VNode

【设置key不举荐应用index或者随机数,因为增删子项的时候损耗性能较大】

v-ifv-show

  • v-if在DOM层面决定元素是否存在,会引起重排重绘
  • v-show在CSS层面决定是否将元素渲染进去(实际上该元素始终存在)

    v-ifv-for优先级

v-ifv-for
Vue 2优先
Vue 3优先

解决方案 :

  1. 父元素应用v-if,子元素应用v-for
  2. 应用计算属性computed
computed() {    list() {        return [1, 2, 3].filter(item => item !== 2);    }}

data是个函数并且返回一个对象 / data为什么要用return

因为一个组件可能会多处调用,每次调用会执行data函数并返回新的数据对象,因而这样能够防止多处调用之间的数据净化

Vue 如何监听键盘事件

  1. @keyup.办法
  2. addEventListener

    组件通信

  3. 父子的传参及办法调用:props / &dollar;emit、&dollar;parent / &dollar;children
  4. 祖孙的传参:provide / inject API、&dollar;attrs / $listeners
  5. 兄弟的传参:bus.js、Vuex
  6. 路由的传参:query、params
父子祖孙/隔代兄弟
props / $emit
ref与 &dollar;parent / &dollar;children
&dollar;attrs / $listeners
provide / inject
EventBus(&dollar;emit / $on)
Vuex

localStorage/Cookie等都能够

删除数组用 delete 和 Vue.delete 的区别

  • delete:只是被删除数组成员变为 empty / undefined,其余元素键值不变

    • Vue.delete:间接删了数组成员,并扭转了数组的键值
      (对象是响应式的,确保删除能触发更新视图,这个办法次要用于避开 Vue 不能检测到属性被删除的限度)

计算属性computed和属性检测watch

cpmputed:当且仅当计算属性依赖的 data 扭转时才会主动计算
computedwatch
首次运行×
默认依赖深度(举荐应用)浅度
调用时在模板渲染只需批改元数据
适合性筛选、不可异步开销较大、异步操作
特色依据页面变动而变动(用于计算)监听页面状态而变动(用于监听)

Vue组件封装过程

graph LRVue.extend&nbsp创立组件-->Vue.component&nbsp注册组件

v-for后应用this.$refs报错domundefined

组件初始化到第一次渲染实现的mounted周期里,只是渲染了组件模板的静态数据,并没有初始化动静绑定的dom,所以在mounted周期外面操作获取不到dom

解决办法:

  1. 把this.$nextTick放在获取到v-for绑定的数据并赋值之后,也就是触发响应式更新之后再进行操作
  2. 把操作dom的操作放到updated生命周期里,然而这样每次更新视图都会触发该操作

    scoped的实现原理

  3. 通过PostCSS给所有dom都增加了惟一的动静属性
  4. 通过PostCSS也给css选择器额定增加对应的属性选择器,来抉择组件中的dom

    插槽

  5. 默认插槽
  6. 具名插槽
  7. 作用域插槽

    Vue CLI

    src目录每个文件夹和文件的用法

  8. assets文件夹是放动态资源;
  9. components是放组件;
  10. router是定义路由相干的配置;
  11. app.vue是一个利用主组件;
  12. main.js是入口文件

    static和assets的区别

    原理:webpack 如何解决动态资源

    staticassets
    内容类库我的项目资源
    资源间接援用被 webpack 打包

(static放他人家的资源,assets放本人家的资源)

引入第三方库

  1. 绝对路径间接引入
  2. 在 webpack 中配置 alias [elis]
  3. 在 webpack 中配置 plugins [plu:genz]

    Vue-Router

    路由实现原理

  4. 利用URL中的hash("#")
  5. 利用History interface在HTML5中新增的办法

    hash模式和history模式

    hash模式history模式
    浏览器反对版本IE、低版本HTML5新推出的API
    刷新从新加载404
    URL中是否带 #×
    # 前面的hash变动不会从新加载,会触发hashchange事件渲染对应内容从新加载,会触发popState事件渲染对应内容

传参

  • name 传参
  • URL 传参
  • <router-link>的to传参
  • 用 path 匹配路由,通过 query 传参

    二级路由 / 嵌套路由哦

    应用路由导航<router-link>和路由容器<router-view>,配置children

    路由守卫触发流程

  • 不同组件(A组件跳转到B组件)

    graph TD触发导航-->调用A组件的路由守卫beforeRouteLeave-->调用全局路由前置守卫beforeEach-->调用B路由独享守卫beforeEnter-->解析异步路由组件B-->调用B的组件内路由守卫beforeRouteEnter-->调用全局路由解析守卫beforeResolve-->确认导航-->调用全局路由钩子afterEach-->渲染B组件DOM

    keep-alive

    keep-alive用于保留组件的渲染状态

不心愿组件被从新渲染影响用户体验和升高性能,而是心愿组件能够缓存下来,维持以后的状态,这时候就能够用到keep-alive组件

(通常搭配生命周期activated应用)

keep-alive是一个形象组件:它本身不会渲染一个DOM元素,也不会呈现在父组件链中;应用keep-alive包裹动静组件时,会缓存不流动的组件实例,而不是销毁它们。

Vuex

Vuex 是一个专为 Vue.js 利用程序开发的状态管理模式。它采纳集中式存储管理利用的所有组件的状态,并以相应的规定保障状态以一种可预测的形式发生变化。
简略来说就是:利用遇到多个组件共享状态时,应用vuex。

vuex的流程

graph TD页面通过&nbspmapAction&nbsp异步提交事件到&nbspaction-->action&nbsp通过&nbspcommit&nbsp把对应参数同步提交到&nbspmutation-->mutation&nbsp批改&nbspstate&nbsp中对应的值-->通过&nbspgetter&nbsp传递对应值-->在页面的&nbspcomputed&nbsp中通过&nbspmapGetter&nbsp来动静获取&nbspstate&nbsp中的值

vuex属性

mapAction:State , Getter , Mutation , Action , Module

  1. state:vuex的根本数据(state),用来存储变量
  2. getter:从根本数据(state)派生的数据,相当于state的计算属性
  3. mutation:提交更新数据的办法,必须是同步的(如果须要异步应用action)。每个mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。回调函数就是咱们理论进行状态更改的中央,并且它会承受 state 作为第一个参数,提交载荷作为第二个参数。
  4. action:和mutation的性能大致相同
    不同之处:
  5. Action 提交的是 mutation,而不是间接变更状态
  6. Action 能够蕴含任意异步操作
  7. modules:模块化vuex,能够让每一个模块领有本人的state、mutation、action、getters,使得构造清晰,方便管理。

    ajax 写在 methods 中还是 actions 中

  8. 仅在申请组件内应用:写在组件的 methods 中
  9. 在其余组件复用:写在 vuex 的 actions 中
    (包装成 promise 返回,在调用处用 async await 解决返回的数据)