vue背记过程

订阅发布模式和观察者模式

订阅发布模式

希望接收通知的对象:基于一个主题通过自定义事件订阅主题

发布事件的对象:通过发布主题事件的方式通知各个订阅该主题的对象

消息发送方:发送者

消息接收方:订阅者

订阅者与发布者不知道对方,需要第三方组件叫做信息中介。

image.png

观察者模式

一个对象(subject)维持一系列依赖于它的对象(observer),将有关状态的任何变更自动通知给观察者

image.png

比较(一到北地)

  • Observer模式要求观察者必须订阅内容改变的事件,定义了一个一对多的依赖关系;
  • Publish/Subscribe模式使用了一个主题/事件通道,这个通道介于订阅着与发布者之间;
  • 观察者模式里面观察者「被迫」执行内容改变事件(subject内容事件);发布/订阅模式中,订阅着可以自定义事件处理程序;
  • 观察者模式两个对象之间有很强的依赖关系;发布/订阅模式两个对象之间的耦合读底。


MVVM、MVC、MVP区别

时三种常见的软件架构设计模式,通过分离关注点的方式来组织代码结构,优化开发效率。

  • MVC即模型、视图、控制器(Model View Controller)
  • 简单来说就是通过controller的控制去操作model层的数据,并且返回给view层展示。controller在这里执行的的就是别墅里面的“管家”的作用。

  • View 接受用户交互请求
  • View 将请求转交给Controller处理
  • Controller 操作Model进行数据更新保存
  • 数据更新保存之后,Model会通知View更新
  • View 更新变化数据使用户得到反馈

MVVM

  • MVVM即模型、视图、视图模型(Model-View-ViewModel),ViewModel是MVVM这栋别墅的“管家”。
  • 将其中的 View 的状态和行为抽象化,让我们可以将UI和业务逻辑分开。
  • MVVM的优点是低耦合可重用性独立开发

mvvm.jpg

  • View 接收用户交互请求
  • View 将请求转交给ViewModel
  • ViewModel 操作Model数据更新
  • Model 更新完数据,通知ViewModel数据发生变化
  • ViewModel 更新View数据

MVP 

与mvc唯一不同在于presenter和controller,

mvc,model改变,通知view更新,逻辑混乱,controller只知道model的接口,无法控制view的更新

presenter可以更新view


slot

插槽

  1. 默认插槽
    1. 匿名插槽,slot没有指定name时默认插槽,一个组件只能由一个
      1. 组件
        <slot></slot>

        使用组件

        <Category title="美食" >
        			<img src="https://s3.ax1x.com/2021/01/16/srJlq0.jpg" alt="">//放入插槽
        		</Category>

  2. 具名插槽
    1. 带有name属性的slot,一个组件可以出现多个
    2. 组件
      <slot name="center">我是一些默认值,当使用者没有传递具体结构时,我会出现1</slot>

      使用组件

      <Category title="美食" >
      			<img slot="center" src="https://s3.ax1x.com/2021/01/16/srJlq0.jpg" alt="">
      			<a slot="footer" href="http://www.atguigu.com">更多美食</a>
      		</Category>

  3. 作用域插槽(子给父亲)
    1. 在子组件渲染作用域插槽时可以将内部数据传递过去
    2. 组件
      <slot :games="games" msg="hello">我是默认的一些内容</slot>
              data() {
      			return {
      				games:['红色警戒','穿越火线','劲舞团','超级玛丽'],
      			}
      		},

      使用组件

      <Category title="游戏">
      			<template scope="atguigu">
      				<ul>
      					<li v-for="(g,index) in atguigu.games" :key="index">{{g}}</li>
      				</ul>
      			</template>
      		</Category>

过滤器

过滤数据是一个函数,他会把表达式中的值始终当作函数的第一个参数,

过滤器用在插值表达式{{}},v-bind中放在’|‘后显示


如何保存页面当前的状态

  1. 前组件会被卸载
    1. 存储在local/session storage中
  2. 前组件不会被卸载
    1. 单页面渲染,要切换的组件作为子组件全屏渲染,父组件正常存储页面状态
    2. keep-alive

常见的修饰符

