VUE 基础

VUE

事件修饰符

  • .prevent 阻止默认行为(例如:阻止a链接的挑战)
  • .stop 阻止事件冒泡
  • self 只当在 event.target 是当前元素自身时触发处理函数,相当于阻止事件冒泡
  • once 绑定了事件以后只能触发一次,第二次就不会触发
  • caption 用于事件捕获

v-model 表单修饰符

  • .number 自动将用户输入值转为数值类型
  • .trim 自动过滤用户输入的收尾空白字符
  • .lazy 在“change”时而非“input”更新

v-bind 修饰符

  • sync 对 props 进行一个双向绑定
  • prop 设置之定义标签属性,避免暴露数据,防止污染 HTML 结构
  • camel 驼峰化
    sync 注意点:
  • 使用 sync 的时候,子组件传递事件名格式必须为 Update:value, 其中 value 必须与子组件中的 props 中的声明名称完全一致
  • 注意带有 .sync 修饰符的 v-bind 不能和表达式一起使用
// 父组件
<comp :myMessage.sync="bar"></comp> 
// 子组件
this.$emit('update:myMessage',params);

v-if 和 v-show
v-if 有更高的切换开销,v-show 有更高的初始渲染开销

  • 如果有频繁的切换,用v-show
  • 如果在运行条件很少时,用v-if
    v-show 原理:不管初始条件是什么,元素总是会被渲染
    v-if 原理: render 函数通过表达式的值来决定是否生成 DOM

过滤器

过滤器的注意点

  • 要定义到 filters 节点下,本质是一个函数
  • 在过滤器函数中,一定要有 return 值
  • 在过滤器的形参中,可以获取到“管道符 [ | ]”前面待处理的那个值
  • 如果全局过滤器和私有过滤器名字一致,此时按照“就近原则”,调用的是”私有过滤器“
  • 一个表达式可以使用多个过滤器。过滤器之间需要用管道符 “ | ”隔开。其执行顺序从左往右
    应用场景:
    单位转换、数字打点、文本格式化、时间格式化
    原理:
  • 在编译阶段通过 parseFilters 将过滤器编译成函数调用(串联过滤器则是一个嵌套的函数调用,前一个过滤器执行的结果是后一个过滤器函数的参数)
  • 编译后通过调用 resolveFilters 函数找到对应过滤器并返回结果
  • 执行结果作为参数传递给 toString 函数,而 toString 执行后,其结果会保存在 Vnode 的 text 属性中,渲染到视图

watch 侦听器

侦听器的格式

  1. 方法格式的侦听器
    • 缺点1:无法在刚进入页面的时候,自动触发!!!
    • 缺点2:如果侦听的是一个对象,如果对象中的属性发生了变化,不会触发侦听器!!!
  2. 对象格式的侦听器
    • 好处1:可以通过 immediate 选项,让侦听器自动触发!!!
    • 好处2:可以通过 deep 选项,让侦听器深度监听对象中每个属性的变化!!!

计算属性

特点:

  1. 定义的时候,要被定义为“方法”
  2. 在使用计算属性的时候,当普通的属性使用即可

好处:

  1. 实现了代码的复用
  2. 只要计算属性中依赖的数据源变化了,则计算属性会自动重新求值!

异步渲染 ( 批量的 )

数据发生变化是,vue 并不会立即去更新 Dom ,而是将修改数据的操作放在了一个异步操作队列中,如果我们一直修改相同数据,异步操作队列还会进行去重,等待同一事件循环中的所有数据变化完成之后,会将队列中的时间拿来进行处理,进行 DOM 更新
$nextTick 下一次 DOM ( 渲染 ) 更新周期之后执行

