【vue面试题】

news2024/11/25 22:39:35

vue

      • 谈谈你怼MVVM开发模式的理解
      • vue优点
        • 渐进式框架的理解
      • vue常用的指令
      • v-if和v-show
        • v-if和v-for的优先级
      • 如何让CSS只在当前组件中起作用?
      • `<keep-alive></keep-alive> `的作用是什么?
      • 如何获取dom?
      • vue-loader是什么?使用它的用途有哪些?
      • assets和static的区别
      • v-model原理
        • Vue中双向数据绑定是如何实现的?
      • 如何优化SPA应用的首屏加载速度慢的问题?
      • vue组件间传值
        • vue父组件向子组件传递数据?
        • 子组件像父组件传递事件?
      • computed和watch
      • vue组件中data为什么必须是一个函数,key的作用
      • 你有对 Vue 项目进行哪些优化?
      • $nextTick的使用
      • 单页面应用(SPA)和多页面(MPA)应用区别及优缺点
      • vue常用修饰符
      • vue两个核心
      • vue和jQuery的区别
      • delete和Vue.delete删除数组的区别
      • SPA首屏加载慢如何解决
      • hash、history和abstract
        • Vue-router跳转和location.href有什么区别
      • vuenextTick实现原理
      • vue源码核心
      • vue的diff算法
      • 你们vue项目是打包了一个js文件,一个css文件,还是有多个文件?
      • Vue2中注册在router-link上事件无效解决方法
      • RouterLink在IE和Firefox中不起作用(路由不跳转)的问题
      • 请说下封装 vue 组件的过程?
      • vue初始化页面闪动问题
      • vue更新数组时触发视图更新的方法
      • vue修改打包后静态资源路径的修改
      • slot插槽
      • vue.directive
      • vue过滤器
      • proxy与object.defineProperty优势对比
      • 自定义组件
      • vue.js的templete编译的理解
      • vue项目优化
      • vue3.0新特性

谈谈你怼MVVM开发模式的理解

MVVM分为Model、View、ViewModel三者。
Model:代表数据模型,数据和业务逻辑都在Model层中定义;
View:代表UI视图,负责数据的展示;
ViewModel:负责监听Model中数据的改变并且控制视图的更新,处理用户交互操作;
Model和View并无直接关联,而是通过ViewModel来进行联系的,Model和ViewModel之间有着双向数据绑定的联系。因此当Model中的数据改变时会触发View层的刷新,View中由于用户交互操作而改变的数据也会在Model中同步。
这种模式实现了Model和View的数据自动同步,因此开发者只需要专注对数据的维护操作即可,而不需要自己操作dom。

vue优点

  • 轻量级框架:只关注视图层,是一个构建数据的视图集合,大小只有几十 kb ;
  • 简单易学:国人开发,中文文档,不存在语言障碍 ,易于理解和学习;
  • 双向数据绑定:保留了 angular 的特点,在数据操作方面更为简单;
  • 组件化:保留了 react 的优点,实现了 html 的封装和重用,在构建单页面应用方面有着独特的优势;
  • 视图,数据,结构分离:使数据的更改更为简单,不需要进行逻辑代码的修改,只需要操作数据就能完成相关操作;
  • 虚拟DOM:dom 操作是非常耗费性能的, 不再使用原生的 dom 操作节点,极大解放 dom 操作,但具体操作的还是 dom 不过是换了另一种方式;
  • 运行速度更快:相比较于 react 而言,同样是操作虚拟 dom ,就性能而言, vue 存在很大的优势。

渐进式框架的理解

主张最少;可以根据不同的需求选择不同的层级;

vue常用的指令

  • v-text:元素的InnerText属性,用于数据绑定
  • v-html:元素的InnerHTML属性,用于绑定一段html
  • v-bind:给元素的属性赋值,v-bind后面是 [:属性名=] [变量名],简写为:属性名
  • v-for:列表的循环渲染。语法v-for="item in data",data 可以是数组或者对象
  • v-show、v-if:控制页面元素的显示和隐藏
  • v-if、v-else-if、v-else:v-if的条件渲染和JavaScript条件判断语句中if、else、else if非常类似。
  • v-on:给元素绑定事件,用法v-on:事件名="方法"
  • v-model:实现数据的双向绑定
  • v-pre:跳过所在元素和它的子元素的编译过程,也就是把这个节点及其子节点当作一个静态节点来处理
  • v-once:模板只会在第一次更新时显示数据,此后再次更新该DOM里面引用的数据时,内容不会自动更新

v-if和v-show

v-show 仅仅控制元素的显示方式,将 display 属性在 block 和 none 来回切换;
v-if会控制这个 DOM 节点的存在与否。

  • 主要区别是是否渲染,当我们需要经常切换某个元素的显示/隐藏时,使用v-show会更加节省性能上的开销;当只需要一次显示或隐藏时,使用v-if更加合理。
  • 当 v-if 与 v-for 一起使用时,v-for 具有比 v-if 更高的优先级,这意味着 v-if 将分别重复运行于每个 v-for 循环中。所以,不推荐v-if和v-for同时使用。
  • 如果v-if和v-for一起用的话,vue中的的会自动提示v-if应该放到外层去。