.stop        阻止冒泡

.prevent        阻止默认行为

.capture        事件捕获

.once        只触发一次


data为什么是函数而不是对象

js中的对象是引用类型数据,当多个实例引用一个对象时,只要夜歌实例对这个对象进行操作,其他实例中的数据也会改变

复用组件时,每个组件都要有自己的数据,互不干扰

所以组件的数据不能写成对象,要写成函数,已返回值的形式定义,每次复用都会返回一个新的data


$nextTick原理及作用

本质时对js执行原理eventloop的一种应用

本质是为了利用js的这些异步回调任务队列来实现vue框架中自己的异步回调队列。

vue中数据更新与dom渲染是异步的,数据更新,会把任务交给一个异步队列,当当前任务空闲时,才会进行dom渲染,渲染后立即调用。

执行顺序

  1. Call Stack清空
  2. 执行当前的微任务
  3. 尝试DOM渲染
  4. 触发Event Loop

应用场景: 

  1. 数据变化后执行的某个操作,而这个操作需要使用随数据变化而变化的dom结构时
  2. 在vue生命周期中,如果在created的狗子中进行dom操作,要放在nextTick的回调函数中

vue中给data新添加一个属性

新添加的属性,并不是响应式属性,不会触发视图更新,需要使用vue的全局api,$set()

this.$set(target,  key , value)


单页面应用于多页面应用

  1. 单页面(spa,一句)
    1. 只有一个主页面的应用,一开始只需要加载一次js,css等相关资源,所有内容都包含在主页面,每一个功能组件化,单页面应用跳转只切换相关组件,刷新局部资源
  2. 多页面(MPA,重整)
    1. 每个页面都要重复加载js、css等资源,刷新整个网页

区别

775316ebb4c727f7c8771cc2c06e06dd.jpg


template到render的过程

template->ast->render函数


vue data中的一个属性改变后,视图是否会立即重新渲染

不会立即渲染,

vue实现响应式布局吧并不是数据变化后DOM立即变化,而是按照一定策略对dom更新。

vue在更新,dom时是异步执行的。


vue优点(请数组时需快)

轻量级框架:只关注视图层,大小很小

双向数据绑定:数据操作简单

组件化:在构建单页面应用时有很大优势

视图,数据,结构分离:是数据的更改更为简单。

虚拟dom:不使用原生dom,提高性能

运行速度快:相较于react vue运行更快


vue模板编译原理

vue中的template无法被浏览器直接解析,需要将template转为一个js函数(render).浏览器执行这个函数,并渲染出相对应的html元素。这个转化过程被称为模板编译。有三个阶段

  • 解析阶段
    • 使用大量的正则表达式,对template字符串进行解析,将标签,指令,属性转化为AST抽象语法树
  • 优化阶段
    • 遍历AST找到其中的一些静态节点并标记,方便再次渲染时进行diff比较时,直接跳过着一些静态节点,优化runtime性能
  • 生成阶段
    • 将AST转化为render函数字符串

对ssr的理解

服务器端渲染,将vue在客户端把标签渲染成HTML的工作放在服务器端完成,然后再把html直接返回给客户端

优势

更好的seo

首屏加载速度更快

缺点

开发阶段受限制,服务器端渲染支支持beforeCreate和created两个钩子

更多的服务器负载


vue性能优化

  1. 编码阶段(换位需防迪兰)
    1. 减少data中的数据
    2. 使用路由懒加载、图片懒加载
    3. 第三方模块按需导入
    4. 防抖节流
    5. spa页面使用keep-alive缓存组件
    6. key值唯一
    7. v-if替代v-show
    8. v-for和v-if不连用
  2. SEO优化
    1. 预渲染
    2. SSR
  3. 打包优化
    1. 压缩代码
    2. 使用cdn加载静态资源
    3. tree shaking
    4. 多线程打包happypack

对spa单页面的理解

在web页面初始化时加载html,js,css。一旦加载完成,用户的操作不会使得页面重新加载或跳转。取而代之的是通过路由实现页面的内容的局部刷新。