插槽 v-solt

  • 默认插槽
  • 作用域插槽 ( 父组件给子组件插槽传值 )
  • 具名插槽
    总结:
  • v-slot 属性只能在 < template > 上使用,但是只有默认插槽
  • 默认插槽名为default,可以省略default直接写v-slot
  • 缩写为#时不能不写参数,写成#default
  • 可以通过解构获取v-slot={user},还可以重命名v-slot=“{user: newName}“和定义默认值v-slot=”{user = ‘默认值’}”
    原理:
    slot本质上是返回VNode的函数,一般情况下,Vue中的组件要渲染到页面上需要经过template -> render function -> VNode -> DOM 过程

组件之间传值

  1. 父子 关系
  2. 兄弟 关系

1. 父子关系

1). props/$emit  => 父传子,可以通过 自定义属性, 子传父,可以通过 自定义事件 

2). provide/inject => 父传子,子传孙, provide 将数据以对象的形式传出去, 在孙组件中 inject 接收
3). $attrs/$listeners => 父传子, 子传孙,类似与第一种,给中间的子组件加上 v-on="$listeners"
<sun v-bind="$attrs" v-on="$listeners"></sun>

2. 兄弟组件

EventBus => $emit/$on
1). 创建 eventBus.js 模块, 并向外共享一个 Vue 的实例对象 
2). 在数据发送方, 调用 bus.$emit ('事件名称', 要发送的数据) 方法触发自定义事件
3). 在数据接收方,调用 bus.$on('事件名称',事件处理函数) 方法注册一个自定义事件

3. 全局
vuex

4. ref

ref 引用

ref 用来获取 DOM 元素或者 组件 的引用

生命周期

生命周期描述
beforeCreate组件实例被创建之初,组件的属性生效之前
created组件实例已经完全创建,data 数据初始化,属性也绑定,但真实的 DOM 还没生成,$el( 虚拟 DOM ) 还不可用
beforeMount在挂在之前被调用,$el 初始化:相关的 render 函数首次被调用
mountedel 被新创建的 vm.$el 替换,完成挂载
beforeUpdate组件数据更新之前调用,发生在虚拟 DOM 打补丁之前
update组件数据更新之后
activitedkeep-alive 专属,组件被激活时调用
deactivatedkeep-alive 专属,组件被销毁时调用
beforeDestory组件销毁前调用
destoryed组件销毁后调用

初始化顺序: props、methods、data
父子组件的加载的生命周期:父 beforeCreate => 父 create => 父 beforeMount => 子 beforeCreate => 子 create => 子 beforeMount => 子 mounted => 父 mounted

在哪个生命周期内调用异步请求

created、beforeMount 、mounted
推荐 created 中请求异步

  1. 能更快的获取到服务端数据,减少页面的 loading 时间
  2. ssr 不支持 beforeMount 、mounted 钩子函数,所以放在 created 中有助于一致性
  3. 请求在 mounted 中有可能会导致页面闪动

SSR

SSR 服务端渲染,在服务端将标签渲染成整个 html 片段,直接返回给客户端
优点:
1). 更好的SEO( 搜索引擎优化 )
2). 首屏加载更快,不需要下载 Vue 编译后的 js 和 css
缺点:
1). 更多的开发条件限制:例如服务端渲染只支持 beforeCreate 和 created 这两个钩子函数
2). 更多的服务器负载: 在服务器中渲染完整的应用程序,显然会比仅仅提供静态文件的 server 更加大量占用 CPU 资源

说说你对 VUE 的理解?

Vue.js 是一个用于创建用户界面的开源 JavaScript 框架,也是一个创建单页面(SPA)的 web 应用框架

Vue 的核心特征:

  • 数据驱动 (MVVM)
  • 组件化:把图形、非图形的各种逻辑均抽象为一个统一的概念(组件)来实现开发的模式
  • 指令系统