v-if和v-for的优先级

v-for 具有比v-if更高的优先级

如何让CSS只在当前组件中起作用?

在组件中的 style 前面加上 scoped

<keep-alive></keep-alive> 的作用是什么?

keep-alive 是 Vue 内置的一个组件,可以使被包含的组件保留状态,或避免重新渲染。

如何获取dom?

ref="domName" 用法:this.$refs.domName

vue-loader是什么?使用它的用途有哪些?

vue 文件的一个加载器,将 template/js/style 转换成 js 模块。

用途:js 可以写 es6 、 style样式可以scss 或 less template 可以加 jade

assets和static的区别

相同点: assets 和 static 两个都是存放静态资源文件。项目中所需要的资源文件图片,字体图标,样式文件等都可以放在这两个文件下,这是相同点

不相同点:assets 中存放的静态资源文件在项目打包时,也就是运行 npm run build 时会将 assets 中放置的静态资源文件进行打包上传,所谓打包简单点可以理解为压缩体积,代码格式化。而压缩后的静态资源文件最终也都会放置在 static 文件中跟着 index.html 一同上传至服务器。static 中放置的静态资源文件就不会要走打包压缩格式化等流程,而是直接进入打包好的目录,直接上传至服务器。因为避免了压缩直接进行上传,在打包时会提高一定的效率,但是 static 中的资源文件由于没有进行压缩等操作,所以文件的体积也就相对于 assets 中打包后的文件提交较大点。在服务器中就会占据更大的空间。

建议: 将项目中 template需要的样式文件js文件等都可以放置在 assets 中,走打包这一流程。减少体积。而项目中引入的第三方的资源文件如iconfoont.css 等文件可以放置在 static 中,因为这些引入的第三方文件已经经过处理,我们不再需要处理,直接上传。

v-model原理

v-model是一个十分强大的指令,它可以自动让原生表单组件的值自动和你选择的值绑定,我们经常用它做双向绑定。view层输入值影响data的属性值,data属性值发生改变会更新view层的数值变化。

依赖收集:在组件初始化时,比如render function里引用到了某个响应式对象,就会触发这个对象属性的getter,这时候就会把这个render function放到这个对象的订阅者列表里(track)
响应下次去设置这个响应式对象的属性时就会触发对象属性的getter,继而调用对应的订阅者列表(trigger)

1、实现原理浅层理解:触发input事件来修改value值
v-model其实是个语法糖,它实际上是做了两步动作:

v-bind:绑定响应式数据
触发 input 事件 并传递数据 (核心和重点) input>标签有一个oninput事件,该事件类似于onchange事件,不同之处在于 oninput 事件在元素值发生变化是立即触发, onchange 在元素失去焦点时触发。

2、 深层理解:利用Object.defineProperty()数据劫持来实现。
现目前使用的很多框架,最大的优点就是可以实现数据绑定,再也不需要手动进行DOM操作了,它们实现的原理之一就是数据劫持。
3、Object.defineProperty()实现数据劫持
Object.defineProperty(obj,prop,descriptor)的作用就是直接在一个对象上定义一个新属性,或者修改一个已经存在的属性。但不能监听数组的变化。
在这里插入图片描述
在Vue中其实就是通过Object.defineProperty来劫持对象属性的setter和getter操作,并“种下”一个监听器,当数据发生变化的时候发出通知。我们完全可以控制对象属性的设置和读取。getter 函数用于在数据读取时进行依赖收集,在对应的 dep 中存储所有的 watcher;setter 则是数据更新后通知所有的 watcher 进行更新。

Object.defineProperty(a, 'b', {
  enumerable: false,
  configurable: false,
  get: function(){
    console.log('b' + '被访问');
  },
  set: function(newVal){
    console.log('b' + '被修改,新' + 'b' + '=' + newVal);
  }
});
 
a.b = 2;  // b被修改,新b=2
a.b;    // b被访问

get: 一旦目标属性被访问就会调回此方法,并将此方法的运算结果返回用户。

set:一旦目标属性被赋值,就会调回此方法。

注意:当使用了getter或setter方法,不允许使用writable和value这两个属性

Vue中双向数据绑定是如何实现的?

vue 双向数据绑定是通过 数据劫持 结合 发布订阅模式的方式来实现的, 也就是说数据和视图同步,数据发生变化,视图跟着变化,视图变化,数据也随之发生改变;核心:关于VUE双向数据绑定,其核心是 Object.defineProperty() 方法

如何优化SPA应用的首屏加载速度慢的问题?

  • 将公用的JS库通过script标签外部引入,减小 app.bundel 的大小,让浏览器并行下载资源文件,提高下载速度;
  • 在配置 路由时,页面和组件使用懒加载的方式引入,进一步缩小 app.bundel 的体积,在调用某个组件时再加载对应的js文件;
  • 加一个首屏loading图,提升用户体验;

vue组件间传值