优点

        用户体验好,快。页面内容不需要整个重新刷新,避免了不必要的跳转和重复渲染

        spa对服务器压力小

        前后端分离,架构清晰。前端进行交互逻辑,后端负责数据处理

缺点

        初次加载耗时多

        seo难度大

        不能使用浏览器的前进后退


assets与static的区别

同:

        都是用于存放静态资源文件

异:

        assets中存放的静态资源文件在项目打包时,会将assets中防止的静态资源文件进行打包上传。压缩后的静态资源文件,最终也会放置在static中跟着index.html一同上传到服务器。

        static中的静态资源不走打包压缩格式化等流程,而是直接进入打包好的目录,直接上传。体积更大


MVVM优缺

优点(分梯子)

  1. 分离视图和模型,降低代码耦合。提高试图或者逻辑的重用性
  2. 提高可测试性:viewmodel可以帮助开发者更好的开发测试代码
  3. 自动更新dom:利用双向绑定,数据更新后视图自动更新

缺点(对于大型图形应用,视图状态多,vm构建和维护成本高)

  1.  大的模块中mode也很大,长期使用造成内存浪费
  2. 对大型图形应用的应用程序,视图状态多,vm的构建和维护成本高

生命周期

  • beforeCreate(创建前)啥也没
  • created(创建后)数据,函数可以。节点大咩
  • beforeMount(挂载前)有html无节点
  • mounted(挂载后):可以调用dom。
  • beforeUpdate(更新前)数据可以,节点打灭
  • updated(更新后)可以了
  • beforeDestroy(销毁前):实例销毁之前调用。这一步,实例仍然完全可用,this 仍能获取到实例。
  • destroyed(销毁后):实例销毁后调用,调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。该钩子在服务端渲染期间不被调用。

在那个生命周期请求异步数据

created - beforeMount - mounted

推荐在created钩子函数中调用异步请求,

在created钩子函数中调用异步请求的优点

  1. 更快获取服务器端数据,减少页面加载时间
  2. ssr不支持beforeMount,mounted函数 ,有助于提高一致性

keep-alive的生命周期

是vue的内置组件,用来对组件进行缓存,在组件切换过程成将保持状态存在内存中 

如果一个组件包裹了keep-alive那么他会多出两个生命周期

deactivated:切换走

,activated:切换来

同时beforeDestroy和destroy就不会再触发了


组件通信

(1)父子组件间通信

  • 子组件通过 props 属性来接受父组件的数据,然后父组件在子组件上注册监听事件,子组件通过 emit 触发事件来向父组件发送数据。
  • 父:<son :list='list'></son>
  • 子:props:[  'list'    ]

this.$refs.student.$on('atguigu',this.getStudentName)

getStudentName(name,...params){
				console.log('App收到了学生名:',name,params)
				this.studentName = name
			},

this.$emit('atguigu',this.name,666,888,900)

(2)兄弟组件间通信

  • 使用 eventBus 的方法,它的本质是通过创建一个空的 Vue 实例来作为消息传递的对象,通信的组件引入这个实例,通信的组件通过在这个实例上监听和触发事件,来实现消息的传递。在
  • 安装 
  • vue上beforeCreate(){    Vue.prototype.$bus=this    }

发送                 

this.$bus.$emit('hello',this.name)

接受

this.$bus.$on('hello',(data)=>{
				console.log('我是School组件,收到了数据',data)
			})

(3)任意组件之间

  • 使用 eventBus ,其实就是创建一个事件中心,相当于中转站,可以用它来传递事件和接收事件。

路由

路由懒加载的实现

非懒加载

import List from '@/components/list.vue'
const router = new VueRouter({
  routes: [
    { path: '/list', component: List }
  ]
})

懒加载