组件化的优势:

  • 降低整个系统的耦合度,在保持接口不变的情况下,我们可以替换不同的组件快速完成需求,例如输入框,我们可以替换为日历、时间、范围等组件作具体的实现
  • 调试方便,由于整个系统是通过组件组合起来的,在出现问题的时候,可以排除法直接移除组件、或者根据报错的组件快速定位问题,是因为每个组件之间低耦合,职责单一,所以逻辑分析会比整个系统要简单
  • 提高可维护性,由于每个组件的职责单一,并且组件在系统是被复用的,所以对代码进行优化可获得系统的整体升级

指令系统:
指令是带有 v- 前缀的特殊属性作用:当表达式的值改变时,将其产生的连带影响,响应式的作用于 DOM 。v-if 、v-for、v-bind、v-model

Vue 和 React 对比

相同点:

  • 都有组件化思想
  • 都支持服务器端渲染
  • 都有 Virtual DOM (虚拟 DOM)
  • 数据驱动视图
  • 都有支持 native 的方案:Vue 的 weex、React 的React native
  • 都有自己的构建工具:Vue 的 vue-cli、React 的 create React App

区别

  • 数据变化的实现原理不同。React 使用的是不可变数据,而 Vue 使用的是可变数据
  • 组件化通信的不同。React 中我们通过使用回调函数进行通信,而 Vue 中子组件向父组件传递消息方式有两种方式:事件和回调函
  • diff 算法不同。React 主要使用 diff 队列保存需要更新哪些 DOM,得到 patch 树,再统一操作批量更新 DOM。Vue 使用双指针,边对比,边更新 DOM

说说对双向绑定的理解

MVVM
VM (ViewModel)的主要职责是:

  • 数据变化后更新视图
  • 视图变化后更新数据
    流程:
  1. new Vue() 首先执行初始化,对 data 执行响应化处理,这个过程发生在 Observe 中
  2. 同时对模版执行编译,找到其中动态绑定的数据,从 data 中初始化视图,这个过程发生在 Complie 中
  3. 同时定义一个更新函数和 Watcher ,将来对应数据变化时 Watcher 会调用更新函数
  4. 由于 data 的某个 key 在视图中可能出现多次,所以每个 key 都需要一个管家 Dep 来管理多个 Watcher
  5. 将来 data 中的数据一旦发生变化,会首先找到对应的 Dep ,通知所有的 Watcher 执行更新函数

说说对 SPA 单页应用 的理解

SPA 是一种 网络应用程序或者网站的模型
优点:

  • 具有桌面应用的即时性、网站的可移植性和可访问性
  • 用户体验号、快,内容的改变不需要更新加载整个页面
  • 良好的前后端分离,分工更明确
    缺点:
  • 不利于搜索引擎的抓取
  • 首次渲染速度相对较慢
单页面应用 (SPA)多页面应用(MPA)
组成一个页面或者多个页面片段多个页面
刷新方式局部刷新整页刷新
URL 模式哈希模式历史模式
SEO 搜索引擎化难实现,可使用 SSR方式改善容易实现
数据传递容易通过 URL、cookie、localStorage等传递
页面切换速度快,用户体验号切换加载资源,速度慢,用户体验差
维护成本相对容易相对复杂

如何给 SPA 做 SEO

  • SSR 服务端渲染
  • 静态化:1)通过程序将动态页面抓取并保存为静态页面,这样的页面实际存在于服务器硬盘中;2)Web 服务器的 URL Rewrite 的方式,原理是通过 Web 服务器内部模块按照一定的规则将外部的 URL 请求转化为内部的文件地址,一句话来说就是把请求的静态地址转化为动态页面地址,而静态页面实际是不存在的
  • 使用 Phantomjs 针对爬虫处理

Vue 实例挂载的过程中发生了什么?

  • new Vue 的时候会调用 _init 方法
    * 定义 $ set 、$ get、 $ delete 、$watch 等方法
    * 定义 $ on、$ off 、$ emit 、等事件
    * 定义 _update、$ forceUpdate、$ destroy 等生命周期
  • 调用 $ mount 进行页面的挂载
  • 挂载的时候主要通过 mountComponent 方法
  • 定义 updateComponment 更新函数
  • 执行 render 生成虚拟 DOm
  • _update 将虚拟 DOM 生成真实 DOM 结构,并且渲染到页面中