组件是 vue.js最强大的功能之一,而组件实例的作用域是相互独立的,这就意味着不同组件之间的数据无法相互引用,一般来说,组件可以有以下几种关系:
在这里插入图片描述
如上图所示,A 和 B、B 和 C、B 和 D 都是父子关系,C 和 D 是兄弟关系,A 和 C 是隔代关系(可能隔多代)。

  • ref $parent / $children 适用 父子组件通信
    ref:如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子组件上,引用就指向组件实例
    parent/parent / parent/children:访问父 / 子实例
  • 父子组件传递数据props/$emit
  • EventBus ($emit / $on) 适用于 父子、隔代、兄弟组件通信」这种方法通过一个空的 Vue 实例作为中央事件总线(事件中心),用它来触发事件和监听事件,从而实现任何组件间的通信,包括父子、隔代、兄弟组件
  • $emit/$on 通过一个空的Vue实例作为中央事件总线(事件中心),用它来触发事件和监听事件,巧妙而轻量地实现了任何组件间的通信,包括父子、兄弟、跨级
  • attrs/listeners 适用于 隔代组件通信
    attrs:包含了父作用域中不被prop所识别(且获取)的特性绑定(class和style除外)。当一个组件没有声明任何prop时,这里会包含所有父作用域的绑定(class和style除外),并且可以通过v−bind="attrs" 传入内部组件。通常配合 inheritAttrs 选项一起使用。
    listeners:包含了父作用域中的(不含.native修饰器的)v−on事件监听器。它可以通v−on="listeners:包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。它可以通过 v-on="listeners:包含了父作用域中的(不含.native修饰器的)v−on事件监听器。它可以通过v−on="listeners" 传入内部组件
  • provide / inject 适用于 隔代组件通信
    祖先组件中通过 provider 来提供变量,然后在子孙组件中通过 inject 来注入变量。
    provide / inject API 主要解决了跨级组件间的通信问题,不过它的使用场景,主要是子组件获取上级组件的状态,跨级组件间建立了一种主动提供与依赖注入的关系。
  • vuex适用于 父子、隔代、兄弟组件通信
    Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。
    改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。这样使得我们可以方便地跟踪每一个状态的变化。

vue父组件向子组件传递数据?

通过 props

子组件像父组件传递事件?

$emit 方法

computed和watch

  • computed:
    1. 计算属性,依赖其他属性值,且值具备缓存的特性。只有它依赖的属性值发生改变,下一次获取的值才会重新计算。
    2. 当一个属性受多个属性影响的时候就需要用到computed
    3. 适用于数值计算,并且依赖于其他属性时。因为可以利用缓存特性,避免每次获取值,都需要重新计算。购物车商品结算的时候
  • watch:
    1. 当一条数据影响多条数据的时候就需要用watch
    2. 观察属性,监听属性值变动。每当属性值发生变化,都会执行相应的回调。
    3. 适用于数据变化时执行异步或开销比较大的操作。搜索数据

vue组件中data为什么必须是一个函数,key的作用

组建中的data写成一个函数,数据以函数返回值的形式定义,这样每次复用组件的时候,都会返回一份新的data,相当于每个组件实例都有自己私有的数据空间,它们只负责各自维护的数据,不会造成混乱。而单纯的写成对象形式,就是所有的组件实例共用了一个data,这样改一个全都改了。

  • 因为JavaScript的特性所导致,在component中,data必须以函数的形式存在,不可以是对象。
  • 需要使用key来给每个节点做一个唯一标识,Diff算法就可以正确的识别此节点。作用主要是为了高效的更新虚拟DOM。

你有对 Vue 项目进行哪些优化?

  1. 代码层面的优化:
  • v-if 和 v-show 区分使用场景
  • computed 和watch 区分使用场景
  • v-for 遍历必须为 item 添加 key,且避免同时使用 v-if
  • 长列表性能优化
  • 事件的销毁
  • 图片资源懒加载
  • 路由懒加载
  • 第三方插件的按需引入
  • 优化无限列表性能
  • 服务端渲染 SSR or 预渲染
  1. Webpack 层面的优化:
  • Webpack 对图片进行压缩
  • 减少 ES6 转为 ES5 的冗余代码
  • 提取公共代码
  • 模板预编译
  • 提取组件的 CSS
  • 优化 SourceMap
  • 构建结果输出分析
  • Vue 项目的编译优化
  • 基础的 Web 技术的优化:
    1. 开启gzip 压缩
    2. 浏览器缓存
    3. CDN的使用
    4. 使用 Chrome Performance 查找性能瓶颈

$nextTick的使用

当你修改了data的值然后马上获取这个dom元素的值,是不能获取到更新后的值,
你需要使用$nextTick这个回调,让修改后的data值渲染更新到dom元素之后在获取,才能成功。

