前端之VUE

本文深入探讨了Vue.js的MVC与MVVM模式,重点解析了Vue2.x与Vue3.x数据响应式的实现,包括Object.defineProperty和Proxy的应用。另外,详细介绍了Vue指令的原理,如V-if与V-show的区别,以及Vue生命周期、组件通信、计算属性和侦听器。同时,文章涵盖了Vue的Diff算法、虚拟DOM和Key的作用,以及Vue性能优化和服务器端渲染(SSR)的知识。
摘要由CSDN通过智能技术生成

MVC模式

1 控制器Controller 模型 Model 视图 View

2 路由解析(根据URL寻找控制器与行为) à 控制器调用行为,进行数据操作 –>  数据操作后进行 视图与数据的页面渲染 输入到客户端

MVVM模式

将 MVC 中的控制器变成View Model 

VIEW代表UI组件 MODEL代表数据模型   

VIEW和MODEL之间的桥梁 视图发生改变通知VIEWMODEL层更新,数据发生改变通知VIEWMODEL层更新视图渲染。

 

VUE2.0数据响应式

Object.defineProperty 给data中所有属性设置setter和getter,收集依赖。数据变化时触发setter通知依赖,Watcher通知外界数据改变(视图更新或者触发回调)。外界读取数据时触发getter将watcher收集到依赖中。

缺点:E6之前无元编程,新增删除属性无法设置响应式,需要重新遍及设置响应式。数组的一些方法也会无法通知watcher数据发生变化。

VUE2数组如何设置

使用函数劫持,重写函数方法。调用数组API的时候就会通知依赖更新。缺点:修改第一个元素时,无法检测。  清楚数组的操作也无法检测。

VUE3.0数据响应式

使用Proxy 代理直接监听对象和数组的变化,判断Refect.get返回的是否为对象然后通过relative方法做代理,实现深层观测。

观测数组时触发多次如何避免--à用key判断是否代理对象target自身属性。或者判断新旧值是否相等,才执行触发器。

VUE指令原理

模版编译时,将指令解析出来并添加到AST的directives属性里.

VUE常用修饰符

键盘.delete .ctrl .alt .shift .enter .meta

鼠标.left .right 将输入转换成数字v-model.number/.trim

.middle

nestTick原理

再下次DOM更新循环结束后执行延迟回调。

分为宏任务和微任务。

Promise

Mutation Observer

Setimmediate

以上皆不可以使用setTimeout。定义一个异步方法,多次调用nestTick会存入一个队列 。

V-if 和 V-show的区别

实现方式:V-if根据数据真假值判断Dom树删除还是建立元素节点。

v-show只是单纯修改CSS样式,元素一直存在Dom树上。

编译过程中V-if有一个局部编译/卸载的过程。(销毁或者重建内部的事件监听和自组件。)

v-if是惰性 条件为假,什么都不做。

 

VUE生命周期

创建实例à初始化数据à编译模板à渲染函数à创建虚拟DOMà渲染真实DOMà更新à销毁。组件通过new Vue() 创建后会初始化事件和生命周期。beforeCreate钩子函数,无法访问到数据。Created函数之后实例建立,完成挂载数据,绑定事件,可以获得初始数据。DOM树未建立可以使用vue.$nestTick与dom交互。寻找template模版,编译模板为渲染函数,创建虚拟DOM,然后执行BeforeMounted函数。虚拟dom建立完成。然后渲染真实dom,Mounted 挂载完成后,真实Dom挂载完毕,数据进行双向绑定。可以操作真实dom。响应式数据发生改变,执行Beforeupdate,虚拟dom利用diff算法与真实DOM对比重新渲染。更新完成后,执行Updated 真实DOM更新,此时避免修改数据,防止无线循环更新。调用$destroy方法后,立即执行beforeDestroy,实力销毁前,清除计时器、清除非指令绑定的事件,组件的数据绑定、监听。只剩下dom空壳。然后执行destroyed。

组件通信方式

父->子Props   给子节点指定ref

子->父$on $emit 事件订阅和发布

使用$parent  $children 获取实例不推荐会导致代码高度耦合

Ref获取实例      VUEX

COMPUTED 和 WATCH

Computed就是具有缓存的watcher,

依赖属性变化时更新视图。计算比较消耗性能的计算场景。

模板放入过多逻辑无法维护。

Watch没有缓存性,更多是一个观察的作用,可以监听某些数据,执行回调。当我们需要深度监听时 Deep:true

Data为什么是一个函数

一个组件被复用多次的话,会建立多个实例。

本质上,这些实例都是同一个创造函数,如果data是一个对象,对象属于引用类型,会影响到所有实例。

保证了不同实例之间不冲突。

V-model原理

本质是一个语法糖 value + input方法的语法糖。可以通过model实行的prop和event属性进行自定义。

根据不同的标签属性生成不同的事件和属性。

 

VUE模版翻译

生成AST抽象语法树

深度遍及抽象语法数 查找静态节点(更新dom时直接跳过)。

然后把语法树编译成渲染函数。

 

VUE2.0和3.0 Diff算法

2.0进行双端比较--------新前旧前,新后旧后,新后旧前,新前旧后 移动节点。借助key找到可以复用的节点。