SPA 首屏加载速度慢怎么解决

先计算 通过 DOMContentLoad 或者 performance 计算出首屏时间

// 方案一:
document.addEventListener('DOMContentLoaded', (event) => {
    console.log('first contentful painting');
});
// 方案二:
performance.getEntriesByName("first-contentful-paint")[0].startTime

// performance.getEntriesByName("first-contentful-paint")[0]
// 会返回一个 PerformancePaintTiming的实例,结构如下:
{
  name: "first-contentful-paint",
  entryType: "paint",
  startTime: 507.80000002123415,
  duration: 0,
};

加载慢的原因:

  • 网络延迟问题
  • 资源文件体积是否过大
  • 资源是否重复发送请求去加载了
  • 加载脚本的时候,渲染内容堵塞了

解决方案:
几种常用的 SPA 首屏优化方式:

  • 减小入口文件体积
  • 静态资源本地缓存:强缓存、协商缓存、Service Worker 离线缓存
  • UI 架构按需加载:
  • 图片资源的压缩:矢量字体、精灵图
  • 组件重新打包
  • 开启 GZip 压缩:使用 compression-webpack-plugin
  • 使用 SSR

减小入口文件体积:

  1. 路由懒加载,配置路由采用动态路由
  2. externals 加载外部 CDN 资源

v-if 和 v-for 不建议一起用

在 Vue 2.0 中 v-for 的优先级比 v-if 高 ,作用域同一个元素上,带来性能的浪费(每次渲染都会先循环在进行条件判断)
单在 Vue 3.0 中 v-if 的优先级永远比 v-for 高

为什么 data 属性是一个函数而不是一个对象

是为了防止同一个组件多次创建实例对象共用一个 data,产生数据污染。采用函数的形式,initData 是会将其作为工厂函数都会返回全新 data 对象

Vue 中给对象添加新属性界面不刷新?

  • Vue.set( target: Object | Array ,proprertyName/index : String| number, value: Number)
  • Object.assign()
  • $forcecUpdated()
    小结:
  • 如果为对象添加少量的新属性,可以直接采用 Vue.set()
  • 如果需要为新对象添加大量的新属性,则通过 Object.assign() 创建对象
  • 如果实在是不知道怎么操作时候,可采用 $forceUpdate() 进行强制刷新(不建议)

Vue 中组件和插件有什么区别

插件:

  • 添加全局方法或者属性。如:vue-custom-element
  • 添加全局资源:指令/ 过滤器 / 过渡 等。如 vue-touch
  • 通过全局混入来添加一些组件选项。如 vue-router
  • 添加 Vue 实例方法,通过把它们添加到 Vue.prototype 上实现
  • 一个库,提供自己的 API,同时提供上面提到的一个或者多个功能。如 vue-router
组件插件
编写形式vue 单文件,每一个 .vue 文件都可以看成一个组件vue 插件的实现应该暴露一个 install 方法,这个方法的第一个参数是 Vue 构造器,第二个参数是一个可选的选项对象
注册形式全局注册和局部注册通过 Vue.use() 注册
使用场景用来构成你的 App 的业务模块对 Vue 的功能的增强或者补充

说说对 vue 的 mixin 的理解,有什么应用场景?

局部混入 和 全局混入
合并策略:

  • 替换型:props、methods、inject、computed
  • 合并型:data,通过 set 方法进行合并和重新赋值
  • 队列型:全部生命周期和 watch,原理是将函数存入一个数组,然后正序遍历执行
  • 叠加型:component、directives、filters 通过原型链进行层层的叠加

SSR 解决了什么问题?