单页面应用(SPA)和多页面(MPA)应用区别及优缺点

  • SPA:通俗一点说就是指只有一个主页面的应用,浏览器一开始要加载所有必须的 html, js, css。所有的页面内容都包含在这个所谓的主页面中。但在写的时候,还是会分开写(页面片段),然后在交互的时候由路由程序动态载入,单页面的页面跳转,仅刷新局部资源。多应用于pc端。
  • MPA:就是指一个应用中有多个页面,页面跳转时是整页刷新
    单页面的优点:用户体验好,快,内容的改变不需要重新加载整个页面,基于这一点spa对服务器压力较小;前后端分离;页面效果会比较炫酷(比如切换页面内容时的专场动画)。

单页面缺点:不利于seo;导航不可用,如果一定要导航需要自行实现前进、后退。(由于是单页面不能用浏览器的前进后退功能,所以需要自己建立堆栈管理);初次加载时耗时多;页面复杂度提高很多。

vue常用修饰符

.stop:等同于JavaScript中的event.stopPropagation(),防止事件冒泡;
.prevent:等同于JavaScript中的event.preventDefault(),防止执行预设的行为(如果事件可取消,则取消该事件,而不停止事件的进一步传播);
.capture:与事件冒泡的方向相反,事件捕获由外到内;
.self:只会触发自己范围内的事件,不包含子元素;
.once:只会触发一次。

vue两个核心

数据驱动:ViewModel,保证数据和视图的一致性。
组件系统:应用类UI可以看作全部是由组件树构成的。

vue和jQuery的区别

jQuery是使用选择器( $ )选取DOM对象,对其进行赋值、取值、事件绑定等操作,其实和原生的HTML的区别只在于可以更方便的选取和操作DOM对象,而数据和界面是在一起的。比如需要获取label标签的内容:$(“lable”).val(); ,它还是依赖DOM元素的值。Vue则是通过Vue对象将数据和View完全分离开来了。对数据进行操作不再需要引用相应的DOM对象,可以说数据和View是分离的,他们通过Vue对象这个vm实现相互的绑定。这就是传说中的MVVM。

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

delete 只是被删除的元素变成了 empty/undefined 其他的元素的键值还是不变。Vue.delete 直接删除了数组 改变了数组的键值。

SPA首屏加载慢如何解决

安装动态懒加载所需插件;使用CDN资源。

hash、history和abstract

  1. hash:监听的hashchange事件,即地址栏 URL 中的 # 符号;hash 虽然出现在 URL 中,但不会被包括在 HTTP 请求中,对后端完全没有影响,因此改变 hash 不会重新加载页面。兼容性好,支持低版本浏览器和 IE 浏览器。
  2. history:history模式监听pushstate和popstate,(需要特定浏览器支持)这两个方法应用于浏览器的历史记录栈,在当前已有的 back、forward、go 的基础之上,它们提供了对历史记录进行修改的功能。只是当它们执行修改时,虽然改变了当前的 URL,但浏览器不会立即向后端发送请求。
  3. abstract:支持所有 JS 运行模式,Vue-Router 自身会对环境做校验,如果发现没有浏览器 API,路由会自动强制进入 abstract 模式。在移动端原生环境也是使用 abstract 模式。
    使用场景:
  • 一般场景下,hash 和 history 都可以,除非你更在意颜值,# 符号夹杂在 URL 里看起来确实有些不太美丽。
    history优势:
  • pushState() 设置的新 URL 可以是与当前 URL 同源的任意 URL;而 hash 只可修改 # 后面的部分,因此只能设置与当前 URL 同文档的 URL;
  • pushState() 设置的新 URL 可以与当前 URL 一模一样,这样也会把记录添加到栈中;而 hash 设置的新值必须与原来不一样才会触发动作将记录添加到栈中;
  • pushState() 通过 stateObject 参数可以添加任意类型的数据到记录中;而 hash 只可添加短字符串;
  • pushState() 可额外设置 title 属性供后续使用。
    history劣势:
  • 跳转后刷新或者回跳,会报一个404的错误,找不到指定的路由,最后后端去指向正确的路由 加了/hd/xxx 去匹配是否有这个/hd/{:path} 才得以解决

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

使用 location.href= /url 来跳转,简单方便,但是刷新了页面;使用 history.pushState( /url ) ,无刷新页面,静态跳转;引进 router ,然后使用 router.push( /url ) 来跳转,使用了 diff 算法,实现了按需加载,减少了 dom 的消耗。其实使用 router 跳转和使用history.pushState()没什么差别的,因为vue-router就是用了 history.pushState() ,尤其是在history模式下。

vuenextTick实现原理

nextTick:在下次 DOM 更新循环结束之后执行延迟回调。常用于修改数据后获取更新后的DOM。
源码位置:vue/src/core/util/next-tick.js
按照浏览器是否支持promise->mutation-observe->setImmediate->setTimeout的顺序来实现,表现出来的效果跟setTimeout大致一样的

  1. 运用异步锁的概念,保证同一时刻任务队列中只有一个 flushCallbacks。当 pengding 为 false 的时候,表示浏览器任务队列中没有 flushCallbacks 函数;当 pengding 为 true 的时候,表示浏览器任务队列中已经放入 flushCallbacks;待执行 flushCallback 函数时,pengding 会被再次置为 false,表示下一个 flushCallbacks 可进入任务队列。
  2. 环境能力检测,选择可选中效率最高的(宏任务/微任务)进行包装执行,保证是在同步代码都执行完成后再去执行修改 DOM 等操作。
  3. flushCallbacks 先拷贝再清空,为了防止nextTick嵌套nextTick导致循环不结束。

