回答:
1、vue的生命周期
1)、生命周期是什么? Vue 实例有一个完整的生命周期,也就是从开始创建、初始化数据、编译模版、挂载 Dom -> 渲染、更新 -> 渲染、卸载等一系列过程,我们称这是 Vue 的生命周期。
2)、各个生命周期阶段及其钩子函数
vue的生命周期核心经历了四个阶段,在四个阶段的前后分别有两个钩子函数。
第一阶段:数据挂载阶段:把配置项data中的属性,赋给了vue对象本身,并做了数据劫持。
该阶段前后的两个钩子函数:beforeCreate和created
第二阶段:模板渲染阶段:把vue对象的数据渲染到模板上。
该阶段前后的两个钩子函数:beforeMount和mounted
第三阶段:组件更新阶段:当数据发送变化时,组件会进行重新渲染,所以,准确的说是,组件重新渲染阶段。
该阶段前后的两个钩子函数:beforeUpdate和updated
第四阶段:组件销毁阶段:组件销毁。
该阶段前后的两个钩子函数:beforeDestroy和destroyed
视情况可以补充:
当使用keep-alive包裹组件时,会有组件激活和停用之说,这两个钩子函数分别是:activited和deactivated
2、发送请求在生命周期的哪个阶段,为什么不可以是beforeMount,mounted中。
(如果组件的初始数据来自后端)发送请求建议在钩子函数created里,这个钩子函数里是最快,也能有助于一致性。
为什么?
1)、为什么不能放在beforeCreate里?
因为:
一般来说,数据从后端返回回来后,都会赋给vue中的属性(data挂载的),在beforeCreate钩子函数里,data的数据还没有挂载到vue对象本身上,所以,不能在这个钩子函数里用。而created钩子函数里,数据已经挂载到vue对象了。
2)、为什么不可以是beforeMount,mounted中
因为:
第一,在这两个钩子函数里,发送请求有点晚,会增加页面loading的时间;
第二,vue的SSR不支持beforeMount 、mounted 钩子函数,所以,放在 created 中有助于一致性
回答:
1、父子之间传值:
1)、父到子:props,子到父:$emit
2)、$ref、$parent
3)、事件总线(event-bus)
4)、集中管理($root)
2、兄弟之间传值:
1)、事件总线(event-bus)
2)、集中管理($root)
3)、先 子到父(用事件),再 父到子(用props)
回答:
可以使用,但是,在循环时,通过v-if只能拿到少部分数据时,建议不要使用。
原因: v-for比v-if优先级高,如果遍历的数组元素个数比较多,但是满足v-if条件比较少的情况下。会浪费性能。而且,每次刷新页面时,都会执行这样性能不高的代码。
解决:可以在computed里循环数组,通过filter的方式,过滤出需要的数据。v-for直接循环计算属性的结果(不用v-if)。而computed是有缓存的,所以,在原始数据没有变化时,不会多次过滤数据,这样,就提高了效率。
回答:
使用反向代理,vue-cli3+的项目里,新建(编辑)vue.config.js文件,(增加)配置代码如下:
回答:
v-bind指令是把标签的属性处理成动态的。分别可以把属性名和属性值处理成vue里的属性,常间的是属性值处理成动态的。
格式如下:
1、属性值动态绑定: 简写 :html属性="数据"`
示例:
2、 属性名动态绑定:
此时,属性值也是动态的
示例:
回答:
1、插槽的作用:
插槽是用来处理组件的内容的。插槽决定了组件的内容放在组件模板的何处。插槽使用的是vue官方提供的组件来完成的。
2、vue中的插槽分为:
1)、单个插槽
在组件中只有一个插槽时,插槽不用起名字。默认的名字是:default
示例:
2)、具名插槽
但组件中的插槽多于一个时,就需要给组件起名字,用名字来区分不同的插槽。用官方组件slot的name属性给插槽起名字
格式:
示例:
回答:
1、$nextTick理解:
vue更新DOM时,使用的是异步更新队列。目的是提高性能,避免无效的重复的DOM更新。即:vue中更新数据后,并不会立即更新DOM,而是把数据引起的DOM更新放入到异步更新队列里。等待下次事件循环(tick),并在两个tick之间进行UI渲染。
按照这个思路,程序员就不能在更改数据后,立即获取更新后的DOM,也不知道什么时候DOM能够更新。基于此,vue提供了$nextTick函数。程序员只需要把 ”操作更新后DOM的代码“ 放入到$nextTick的回调函数里。由$nextTick内部,在更新完DOM后,调用回调函数。
示例:
2、$nextTick理解和定时器有什么区别
相同:都是延迟加载,都使用事件队列
不同:
1)、定时器是下一个队列的队首。
2)、是放在当前队列的最后一个。$nextTick()的回调函数执行要先于定时器。
event-bus是事件总线,是借助一个全局的vue对象,来完成事件的绑定和事件的触发。
当:我们需要把A组件的数据传给B组件时,在A、B两个组件里都引入全局的vue对象。然后,在B组件里绑定事件,在A组件里触发事件,就可以把A组件的数据传给B组件了。
示例:
回答:
mounted和created都是vue对象生命周期的钩子函数,执行时机不同。
1、created 是在 data配置项的数据挂载到vue对象本身后,会调用的钩子函数。
此时,
1)、用 this. 的方式可以拿到data里的数据。
2)、但是数据还没有渲染到模板上。所以,访问dom时,内容还是原始的模板内容。
2、mounted是在组件的模板初次渲染完毕后会调用的钩子函数。
此时,
data里的数据已经渲染到模板上了。所以,访问dom时,已经和页面上看到的效果一样了。
回答:
1、v-model指令的作用
vue中的v-model指令是完成双向绑定的,用在表单元素上。双向绑定就是 M会影响V。V也会影响M。即:能将页面上输入的值同步更新到相关绑定的data属性,也会在更新data绑定属性时候,更新页面上输入控件的值。
2、v-model的原理
v-model指令是一个语法糖,是属性绑定和事件的语法糖。vue会根据不同的表单元素使用不同的属性和事件。
如下:
以文本框为例剖析原理,以下是代码:
而,使用v-model来完成以上功能的代码如下:
vue 为了保证每个实例上的 data 数据的独立性,规定了必须使用函数,而不是对象。因为使用对象的话,每个实例(组件)上使用的 data 数据是相互影响的,这当然就不是我们想要的了。对象是对于内存地址的引用,直接定义个对象的话组件之间都会使用这个对象,这样会造成组件之间数据相互影响。而函数具有内部作用域,可以解决这个问题。
在 vue 中我们可以使用 Vue.directive()方法注册全局指令。也可以只用 directives 选项注册局部指令。
图片懒加载 v-LazyLoad
vue 的移动端适配我们可以参考 vant-ui 组件库给我们提供的方案。使用 amfe-flexible(用于自动定义跟字体大小)插件和 postcss-pxtorem(用于将 px 自动转成 rem)插件在 main.ts 里面 import "amfe-flexible"在根目录新建 .postcssrc.js 文件
rem 是相对于跟字体的倍数,如果我们整个项目都是用 rem 作为单位,那么当我们做移动端的响应式的时候只需要去改变跟字体的大小就能做到适配。
因为 store 里的数据是保存在运行内存中的,当页面刷新时,页面会重新加载 vue 实例,store 里面的数据就会被重新赋值初始化。所以我们可以在修改 store 的数据同时将数据再存一份到本地存储(localStorage 或者 sessionStorage),本地存储的内容是存在浏览器里面的,不会因为刷新而丢失。我们也可以用过比如 vuex-persistedstate 这样的第三方包来帮助我们做 vuex 的持久化数据。
在创建组件的时候我们不必在写唯一的根元素。移除了 vue2 中的 filters。
新增了 renderTracked 和 renderTriggered 两个生命周期。
我们可以使用 setup 函数来使用类似 react 的自定义 hooks 的功能,主要解决逻辑关注点分离的问题。
我们有必要先了解下模板转换成视图的过程整个过程:
简单点讲,在 Vue 的底层实现上,Vue 将模板编译成虚拟 DOM 渲染函数。结合 Vue 自带的响应系统,在状态改变时,Vue 能够智能地计算出重新渲染组件的最小代价并应到 DOM 操作上。
那么 vue 操作虚拟 DOM 有什么优异的地方呢?
那么为什么比原生操作 DOM 还快呢?首先我们每次操作 dom 的时候,都会去执行浏览器的那 5 个步骤,尤其是当大量循环的时候,每次循环完都不知道后面还要不要修改,所以每次都要去重复这个过程,引发不必要的渲染。但是在实际开发过程中,我们会发现虚拟 dom 并没有比真实 dom 更快。这个问题尤雨溪在知乎上面有过回答:这是一个性能 vs. 可维护性的取舍。框架的意义在于为你掩盖底层的 DOM 操作,让你用更声明式的方式来描述你的目的,从而让你的代码更容易维护。没有任何框架可以比纯手动的优化 DOM 操作更快,因为框架的 DOM 操作层需要应对任何上层 API 可能产生的操作,它的实现必须是普适的。针对任何一个 benchmark,我都可以写出比任何框架更快的手动优化,但是那有什么意义呢?在构建一个实际应用的时候,你难道为每一个地方都去做手动优化吗?出于可维护性的考虑,这显然不可能。框架给你的保证是,你在不需要手动优化的情况下,我依然可以给你提供过得去的性能。
在开发中,我们经常会遇到使用 token,token 的作用是要验证用户是否处于登录状态,所以要请求一些只有登录状态才能查看的资源的时候,我们需要携带 token。
一般的后端接口设置的 token 是有时效的,超时后就会失效,失效之后的处理策略一般会做两种处理:
1、created
表示组件实例已经完全创建,data数据已经被 Object.defineProperty 劫持完成,属性也绑定成功,但真实dom还没有生成,$el还不可用。
2、mounted
el选项所对应的视图节点已经被新创建的 vm.$el 替换,并挂载到实例上去了。此时响应式数据都已经完成了渲染。
使用 <keep-alive>对列表页面进行包裹,被包裹的列表页面就有了activated、deactivated这两个生命周期。在离开列表页面时,在deactivated中记录页面的滚动条位置。再次进入列表页面时,在activated中使用 this.$el.scrollTop 把页面滚动到离开时所记录的位置。
要修改elementUI组件的样式,可以采用以下两种方式
1.全局样式
通过选择权重覆盖elementUI组件的样式,如修改复选框为圆角:
但这种方式为全局样式,会影响页面中所有复选框,如果不希望影响其它页面的样式,可以采用第二中方式
2.局部样式
但如果仅仅是设置了scoped属性,样式无法生效,原因是以上样式会被编译成属性选择器,而elementUI组件内部的结构却无法添加该html属性,以上样式被编译成如下代码:
如果是sass或less编写的样式,还可以使用
key是虚拟DOM对象的标识,在更新显示时key起着极其重要的作用,vue和react都是采用diff算法来对比新旧虚拟节点,而key的作用是为了在执行 diff算法 的时候,更快更准确地找到对应的虚拟节点,从而提高diff速度。
和 是vue-router中经常会操作的两个对象, 表示当前的路由信息对象,包含了当前 URL 解析得到的信息,包含当前的路径、参数、query对象等,一般用于获取跳转时传入的参数。对象是全局路由的实例,是router构造方法的实例,一般用户路由跳转,如、 等方法
我们先来看看浏览器渲染一个页面的过和,大概需要以下5个步骤
众所周知,一个页面在浏览器中最大的开销就是DOM节点操作,页面的性能问题大多数是DOM操作引起的,当我们用原生js 或jquery这样的库去操作DOM时,浏览器会从构建DOM树开始执行完以上整个流程,所以频繁操作DOM会引起不需要的计算、重排与重绘,从而导致页面卡顿,影响用户体验
所以减少DOM的操作能达到性能优化的目的,事实上,虚拟DOM就是这么做的,虚拟DOM(VirtualDOM) 的实现原理主要包括以下 3 部分:
Virtual DOM 本质上就是一个javascript对象,数据的修改会生成一个新的虚拟DOM(一个新的javascript对象),然后与旧的虚拟DOM进行对比,得到两个对象的差异项,最后只更新差异对象中的内容到真实DOM,这样能做到最少限度地修改真实DOM,从而实现性能优化
在开发中后台应用过程中或多或少都会涉及到一个问题:权限,简单地说就是让不同的用户在系统中拥有不同的操作能力。
但在实际应用中我们一般不直接将权限赋予在用户身上,因为这样操作对有大量用户的系统来说过于繁琐,所以我们一般基于RBAC(Role-Based Access Control)权限模型,引入角色的概念,通过角色的媒介过渡,先将权限赋予在角色上,再关联相应的用户,对应的用户就继承了角色的权限
用户与角色,角色与权限都是多对多的关系
引入角色媒介的优点:
所谓数据绑定,就是指层和层之间的映射关系。
Vue的双向数据绑定是通过数据劫持结合发布者订阅者模式来实现的 要实现这种双向数据绑定,必要的条件有:
补充回答
在new Vue的时候,在 Observer 中通过 达到数据劫持,代理所有数据的 getter 和 setter 属性,在每次触发 setter 的时候,都会通过 Dep 来通知 Watcher,Watcher 作为数据监听器与模板解析器之间的桥梁,当 Observer 监听到数据发生改变的时候,通过 Updater 来通知 Compile 更新视图,而 Compile 通过 Watcher 订阅对应数据,绑定更新函数,通过 Dep 来添加订阅者,达到双向绑定。
Proxy的优势如下
Object.defineProperty 的优势如下
Object.defineProperty 不足在于:
就是能够自动追踪数据的变化,而不必手动触发视图更新。Vue2.X通过Object.defineProperty()做数据劫持,而Vue3通过Proxy做数据代理,从而捕捉到对数据的get和set。
简单说就是用户更改数据(Data)时,视图可以自动刷新,页面UI能够响应数据变化。
因为这是Vue的立身之本呀,连尤雨溪都在给放文档上这样说,“Vue 最独特的特性之一,是其非侵入性的响应式系统。”
Vue就是通过getter 和setter来对数据进行操作,通过get()和set()函数可以生成一个虚拟属性,来直接调用函数操作数据。这一步是被封装起来的,我们是看不到的。
此外,还需要一个重要的媒介API,那就是Object.defineProperty,因为对象被定义完成后,想要更改或添加属性(像是get和set这样的属性),只能通过这个Object.defineProperty来添加。接着需要实现对数据属性的读写进行监控。能够监控就意味着能让vm(一般生成的实例)能够知道数据有变化,从而触发render(data)函数,页面UI就会做出响应。
1.减少对真实DOM的操作
Diff 算法探讨的就是虚拟 DOM 树发生变化后,生成 DOM 树更新补丁的方式。对比新旧两株虚拟 DOM 树的变更差异,将更新补丁作用于真实 DOM,以最小成本完成视图更新。
具体流程:
这样一个生成补丁、更新差异的过程统称为 diff 算法。
这里涉及3个要点:
通过diff算法能准确的获取到具体的节点 进行针对操作!!!
因为 Vue 的响应式系统已经在初次渲染时收集了渲染依赖的数据项,通过自动的方式就能够得到相当不错的性能。不过,在一些场景下,手动控制刷新检查还是能够进一步提升渲染性能的
vue 的机制,其实就是个依赖关系管理机制。不管是计算属性,watcher,以及 renderer,站在外部看,模型都是一样的,即初始化的时候通过一些方法分析出来这个模块依赖谁,等被依赖的数据更新了,这些模块就重新运算一遍产出物(实际上不尽然,比如计算属性有惰性机制)。
具体到 renderer,哪些数据的变更会引起 dom 变更,在模板编译的时候已经确定了,并且写死在生成的代码里了。
而 react 是没有这种自动机制的,它去执行 render 唯一的原因就是你主动让他 render。那你什么时候让它 render 呢?工程上一般是使用一个数据流工具,数据有变化的时候发出一个事件,一股脑把数据推过来,不区分哪个字段有变更(你区分了也没用,renderer 根本不认)。如果这个数据流模型是多个组件共用的,那必然是在 render 之前有个 hook 给我们个机会告诉组件“这次没你的事儿”,有利于性能优化。
那么,我们有没有可能不增加代码静态分析环节,搞清楚 react renderer 到底依赖哪些数据,继而把这个判断自动做掉呢?依我看不太可能,因为我们不能保证运行期跑一遍 render,它就会一次性访问它所有可能访问的数据。
1、key的作用主要是为了搞笑的更新虚拟dom,其原理是vue在patch过程中通过key可以精准判断两个节点是否是同一个,从而避免频繁更新不同元素,使得整个patch过程更加高效,减少dom操作量,提高性能。2、另外,若不设置key还可能在列表更新时候引发一些隐藏的bug。3、vue中在使用相同标签名元素的过渡切换时,也会使用到key属性,其目的也是为了让vue可以区分它们,否则vue只会替换其内部属性而不会触发过渡效果。
看了上面的介绍其实也很容易明白为什么不能用index作为key。
1、影响性能:当用index作为key的时候,删除节点后面的所有节点都会导致重新渲染,因为index变化了,可以也就变化了
有人说,当你的列表数据没有变化的时候可以用index作为key。也就是说列表不会触发更新元素,只有静态展示。这种说法你怎么看呢?之所以说到这个问题,是在vue官方群里面一群人应为这个问题讨论半天。我弱弱回复一句,任何情况下都不要用index作为key。结果遭到炮轰,哎!(除非前端写死的list,且无操作不会引起key变化,只要是后端数据,前端怎么能保证数据不变呢)。关于这个问题,我有这样三点想法:
1、代码的规范性2、类比typescript,为什么变量要加类型,除了规范,也方便定位错误3、列表的顺序稳定其实是难以保证的
JSX就是Javascript和XML结合的一种格式。React发明了JSX,利用HTML语法来创建虚拟DOM。当遇到<,JSX就当HTML解析,遇到{就当JavaScript解析.
是使用的的模板语法,Vue的模板实际上就是编译成了 render 函数,同样支持 JSX 语法。在 Vue 官网中,提供 createElement 函数中使用模板中的功能。
但是极少数的 VUE项目用JSX语法 JSX语法 根植在react上面 在vue上还是 template舒服!
到此这篇vue钩子函数有哪些含义(vue的钩子函数作用是什么)的文章就介绍到这了,更多相关内容请继续浏览下面的相关推荐文章,希望大家都能在编程的领域有一番成就!版权声明:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权、违法违规、事实不符,请将相关资料发送至xkadmin@xkablog.com进行投诉反馈,一经查实,立即处理!
转载请注明出处,原文链接:https://www.xkablog.com/qdvuejs/12233.html