解决:

  • 利于 SEO
  • 首屏呈现渲染,提高首屏加载速度
    缺点:
  • 复杂度:整个项目的复杂度
  • 库的支持性,代码兼容
  • 性能问题:内存消耗变大、缓存、降级
  • 服务器负载变大

过程:

  • 使用 ssr 不存在单例模式,每次用户请求都会创建一个新的 vue 实例
  • 使用 ssr 需要实现服务端首屏渲染和客户端激活
  • 服务端异步获取数据 asyncData 可以分为首屏异步获取和切换组件获取
    1. 首屏异步获取数据,在服务端预渲染的时候就应该已经完成
    2. 切换组件通过 mixin 混入,在 beforeMount 钩子完成数据获取

Vue.observable

Observable 翻译过来我们可以理解成可观察的
Vue.observable,让一个对象变成响应式数据。Vue 内部会用它来处理 data 函数返回的对象
返回的对象可以直接用于渲染函数和计算属性内,并且会在发生变更时触发相应的更新。也可以作为最小化的跨组件状态存储器

Vue 中 key 的原理

使用场景:

  1. 当我们在使用 v-for 时,需要给单元加上 key
  2. 用 +new Date() 生成的时间戳作为 key ,手动强制触发重新渲染
    key的作用:
    key 是给每一个 vnode 的 唯一 id,也是 diff 的一种优化策略,可以根据 key,更准确,更快的找到对应的 vnode 节点

keep-alive

keep-alive 是 vue 中的内置组件,能在组件切换过程中将状态仍保留在内存中,防止重复渲染 DOM
props 属性:

  • include - 字符串或正则表达式,只有名称匹配的组件会被缓存
  • exclude - 字符串或者正则表达式,任何名字匹配的组件都不会被缓存
  • max - 数字,最多可以缓存多少组件实例

自定义指令

指令系统:vue 中提供了一套为数据驱动视图更为方便的操作
注册指令:全局注册 和 局部注册 (directive)
应用场景:

  • 防抖
  • 图片懒加载
  • 一键 Copy 功能
  • 权限校验

Vue 项目中有封装过 axios ?

axios 是一个轻量的 HTTP 客户端,基于 XMLHTTPRequest 服务来执行 HTTP 请求
特性:

  • 从浏览器中创建 XMLHttpRequest
  • 从 node.js 创建 http 请求
  • 支持 Promise APL
  • 拦截请求和响应
  • 转换请求数据和响应数据
  • 取消请求
  • 自动转换 JSON 数据
  • 客户端支持 防御 XSRF

如何封装:

  • 封装的同时,你需要和后端协商好一些约定,请求头、状态码、请求超时时间…
  • 设置接口请求前缀:根据开发、测试、生产环境的不同,前缀需要加以区分
  • 请求头:来实现一些具体的业务,也必须携带一些参数才可以请求
  • 状态码:根据不同接口返回的不同 status,来执行不同的业务
  • 请求方法:根据 get 、post 等方法进行一个再次封装
  • 请求拦截器:更加请求的请求头设定,来决定哪些请求可以访问
  • 响应拦截器:根据后端返回的状态码进行判定执行不同的业务

Vue 项目的目录结构

基本原则:

  • 文件夹和文件夹内部语义一致性
  • 单一入口/出口
  • 就近原则,紧耦合的文件应该放到一起,且应以相对路径引用
  • 公共的文件应该以绝对路径的方式从根目录引用
  • ./src 外的文件不应该被引入

Vue 做权限管理

前端权限控制可以分为四个方面:

  • 接口权限 JWT
  • 按钮权限
  • 菜单权限
  • 路由权限

vue 项目如何部署,404 问题

为什么在 history 模式下有问题?没有刷新
为什么在 hash 模式下没有问题?
解决方案: nginx 重定向

如何处理 Vue 项目中的错误的

主要错误来源:

  • 后端接口错误: axios 的 interceptor 实现网络请求的 response 先进行一层拦截
  • 代码本身逻辑的错误:全局设置错误处理
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值