vue源码核心

  • 模板编译compiler
  • 虚拟dom及diff
  • 虚拟dom转真实dom
  • 基于依赖收集的响应式原理

vue的diff算法

核心源码:vue/src/core/vdom/patch.js
为什么要diff、同层对比、深度优先、两端对比

  • 首先需要diff的原因是操作dom的代价是昂贵的,我们要减少操作dom所以需要对比出新老虚拟dom的最小差异点,尽可能复用原有dom
  • 因为我们很少跨层级的去移动dom,所以diff算法只会对比同一父节点下的子节点,使算法的时间复杂度是O(n)
  • 深度优先,比较新vnode找到对应的老vnode,这时会先执行patchChildren进入子节点的比较,所以是深度优先
  • 首尾两端对比法,依次把旧vnode数组的首尾分别和新vnode数组的首尾进行对比,能匹配上就进入他们子节点的对比,都匹配不上就通过key索引找新vnode数组第一个节点对应的在旧vnode数组里的index,还是找不到的话就新建一个vnode。当旧vnode数组里还有节点,而新vnode数组已经遍历完了时就remove掉对应的多出来的真实dom

你们vue项目是打包了一个js文件,一个css文件,还是有多个文件?

根据vue-cli脚手架规范,一个js文件,一个CSS文件。

Vue2中注册在router-link上事件无效解决方法

使用 @click.native 。原因:router-link会阻止click事件,.native指直接监听一个原生事件。

RouterLink在IE和Firefox中不起作用(路由不跳转)的问题

方法一:只用a标签,不适用button标签;
方法二:使用button标签和Router.navigate方法

请说下封装 vue 组件的过程?

  1. 建立组件的模板,先把架子搭起来,写写样式,考虑好组件的基本逻辑。(os:思考1小时,码码10分钟,程序猿的准则。)
  2. 准备好组件的数据输入。即分析好逻辑,定好 props 里面的数据、类型。
  3. 准备好组件的数据输出。即根据组件逻辑,做好要暴露出来的方法。
  4. 封装完毕了,直接调用即可.

vue初始化页面闪动问题

使用vue开发时,在vue初始化之前,由于 div 是不归 vue 管的,所以我们写的代码在还没有解析的情况下会容易出现花屏现象,看到类似于 {{message}} 的字样,虽然一般情况下这个时间很短暂,但是我们还是有必要让解决这个问题的。首先:在css里加上 [v-cloak] { display: none; } 。如果没有彻底解决问题,则在根元素加上 style="display: none;" :style="{display: block }"

vue更新数组时触发视图更新的方法

  1. push();
  2. pop();
  3. shift();
  4. unshift();
  5. splice();
  6. sort();
  7. reverse()

vue修改打包后静态资源路径的修改

cli2 版本:将 config/index.js 里的 assetsPublicPath 的值改为 ./ 。

build: { 
  // ... 
  assetsPublicPath:  ./ , 
  // ...  
} 

cli3版本:在根目录下新建vue.config.js 文件,然后加上以下内容:(如果已经有此文件就直接修改)

module.exports = { 
  publicPath: , // 相对于 HTML 页面(目录相同)    
} 

slot插槽

slot 插槽,可以理解为slot在组件模板中提前占据了位置。当复用组件时,使用相关的slot标签时,标签里的内容就会自动替换组件模板中对应slot标签的位置,作为承载分发内容的出口。
主要作用是复用和扩展组件,做一些定制化组件的处理。

  • 默认插槽
// 子组件
<template>
  <slot>
    <div>默认插槽备选内容</div>
  </slot>
</template>

// 父组件
<template>
  <Child>
    <div>替换默认插槽内容</div>
  </Child>
</template>
  • 具名插槽:slot 标签没有name属性,则为默认插槽。具备name属性,则为具名插槽
// 子组件
<template>
  <slot>默认插槽的位置</slot>
  <slot name="content">插槽content内容</slot>
</template>

// 父组件
<template>
   <Child>
     <template v-slot:default>
       默认...
     </template>
     <template v-slot:content>
       内容...
     </template>
   </Child>
</template>
  • 作用域插槽:子组件在作用域上绑定的属性来将组件的信息传给父组件使用,这些属性会被挂在父组件接受的对象上
// 子组件
<template>
  <slot name="footer" childProps="子组件">
    作用域插槽内容
  </slot>
</template>

// 父组件
<template>
  <Child v-slot="slotProps">
    {{ slotProps.childProps }}
  </Child>
</template>

vue.directive