3.0借鉴了ivi算法和inferno算法

创建VNode时确定类型,以及在patch的过程中采用位运算来判断一个VNode的类型,在这个基础上配合核心diff算法。

虚拟DOM

浏览器渲染真实dom十分耗时。频繁操作dom会造成性能问题。

虚拟dom用js对象描述一个dom节点。对真实dom进行一个抽象形成Vnode 虚拟节点。  经历create-diff-patch

虚拟dom本质上就是在 JS DOM 之间做了一个缓存

Key的作用

为了更高效的复用dom元素。新旧节点中保存映射关系。以便在旧节点中找到可以复用的元素,key就是节点的唯一标识。

新旧节点只有顺序不同时,直接进行移动元素。

 

Keep-alive

实现组件缓存,当组件切换时不会对当前组件进行卸载。

常用的比如 include / exclude 允许组件有条件的缓存

生命周期有 active / deactivated 通知当前组件是否活跃

还使用的LRU算法

 

VUE生命周期调用顺序

父 beforecreate 父created 父beforemount

子 beforecreate 子created 子beforemount

子mountd

父mountd

父beforeupdate 子beforeupdate

子updated父Updated

父beforddestroy 子beforddestroy 子destroyed 父destroyed

 

SSR

服务器渲染,把vue在客户端渲染成HTML的工作放在服务端完成直接把html文件返回给客户端。

首屏加载快。开发受限生命周期只有befordcreate 和 created

服务器更大的耗载。

VUE的性能优化

v-if 和 v-for 不连用。

尽量减少data数据。会增加更多的getter和setter 收集对应的watcher。

SPA页面使用keep-alive

Key保证唯一

防抖和节流

图片懒加载

长列表滚动到可视区域动态加载。

SEO优化

预渲染

服务端渲染SSR

打包优化

压缩代码

CDN加载第三方模块

抽离公共文件

Vuex

1.vuex有哪几种属性?

分别有State、 Getter、Mutation 、Action、 Module。

2.state的理解?

1----Vuex就是一个仓库,仓库里面放了很多对象。其中state就是数据源存放地,对应于与一般Vue对象里面的data
2----state里面存放的数据是响应式的,Vue组件从store中读取数据,若是store中的数据发生改变,依赖这个数据的组件也会发生更新
3----它通过mapState把全局的 state 和 getters 映射到当前组件的 computed 计算属性中

 

3.vuex的Getter特性?

一getters 可以对State进行计算操作,它就是Store的计算属性
二虽然在组件内也可以做计算属性,但是getters 可以在多组件间复用

三如果一个状态只在一个组件内使用,是可以不用getters

 

4.vuex的Mutation的特性?
Action 类似于 mutation,不同在于:Action 提交的是 mutation,而不是直接变更状态。

Action 可以包含任意异步操作



5.vue.js中ajax请求代码放在methods还是actions
一、如果请求来的数据是不是要被其他组件公用,仅仅在请求的组件内使用,就不需要放入vuex 的state里。
二、如果被其他地方复用,如果需要,请将请求放入action里,方便复用,并包装成promise返回,在调用处用async await处理返回的数据。如果不要复用这个请求,那么直接写在vue文件里很方便。

Vue-router路由

1.怎么定义vue-router的动态路由?怎么获取传过来的值?

动态路由的创建,主要是使用path属性过程中,使用动态路径参数,以冒号开头,如下:

{

  path: '/details/:id'

  name: 'Details'

  components: Details

}

访问details目录下的所有文件,如果details/a,details/b等,都会映射到Details组件上。

当匹配到/details下的路由时,参数值会被设置到this.$route.params下,所以通过这个属性可以获取动态参数

this.$route.params.id

 

 

2.vue-router有哪几种路由守卫?


router.beforeEach 全局守卫(全局前置守卫 )进入路由之前

router.afterEach 全局后置钩子

router.beforeResolve全局解析守卫

router.beforeRouteEnter,router.beforeRouteUpdate,

router.beforeRouteLeave组件内的守卫-----路由独享守卫

 

3.$route和 $router的区别是什么?

$router为VueRouter的实例,是一个全局路由对象,包含了路由跳转的方法、钩子函数等。

$route 是路由信息对象||跳转的路由对象,每一个路由都会有一个route对象,是一个局部对象,包含path,params,hash,query,fullPath,matched,name等路由信息参数。

 

4.vue-router响应路由参数的变化

(1)用Watch检测

Watch: {

$route(to, from){

console.log(to.path) 对路由变化进行响应

}}

(2)组件内导航钩子函数

beforeRouteUpdate(to, from, next){

todosomethings}

 

5. vue-router 传参

(1)使用Params:

只能使用name,不能使用path

参数不会显示在路径上

浏览器强制刷新参数会被清空

Const P = this.$router.params

This.$router.push({

   Name:home,

   Params:{

        Number:1,

        Code:’999’

   }})

 

 

2)使用Query

参数会显示在路径上,刷新不会被清空

name可以使用path路径

Const P = this.$router.query

This.$router.push({

   name:Home,

   qurey:{

        Number:1,

        Code:’999’

   }})

 

 

    

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值