使用箭头函数+import动态加载(const list =箭头函数包裹import

const List = () => import('@/components/list.vue')
const router = new VueRouter({
  routes: [
    { path: '/list', component: List }
  ]
})

箭头函数+require动态加载(无第一行     require做箭头函数返回值

const router = new Router({
  routes: [
   {
     path: '/list',
     component: resolve => require(['@/components/list'], resolve)
   }
  ]
})

路由hash和history的区别

hash

  1. hash值会出现再url中,不会出现在http请求中,对后端没有影响。
  2. 改变hash值不会重新发起请求
  3. 浏览器支持度好

把前端路由的路径拼接在url的#后边。

#后的路径发生变化时,并不会发生请求,而是出发onhashchage事件,但可以页面跳转(哈希路径在前端自生自灭)

history模式

  1. 用户输入url,服务器会接受这个请求,并解析这个url
  2. historyAPI
    1. 切换历史状态
      1. 切换状态:forward,back,go
      2. 修改历史状态:对历史记录进行更改,replaceState(),pushState()方法

路由传参

query参数

路由定义

        正常定义

路由跳转

        <router-link :to="{path:'/profile',query:{name:'why',age:28,height:188}}">档案</router-link>

接受参数

        $route.query

  • 传递后形成的路径:/route?id=123

params参数

路由定义

         {    path: '/user/:userid',    component: User, },

        :userid用来占位

路由跳转

        <router-link :to="{ name: 'users', params: { uname: wade }}">按钮</router-link>


接受:

        $route.params


vue-router路由钩子在生命周期中的体现

路由实现登陆权限验证。

全局路由钩子(一起)

  1. router.beforeEach        全局前置守卫, 进入路由之前
  2. router.beforeResolve     全局解析守卫 在beforeRouterEnter调用之后调用
  3. router.afterEach      全局后置守卫,进入路由之后

路由独享钩子

  1. beforeEnter

组件内钩子(3b)

  1. beforeRouteUpdate        当前地址改变,且组件被复用时触发
  2. beforeRouteEnter           进入组件前触发
  3. beforeRouteLeave         离开调用

router.beforeEach

beforeEnter

beforeRouteEnter

router.beforeResolve

router.afterEach


vue-router跳转和location.href有什么区别

  1. location.href跳转刷新了页面
  2. history.pushState无刷新,静态跳转
  3. 引入router使用router.push使用了diff实现按需加载。

对前端路由的理解

前端路由可以帮助我们在仅有一个页面的的情况下,记住当前用户走到了哪一步。

用户前进后退触发的新内容都会映射到不同的url中,此时即使刷新页面,有url可确定所在位置,内容也不会丢失。


vuex

当多个组件依赖同一状态

来自不同组件行为需要变更到同一状态

b025e120ca3d0bd2ded3d038d58cacf4.jpg

dispatch:调用action的方法        dispatch(functionAction , data)

action:操作处理模块,处理交互行为,可以支持异步操作。其中的操作会调用commit

commit:执行mutation的方法        commit(functionMutation , data)

mutations:状态操作改变方法,真正修改state中数据的操作

state:用于存储数据

getters:state对象读取方法,用于数据加工


vuex的几种属性

state、getters、mutations、actions、modules


vuex和单纯的全局对象有什么区别

vuex的存储状态是响应式的,当vue从store中读取状态的时候,若store中的数据发生变化组件也会更新

不能直接改变store中的状态,可以改变store中的状态唯一途径就是提交


虚拟dom

虚拟dom是对dom的抽象,本质上来说,虚拟dom是js的一个对象。将页面的状态抽象为js对象形式,通过diff算法,计算最小变化,根据变化更新dom,将多次dom修改的结果一次性更新到页面上,从而减少页面渲染的次数,减少dom重绘回流次数,提高渲染性能。


虚拟DOM解析过程

  1. 首先对要插入文档中的DOM树结构进行分析,使用js对象将其表示出来。将这个js对象树保存下来,最后再将dom片段插入到文档
  2. 当页面的状态发生改变,需要对页面的dom结构进行调整的时候,首先根据变更的状态重新构建起一颗对象树,然年后将这颗新的对象树和旧的对象树进行比较,记录两颗树的差异
  3. 最后将记录的有差异的地方应用到真正的dom树中

为什么要使用虚拟dom

(1)保证性能下限,再不优化的前提下提供过得去的性能,

页面渲染流程

解析html-->生成dom->生成cssom-》layout->paint->complier

重绘回流性能小号比

  • 真实dom:生成html字符串+重建所有的DOM元素
  • 虚拟DOM:生成vNode+DOMdiff+必要的dom更新

(2)跨平台


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值