Vue.directive 可以注册全局指令和局部指令。
指令定义函数提供如下钩子函数

  1. bind:指令第一次绑定到元素时调用(只调用一次)
  2. inserted: 被绑定元素插入父节点时使用(父节点存在即可调用)
  3. update:被绑定元素所在模板更新时调用,不论绑定值是否变化。通过比较更新前后的绑定值。
  4. componentUpdated: 被绑定元素所在模板完成一次更新周期时调用。
  5. unbind: 只调用一次,指令与元素解绑时调用。

项目中有涉及 一键copy、权限控制 都可以用指令的方式控制,目的就是简化我们的工作量。

vue过滤器

Vue 过滤器可用在两个地方:双花括号插值和 v-bind 表达式。
Vue3 中已经废弃这个特点。

  • 局部过滤器
<div>{{ message | formatMessage }}</div>
</template>
export default {
  filters: {
    formatMessage: function(value) {
      // 可基于源值做一些处理
      return value
    }
  }
}
  • 全局过滤器
  // 可基于源值做一些处理
  return value
})

过滤器可串联,执行顺序从左到右,第二个过滤器输入值是第一个过滤器的输出值。

<div>{{ message | formatMessage1 | formatMessage2 }}</div>

proxy与object.defineProperty优势对比

「Proxy 的优势如下:」

  • Proxy 可以直接监听对象而非属性;
  • Proxy 可以直接监听数组的变化;
  • Proxy 有多达 13 种拦截方法,不限于 apply、ownKeys、deleteProperty、has 等等是
  • Object.defineProperty 不具备的;
  • Proxy 返回的是一个新对象,我们可以只操作新的对象达到目的,而 Object.defineProperty 只能遍历对象属性直接修改;
  • Proxy 作为新标准将受到浏览器厂商重点持续的性能优化,也就是传说中的新标准的性能红利;
    「Object.defineProperty 的优势如下:」
  • 兼容性好,支持 IE9,而 Proxy 的存在浏览器兼容性问题,而且无法用 polyfill 磨平,因此 Vue
    的作者才声明需要等到下个大版本( 3.0 )才能用 Proxy 重写。

自定义组件

  • 在components目录新建你的组件文件(smithButton.vue),script一定要export default {
  • 在需要用的页面(组件)中导入:import smithButton from ‘../components/smithButton.vue’
  • 注入到vue的子组件的components属性上面,components:{smithButton}
  • template视图view中使用,<smith-button> </smith-button>
    - smithButton命名,使用的时候则smith-button

vue.js的templete编译的理解

先转化成AST树,再得到的render函数返回VNode(Vue的虚拟DOM节点)

  • 首先,通过compile编译器把template编译成AST语法树(abstract syntax tree 即 源代码的抽象语法结构的树状表现形式),compile是createCompiler的返回值,createCompiler是用以创建编译器的。另外compile还负责合并option。
  • 然后,AST会经过generate(将AST语法树转化成render funtion字符串的过程)得到render函数,render的返回值是VNode,VNode是Vue的虚拟DOM节点,里面有(标签名、子节点、文本等等)

vue项目优化

  1. 代码层面优化
  • v-if 和 v-show 区分使用场景
  • computed 和 watch 区分使用场景
  • v-for 遍历必须为 item 添加 key,且避免同时使用 v-if
  • 长列表性能优化
  • 事件的销毁
  • 图片资源懒加载
  • 路由懒加载
  • 第三方插件的按需引入
  • 优化无限列表性能
  • 服务端渲染 SSR or 预渲染
  1. webpack层面优化
  • Webpack 对图片进行压缩
  • 减少 ES6 转为 ES5 的冗余代码
    -提取公共代码
  • 模板预编译
  • 提取组件的 CSS
  • 优化 SourceMap
  • 构建结果输出分析
  • Vue 项目的编译优化
  1. 基础web技术优化
  • 开启 gzip 压缩
  • 浏览器缓存
  • CDN 的使用
  • 使用 Chrome Performance 查找性能瓶颈

vue3.0新特性

  1. 检测机制的改变
    3.0 将带来基于代理 Proxy 的 observer 实现,提供全语言覆盖的反应性跟踪。这消除了 Vue 2 当中基于 Object.defineProperty 的实现所存在的很多限制:
    • 只能监测属性,不能监测对象
    • 检测属性的添加和删除;
    • 检测数组索引和长度的变更;
    • 支持 Map、Set、WeakMap 和 WeakSet。
    • 新的 observer 还提供了以下特性:
  • 用于创建 observable 的公开 API。这为中小规模场景提供了简单轻量级的跨组件状态管理解决方案。
    • 默认采用惰性观察。在 2.x 中,不管反应式数据有多大,都会在启动时被观察到。如果你的数据集很大,这可能会在应用启动时带来明显的开销。在 3.x 中,只观察用于渲染应用程序最初可见部分的数据。
    • 更精确的变更通知。在 2.x 中,通过 Vue.set 强制添加新属性将导致依赖于该对象的 watcher 收到变更通知。在 3.x 中,只有依赖于特定属性的 watcher 才会收到通知。
    • 不可变的 observable:我们可以创建值的“不可变”版本(即使是嵌套属性),除非系统在内部暂时将其“解禁”。这个机制可用于冻结 prop 传递或 Vuex 状态树以外的变化。
    • 更好的调试功能:我们可以使用新的 renderTracked 和 renderTriggered 钩子精确地跟踪组件在什么时候以及为什么重新渲染
  1. 模板
    模板方面没有大的变更,只改了作用域插槽,2.x 的机制导致作用域插槽变了,父组件会重新渲染,而 3.0 把作用域插槽改成了函数的方式,这样只会影响子组件的重新渲染,提升了渲染的性能。同时,对于 render 函数的方面,vue3.0 也会进行一系列更改来方便习惯直接使用 api 来生成 vdom 。
  2. 对象式的组件声明方式
    vue2.x 中的组件是通过声明的方式传入一系列 option,和 TypeScript 的结合需要通过一些装饰器的方式来做,虽然能实现功能,但是比较麻烦。3.0 修改了组件的声明方式,改成了类式的写法,这样使得和 TypeScript 的结合变得很容易。此外,vue 的源码也改用了 TypeScript 来写。其实当代码的功能复杂之后,必须有一个静态类型系统来做一些辅助管理。现在 vue3.0 也全面改用 TypeScript 来重写了,更是使得对外暴露的 api 更容易结合 TypeScript。静态类型系统对于复杂代码的维护确实很有必要。
  3. 其它方面的更改
    vue3.0 的改变是全面的,上面只涉及到主要的 3 个方面,还有一些其他的更改:
    • 支持自定义渲染器,从而使得 weex 可以通过自定义渲染器的方式来扩展,而不是直接 fork 源码来改的方式。
    • 支持 Fragment(多个根节点)和 Protal(在 dom 其他部分渲染组建内容)组件,针对一些特殊的场景做了处理。
    • 基于 treeshaking 优化,提供了更多的内置功能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/116116.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

哺乳时宝宝一边吃奶,另一边却自动流出来,这是怎么回事?

别人眼中的母乳喂养只是简单地把宝宝抱在怀里&#xff0c;让宝宝吃饱&#xff0c;超级简单。事实上&#xff0c;有很多母乳喂养。“麻烦事”比如母乳不足、堵奶、乳腺炎等&#xff0c;甚至更多“简单”漏奶会让宝宝头疼。有些妈妈很幸运&#xff0c;不知道什么是漏奶&#xff0…

小程序之会议管理

会议管理 注意事项 一些需要注意的细节&#xff1a; 因为 WXML 节点标签名只能是小写字母、中划线和下划线的组合&#xff0c;所以自定义组件的标签名也只能包含这些字符。自定义组件也是可以引用自定义组件的&#xff0c;引用方法类似于页面引用自定义组件的方式&#xff0…

React DAY07

复习&#xff1a; 1.RN中的样式和布局 RN样式完全脱离浏览器&#xff0c;自成体系的一套样式&#xff0c;使用对象创建样式 行内样式&#xff1a; <Text style{{color: red}}>内部样式&#xff1a; let ss StyleSheet.create({danger: {color: red}}) <Text styl…

从业多年的Android开发,竟拿不到 Application Context?

Android 开发者们对于 Application 并不陌生。有的时候为避免内存泄漏&#xff0c;常常不直接使用 Context 而是通过其提供的 getApplicationContext() 确保拿到的是 Application 级别的 Context。而本次像通常一样&#xff0c;拿到的 Application 却是 null&#xff0c;到底是…

国考省考行测:细节理解,对错判断,要素查找,问什么,找什么,对比分析

国考省考行测&#xff1a;细节理解&#xff0c;对错判断&#xff0c;要素查找&#xff0c;问什么&#xff0c;找什么&#xff0c;对比分析 2022找工作是学历、能力和运气的超强结合体! 公务员特招重点就是专业技能&#xff0c;附带行测和申论&#xff0c;而常规国考省考最重要…

头戴式耳机适合运动吗、五款最适合运动的耳机分享

戴着耳机锻炼&#xff0c;听着动感的音乐&#xff0c;会让你心潮澎湃&#xff0c;瞬间感觉自己力大无穷。那什么样的耳机更适合在健身房锻炼时戴呢&#xff1f;首先稳固性和舒适度一定要比较好&#xff0c;毕竟在运动的过程中老是感觉到不适或者掉落&#xff0c;那真的是很令人…

旋转的扰动、导数和积分

The plus operator 设M\mathcal{M}M表示一个n维的流型&#xff0c;因为流型局部同胚与Rn\mathbb{R}^nRn&#xff0c;所以我们可以通过定义符号⊞\boxplus⊞和⊟\boxminus⊟建立一个流型M\mathcal{M}M的局部邻域和其正切空间的双射。 ⊞:MRn→M;⊟:MMn→Rn\boxplus:\mathcal{M}…

为什么说用了MES系统,但生产数字化管理只做到20%?

随着越来越多的制造企业开始体验和建设MES系统&#xff0c;MES系统能够实现生产执行过程的有效数字化管理已经成为共识。回过头来看&#xff0c;是不是只有生产进度才是工厂需要管理的&#xff1f;当你想详细了解当前存在的问题&#xff0c;进展如何&#xff0c;哪些月度重点任…

JAVA零基础小白学习教程之day09-内部类权限final静态

day09-JAVAOOP 课程目标 1. 【理解】什么是内部类 2. 【掌握】匿名内部类 3. 【掌握】引用数据类型作为方法的参数 4. 【理解】final关键字的使用 5. 【理解】包的定义及使用 6. 【理解】权限修饰符 7. 【掌握】static关键字的使用B友https://www.bilibili.com/video/BV1QG4y…

职场员工有没有潜力,看这一个能力就够了

在我组织的研讨会上&#xff0c;讲故事的课程通常以一个思考练习开始。 我会让参与者闭上眼睛回忆《小红帽》的故事&#xff0c;尤其考虑其中的情节、起伏和结尾。这个练习有时会引发一阵笑声&#xff0c;人们会好奇这与课程有什么相关性&#xff0c;或者干脆把《小红帽》与《…

给Debezium connector 发送信号

1. 概述 Debezium 信号机制提供了一种方法来修改连接器的行为&#xff0c;或触发一次性操作&#xff0c;例如启动表的 临时快照。要触发连接器执行指定操作&#xff0c;可以发出特殊的SQL 命令以将信号消息添加到专门的信号表&#xff0c;也称为信号数据集合。在源数据库上创建…

哪些进销存软件既好用又免费?

中小企业刚起步都会面临着资金紧缺、人力资源不足等诸多管理问题&#xff0c;对于大部分预算不是很多的中小企业或者尚未尝试过进销存软件的企业&#xff0c;都会选择免费进销存软件来进行企业管理或体验进销存软件的功效。 进销存软件的开发需要强大的技术支持&#xff0c;数…

B站技术选型与架构

目录前言B站前端之路B站Golang技术栈分析bilibili技术总监毛剑简介前言 了解了一下B站的技术发展历程&#xff1a;最开始是用PHP语言开发的&#xff0c;后来B站的中台逐步被Node占领&#xff0c;而后台技术为了更高的并发、更稳健&#xff0c;以及为了大数据分析&#xff0c;逐…

RK3568平台开发系列讲解(Linux系统篇)共享内存

🚀返回专栏总目录 文章目录 一、共享内存底层实现二、共享内存API三、共享内存案例沉淀、分享、成长,让自己和他人都能有所收获!😄 📢共享内存技术是功能最强、应用最广的进程间通信技术。其原理是多个进程共享相同的物理内存区,一个进程对该内存区的任意修改,可被其…

不懂Nacos没关系,可以看看它是怎么运用代理模式的

背景 看Nacos的源代码时&#xff0c;发现其中有对代理模式的运用&#xff0c;而且用得还不错&#xff0c;可以作为一个典型案例来聊聊&#xff0c;方便大家以更真实的案例来体验一下代理模式的运用。如果你对Nacos不了解&#xff0c;也并不影响对本篇文章的阅读和学习。 本文…

前端三小时用html和js写一个贪吃蛇游戏,非常简单带讲解,代码可直接用,功能完整

目录 游戏主体部分--地狱模式 游戏主页入口 预览图 游戏入口代码 1.html 2.css 3.js 注册页面代码 游戏实现很简单&#xff0c;只写游戏主体的话只要三小时就够了。 话不多说&#xff0c;我们直接来看效果预览。 转成gif图之后有点卡&#xff0c;但是游戏效果并不卡&…

php宝塔搭建部署实战PESCMSTEAM团队任务管理系统源码

大家好啊&#xff0c;我是测评君&#xff0c;欢迎来到web测评。 本期给大家带来一套php开发的PESCMSTEAM团队任务管理系统源码&#xff0c;感兴趣的朋友可以自行下载学习。 技术架构 PHP7.2 nginx mysql5.7 JS CSS HTMLcnetos7以上 宝塔面板 文字搭建教程 下载源码&am…

k8s lifecycle——poststart和prestop

1、lifecycle的声明 lifecycle:postStart:exec:command: ["/bin/sh", "-c", "sleep 100"]preStop:exec:command: ["/bin/sh", "-c", "sleep 100"]2、poststart 容器创建后立即执行&#xff0c;主要用于资源部署、…

JPEG编码原理及简易编码器实现

简介 以学习为目的编写的简易jpeg编码器&#xff0c;以看得懂为目标&#xff0c;代码尽可能清晰简洁&#xff0c;不对内存、性能做看不懂的优化&#xff0c;也不实现jpeg更多高级特性。 这篇文章是我从自己的开源工程中整理来的 本文对应的工程为https://gitee.com/dma/learn…

【OpenFOAM】-olaFlow-算例4- irreg45degTank

算例路径&#xff1a; olaFlow\tutorials\irreg45degTank 算例描述&#xff1a; 不规则波浪模拟 学习目标&#xff1a; 不规则波浪模拟&#xff1a;olaFlow中单向不规则波采用线性波浪叠加法生成&#xff0c;基本原理如图2所受&#xff0c;需要提供对应波谱的周期、波高和相位的…