admin管理员组文章数量:1567046
Vue面试题
- Vue
- Vue优点?
- Vue组件中data为什么必须是一个函数?
- 渐进式框架的理解。
- 请说出vue.cli项目中src目录每个文件夹和文件的用法
- vue修改打包后静态资源路径的修改
- assets和static的区别
- 封装 vue 组件的过程?
- MVC MVVM
- 对 MVC、MVVM 的区别以及理解
- 说一下 Vue 的双向绑定数据的原理
- 解释单向数据流和双向数据绑定
- Vue中双向数据绑定是如何实现的?
- Vue路由
- Vue路由实现
- Vue里面router-link在电脑上有用,在安卓上没反应怎么解决?
- router-link在IE和Firefox中不起作用(路由不跳转)的问题
- Vue2中注册在router-link上事件无效解决方法
- active-class 是哪个组件的属性?
- Vue-router跳转和location.href有什么区别
- Vue如何去除URL中的#
- hash模式 和 history模式
- $route 和 $router 的区别
- vue-router 有哪几种导航钩子?
- vue-router实现路由懒加载( 动态加载路由 )
- params和query的区别
- vue插槽——slot
- Vue 等单页面应用的优缺点
- Vue生命周期的理解
- 第一次页面加载会触发哪几个钩子?
- 组件通信
- Vuex是什么?如何使用?哪种功能场景使用它?
- Vue.js中ajax请求代码应该写在组件的methods中还是vuex的actions中?
- $NextTick 是做什么的
- Vue 组件 data 为什么必须是函数
- vue中的 methods,computed,watcher
- 对比 jQuery ,Vue 有什么不同
- Vue中怎么自定义指令
- Vue 中怎么自定义过滤器
- axios
- axios及安装?
- 特点有哪些?
- 对 keep-alive 的了解
- Vue与Angular以及React的区别?
- 一句话就能回答的面试题
- css只在当前组件起作用
- v-if和v-for的优先级
- v-if 和 v-show 区别
- vue.js的两个核心是什么?
- vue几种常用的指令
- vue常用的修饰符?
- v-on 可以绑定多个方法吗?
- vue中 key 值的作用?
- 什么是vue的计算属性?
- 如何获取dom?
- 你们vue项目是打包了一个js文件,一个css文件,还是有多个文件?
- vue初始化页面闪动问题
- vue更新数组时触发视图更新的方法
Vue
Vue优点?
- 轻量级框架: 只关注视图层,是一个构建数据的视图集合,大小只有几十 kb ;
- 简单易学: 国人开发,中文文档,不存在语言障碍 ,易于理解和学习;
- 双向数据绑定: 保留了
angular
的特点,在数据操作方面更为简单; - 组件化: 保留了
react
的优点,实现了html
的封装和重用,在构建单页面应用方面有着独特的优势;
视图,数据,结构分离:使数据的更改更为简单,不需要进行逻辑代码的修改,只需要操作数据就能完成相关操作; - 虚拟DOM:
dom
操作是非常耗费性能的, 不再使用原生的dom
操作节点,极大解放dom
操作,但具体操作的还是dom
不过是换了另一种方式; - 运行速度更快: 相比较于
react
而言,同样是操作虚拟dom
,就性能而言,vue
存在很大的优势。
Vue组件中data为什么必须是一个函数?
答:因为 JavaScript
的特性所导致,在 component
中,data
必须以函数的形式存在,不可以是对象。组建中的 data
写成一个函数,数据以函数返回值的形式定义,这样每次复用组件的时候,都会返回一份新的 data
,相当于每个组件实例都有自己私有的数据空间,它们只负责各自维护的数据,不会造成混乱。而单纯的写成对象形式,就是所有的组件实例共用了一个 data
,这样改一个全都改了。
渐进式框架的理解。
答:主张最少;可以根据不同的需求选择不同的层级;
作者:徐飞
链接:https://www.zhihu/question/51907207/answer/136559185
在我看来,渐进式代表的含义是:主张最少。每个框架都不可避免会有自己的一些特点,从而会对使用者有一定的要求,这些要求就是主张,主张有强有弱,它的强势程度会影响在业务开发中的使用方式。比如说,Angular,它两个版本都是强主张的,如果你用它,必须接受以下东西:- 必须使用它的模块机制- 必须使用它的依赖注入- 必须使用它的特殊形式定义组件(这一点每个视图框架都有,难以避免)所以Angular是带有比较强的排它性的,如果你的应用不是从头开始,而是要不断考虑是否跟其他东西集成,这些主张会带来一些困扰。比如React,它也有一定程度的主张,它的主张主要是函数式编程的理念,比如说,你需要知道什么是副作用,什么是纯函数,如何隔离副作用。它的侵入性看似没有Angular那么强,主要因为它是软性侵入。你当然可以只用React的视图层,但几乎没有人这么用,为什么呢,因为你用了它,就会觉得其他东西都很别扭,于是你要引入Flux,Redux,Mobx之中的一个,于是你除了Redux,还要看saga,于是你要纠结业务开发过程中每个东西有没有副作用,纯不纯,甚至你连这个都可能不能忍:const getData = () => { // 如果不存在,就在缓存中创建一个并返回 // 如果存在,就从缓存中拿}因为你要纠结它有外部依赖,同样是不加参数调用,连续两次的结果是不一样的,于是不纯。为什么我一直不认同在中后台项目中使用React,原因就在这里,我反对的是整个业务应用的函数式倾向,很多人都是看到有很多好用的React组件,就会倾向于把它引入,然后,你知道怎么把自己的业务映射到函数式的那套理念上吗?函数式编程,无副作用,写出来的代码没有bug,这是真理没错,但是有两个问题需要考虑:1. JS本身,有太多特性与纯函数式的主张不适配,这一点,题叶能说得更多2. 业务系统里面的实体关系,如何组织业务逻辑,几十年来积累了无数的基于设计模式的场景经验,有太多的东西可以模仿,但是,没有人给你总结那么多如何把你的厚重业务映射到函数式理念的经验,这个地方很考验综合水平的,真的每个人都有能力去做这种映射吗?函数式编程无bug的根本就在于要把业务逻辑完全都依照这套理念搞好,你看看自己公司做中后台的员工,他们熟悉的是什么?是基于传统OO设计模式的这套东西,他们以为拿着你们给的组件库就得到了一切,但是可能还要被灌输函数式编程的一整套东西,而且又没人告诉他们在业务场景下,如何规划业务模型、组织代码,还要求快速开发,怎么能快起来?所以我真是心疼这些人,他们要的只是组件库,却不得不把业务逻辑的思考方式也作转换,这个事情没有一两年时间洗脑,根本洗不到能开发业务的程度。没有好组件库的时候,大家痛点在视图层,有了基于React的组件化,把原先没那么痛的业务逻辑部分搞得也痛起来了,原先大家按照设计模式教的东西,照猫画虎还能继续开发了,学了一套新理念之后,都不知道怎么写代码了,怎么写都怀疑自己不对,可怕。我宁可支持Angular也不支持React的原因也就在此,Angular至少在业务逻辑这块没有软主张,能够跟OO设计模式那套东西配合得很好。我面对过很多商务场景,都是前端很厚重的东西,不仅仅是管理控制台这种,这类东西里面,业务逻辑的占比要比视图大挺多的,如何组织这些东西,目前几个主流技术栈都没有解决方案,要靠业务架构师去摆平。如果你的场景不是这么厚重的,只是简单管理控制台,那当我没说好了。框架是不能解决业务问题的,只能作为工具,放在合适的人手里,合适的场景下。现在我要说说为什么我这么支持Vue了,没什么,可能有些方面是不如React,不如Angular,但它是渐进的,没有强主张,你可以在原有大系统的上面,把一两个组件改用它实现,当jQuery用;也可以整个用它全家桶开发,当Angular用;还可以用它的视图,搭配你自己设计的整个下层用。你可以在底层数据逻辑的地方用OO和设计模式的那套理念,也可以函数式,都可以,它只是个轻量视图而已,只做了自己该做的事,没有做不该做的事,仅此而已。渐进式的含义,我的理解是:没有多做职责之外的事。
请说出vue.cli项目中src目录每个文件夹和文件的用法
- assets 文件夹是放静态资源;
- components 是放组件;
- router 是定义路由相关的配置;
- app.vue 是一个应用主组件;
- main.js 是入口文件。
vue修改打包后静态资源路径的修改
cli2 版本: 将 config/index.js
里的 assetsPublicPath
的值改为 ./
。
build: {
// ...
assetsPublicPath: ./ ,
// ...
}
cli3版本: 在根目录下新建vue.config.js
文件,然后加上以下内容:(如果已经有此文件就直接修改)
module.exports = {
publicPath: , // 相对于 HTML 页面(目录相同)
}
assets和static的区别
-
相同点:
assets
和static
两个都是存放静态资源文件。项目中所需要的资源文件图片,字体图标,样式文件等都可以放在这两个文件下,这是相同点 -
不相同点:
assets
中存放的静态资源文件在项目打包时,也就是运行npm run build
时会将assets
中放置的静态资源文件进行打包上传,所谓打包简单点可以理解为压缩体积,代码格式化。而压缩后的静态资源文件最终也都会放置在static
文件中跟着index.html
一同上传至服务器。static
中放置的静态资源文件就不会要走打包压缩格式化等流程,而是直接进入打包好的目录,直接上传至服务器。因为避免了压缩直接进行上传,在打包时会提高一定的效率,但是static
中的资源文件由于没有进行压缩等操作,所以文件的体积也就相对于assets
中打包后的文件提交较大点。在服务器中就会占据更大的空间。 -
建议: 将项目中
template
需要的样式文件js
文件等都可以放置在assets
中,走打包这一流程。减少体积。而项目中引入的第三方的资源文件如iconfoont.css
等文件可以放置在static
中,因为这些引入的第三方文件已经经过处理,我们不再需要处理,直接上传。
封装 vue 组件的过程?
- 建立组件的模板,先把架子搭起来,写写样式,考虑好组件的基本逻辑。(os:思考1小时,码码10分钟,程序猿的准则。)
- 准备好组件的数据输入。即分析好逻辑,定好 props 里面的数据、类型。
- 准备好组件的数据输出。即根据组件逻辑,做好要暴露出来的方法。
- 封装完毕了,直接调用即可
MVC MVVM
对 MVC、MVVM 的区别以及理解
- MVC特点:
- 所有通信都是单向的
- MVC介绍
- View 传送指令到
Controller
; - Controller 完成业务逻辑后要求
Model
改变状态; - Model 将新的数据发送到
View
,用户得到反馈。
- View 传送指令到
- MVVM 特点:
- 各部分之前的通信,都是双向的;
- 采用双向绑定:
View
的变动,自动反映在ViewModel
,反之亦然。
- MVVM介绍
MVVM
是Model-View-ViewModel
的缩写。Model
代表数据模型,也可以在Model
中定义数据修改和操作的业务逻辑。view
代表 UI 组件,它负责将数据模型转化成 UI 展现出来。ViewModel
监听模型数据的改变和控制视图行为、处理用户交互,简单理解就是一个同步View
和Model
的对象,连接Model
和View
。- 在
MVVM
架构下,View
和Model
之间并没有直接的联系,而是通过ViewModel
进行交互,Model
和ViewModel
之间的交互是双向的, 因此View
数据的变化会同步到Model
中,而Model
数据的变化也会立即反应到View
上。 ViewModel
通过双向数据绑定把View
层和Model
层连接了起来,而View
和Model
之间的同步工作完全是自动的,无需人为干涉,因此开发者只需关注业务逻辑,不需要手动操作DOM
, 不需要关注数据状态的同步问题,复杂的数据状态维护完全由MVVM
来统一管理。
说一下 Vue 的双向绑定数据的原理
- vue 实现数据双向绑定主要是:采用
数据劫持结合“发布者 - 订阅者”模式的方式
,通过Object.defineProperty()
来劫持各个属性的setter
、getter
,在数据变动时发布消息给订阅者,触发相应监听回调。
解释单向数据流和双向数据绑定
- 单向数据流:顾名思义,数据流是单向的。数据流动方向可以跟踪,流动单一,追查问题的时候可以更快捷。缺点就是写起来不太方便。要使 UI 发生变更就必须创建各种
action
来维护对应的state
。 - 双向数据绑定:数据之间是相通的,将数据变更的操作隐藏在框架内部。优点是在表单交互较多的场景下,会简化大量与业务无关的代码。缺点就是无法追踪局部状态的变化,增加了出错时 debug 的难度。
Vue中双向数据绑定是如何实现的?
vue双向数据绑定
是通过 数据劫持 结合 发布订阅模式的方式来实现的, 也就是说数据和视图同步,数据发生变化,视图跟着变化,视图变化,数据也随之发生改变;核心:关于 vue双向数据绑定
,其核心是 Object.defineProperty()
方法。
Vue路由
Vue路由实现
- 路由就是用来跟后端服务器进行交互的一种方式,通过不同的路径,来请求不同的资源,请求不同的页面是路由的其中一种功能。
Vue里面router-link在电脑上有用,在安卓上没反应怎么解决?
Vue
路由在Android机上有问题,babel
问题,安装babel
polypill
插件解决。
router-link在IE和Firefox中不起作用(路由不跳转)的问题
方法一: 只用a标签,不适用button标签;
方法二: 使用button标签和Router.navigate方法
Vue2中注册在router-link上事件无效解决方法
使用 @click.native
。原因:router-link
会阻止click
事件,.native
指直接监听一个原生事件。
active-class 是哪个组件的属性?
vue-router
模块的 router-link
组件。children
数组来定义子路由
Vue-router跳转和location.href有什么区别
使用 location.href= /url
来跳转,简单方便,但是刷新了页面;使用 history.pushState( /url )
,无刷新页面,静态跳转;引进 router
,然后使用 router.push( /url )
来跳转,使用了 diff
算法,实现了按需加载,减少了 dom
的消耗。其实使用 router
跳转和使用 history.pushState()
没什么差别的,因为 vue-router
就是用了 history.pushState()
,尤其是在 history
模式下。
Vue如何去除URL中的#
vue-router
默认使用hash
模式,所以在路由加载的时候,项目中的 URL 会自带 “#”。如果不想使用 “#”, 可以使用vue-router
的另一种模式history:new Router ({ mode : 'history', routes: [ ]})
。- 需要注意的是:当我们启用 history 模式的时候,由于我们的项目是一个单页面应用,所以在路由跳转的时候,就会出现访问不到静态资源而出现 “404” 的情况,这时候就需要服务端增加一个覆盖所有情况的候选资源:如果 URL 匹配不到任何静态资源,则应该返回同一个 “index.html” 页面。
hash模式 和 history模式
- hash模式:在浏览器中符号
"#"
,#
以及#
后面的字符称之为hash
,用window.location.hash
读取;- 特点:
hash
虽然在URL
中,但不被包括在HTTP
请求中;用来指导浏览器动作,对服务器安全无用,hash
不会重加载页面。 hash
模式下,仅hash
符号之间的内容会被包含在请求中,如http://www.xxx
,因此对于后端来说,即使没有做到对路由的全覆盖,也不会返回 404 错误。
- 特点:
- history模式:(需要特定浏览器支持)
history
采用HTML5
的新特性History Interface
中新增的pushState()
,replaceState()
可以对浏览器历史记录栈进行修改,以及popState
事件的监听到状态变更。history
模式下,前端的URL
必须和实际向后端发起请求的URL
一致,如http://www.xxx/items/id
。后端如果缺少对/items/id
的路由处理,将返回404
错误。Vue-Router
官网里如此描述:“不过这种模式要玩好,还需要后台配置支持……所以呢,你要在服务端增加一个覆盖所有情况的候选资源:如果URL
匹配不到任何静态资源,则应该返回同一个index.html
页面,这个页面就是你app
依赖的页面。”
$route 和 $router 的区别
$router
为VueRouter
实例,想要导航到不同URL
,则使用$router.push
方法。返回上一个历史history
用$router.to(-1)
$route
为当前router
跳转对象里面可以获取name
、path
、query
、params
等。
vue-router 有哪几种导航钩子?
第一种: 是全局导航钩子:router.beforeEach(to,from,next)
,作用:跳转前进行判断拦截。
+ beforeEach 主要有3个参数 to ,from ,next
。 作用:跳转前进行判断拦截
+ to:route
即将进入的目标路由对象,
+ from:route
当前导航正要离开的路由
+ next:function
一定要调用该方法 resolve
这个钩子。执行效果依赖 next
方法的调用参数。可以控制网页的跳转。
第二种: 组件内的钩子
第三种: 单独路由独享组件
vue-router实现路由懒加载( 动态加载路由 )
第一种: vue
异步组件技术 ==== 异步加载,vue-router
配置路由 , 使用vue
的异步组件技术 , 可以实现按需加载 .但是,这种情况下一个组件生成一个js
文件。
第二种: 路由懒加载(使用import
)。
第三种: webpack
提供的require.ensure()
,vue-router
配置路由,使用webpack
的require.ensure
技术,也可以实现按需加载。这种情况下,多个路由指定相同的chunkName
,会合并打包成一个js
文件。
params和query的区别
用法: query
要用path
来引入,params
要用name
来引入,接收参数都是类似的,分别是 this.$route.query.name
和 this.$route.params.name
。url
地址显示:query
更加类似于我们ajax
中get
传参,params
则类似于post
,说的再简单一点,前者在浏览器地址栏中显示参数,后者则不显示
注意点: query
刷新不会丢失query
里面的数据 params
刷新会丢失 params
里面的数据。
vue插槽——slot
引用地址: https://segmentfault/a/1190000012996217
- 插槽,也就是
slot
,是组件的一块HTML
模板,这块模板显示不显示、以及怎样显示由父组件来决定。 实际上,一个slot
最核心的两个问题这里就点出来了,是显示不显示和怎样显示。 - 由于插槽是一块模板,所以,对于任何一个组件,从模板种类的角度来分,其实都可以分为非插槽模板和插槽模板两大类。
- 非插槽模板指的是
html
模板,指的是div、span、ul、table
这些,非插槽模板的显示与隐藏以及怎样显示由插件自身控制;插槽模板是slot
,它是一个空壳子,因为它显示与隐藏以及最后用什么样的html
模板显示由父组件控制。但是插槽显示的位置确由子组件自身决定,slot
写在组件template
的哪块,父组件传过来的模板将来就显示在哪块。 - 分类:单个插槽 | 默认插槽 | 匿名插槽
Vue 等单页面应用的优缺点
- 优点
- 良好的交互体验
- 良好的前后端工作分离模式
- 减轻服务器压力
- 切换页面效果会比较炫酷
- 缺点
SEO
难度较高(建议通过服务端来进行渲染组件)- 导航不可用(由于是单页面不能用浏览器的前进后退功能,所以需要自己建立堆栈管理)
- 初次加载耗时多(安装动态懒加载所需插件;使用CDN资源。)
- 不支持低版本的浏览器
Vue生命周期的理解
- beforeCreated():在实例创建之间执行,数据未加载状态。
- 在new一个vue实例后,只有一些默认的生命周期钩子和默认事件,其他的东西都还没创建。在beforeCreate生命周期执行的时候,data和methods中的数据都还没有初始化。不能在这个阶段使用data中的数据和methods中的方法
- created():在实例创建,数据加载后,能初始化数据,
DOM
渲染之前执行。- data 和 methods都已经被初始化好了,如果要调用 methods 中的方法,或者操作 data 中的数据,最早可以在这个阶段中操作
- 用于: 初始化某些属性值
- beforeMount():虚拟
DOM
已创建完成,在数据渲染前最后一次更改数据。- 执行到这个钩子的时候,在内存中已经编译好了模板了,但是还没有挂载到页面中,此时,页面还是旧的
- mounted():页面、数据渲染完成,真实
DOM
挂载完成。- 执行到这个钩子的时候,就表示Vue实例已经初始化完成了。此时组件脱离了创建阶段,进入到了运行阶段。如果我们想要通过插件操作页面上的DOM节点,最早可以在和这个阶段中进行
- 用于: 初始化页面完成后,再对html的dom节点进行一些需要的操作。
- beforeUpdate():重新渲染之前触发。
- 当执行这个钩子时,页面中的显示的数据还是旧的,data中的数据是更新后的, 页面还没有和最新的数据保持同步
- updated():数据已经更改完成,
DOM
也重新render
完成,更改数据会陷入死循环。- 页面显示的数据和data中的数据已经保持同步了,都是最新的
- beforeDestory() 和 destoryed() :前者是销毁前执行(实例仍然完全可用,后者则是销毁后执行)
- beforeDestory():
Vue
实例从运行阶段进入到了销毁阶段,这个时候上所有的data
和methods
, 指令, 过滤器 ……都是处于可用状态。还没有真正被销毁 - destoryed(): 这个时候上所有的
data
和methods
, 指令, 过滤器 ……都是处于不可用状态。组件已经被销毁了。
- beforeDestory():
第一次页面加载会触发哪几个钩子?
beforeCreate, created, beforeMount, mounted
组件通信
- 父组件向子组件通信
- 子组件用过
props
属性,绑定父组件数据,实现双方通信。
- 子组件用过
- 子组件向父组件通信
- 将父组件的事件在子组件中通过
$emit
触发。
- 将父组件的事件在子组件中通过
- 非父子组件、兄弟组件之间的数据传递
- /* 新建一个Vue实例作为中央事件总监 */
let event = new Vue ()
;
- /* 新建一个Vue实例作为中央事件总监 */
/* 监听事件 */
event.$on( 'eventName' , (val) => { //......do something });
/* 触发事件 */
event.$emit( 'eventName' , 'this is amessage' );
Vuex是什么?如何使用?哪种功能场景使用它?
- 只用来读取的状态集中放在
store
中; 改变状态的方式是提交mutations
,这是个同步的事物; 异步逻辑应该封装在action
中。 - 在
main.js
引入store
,注入。新建了一个目录store
,….. export
。 - 场景有:单页应用中,组件之间的状态、音乐播放、登录状态、加入购物车
-
state => 基本数据(数据源存放地)
Vuex
使用单一状态树,即每个应用将仅仅包含一个store
实例,但单一状态树和模块化并不冲突。存放的数据状态,不可以直接修改里面的数据。 -
mutations => 提交更改数据的方法,同步!
mutations
定义的方法动态修改Vuex
的store
中的状态或数据。 -
getters => 从基本数据派生出来的数据
类似vue
的计算属性,主要用来过滤一些数据。 -
action => 像一个装饰器,包裹
mutations
,使之可以异步。
actions
可以理解为通过将mutations
里面处里数据的方法变成可异步的处理数据的方法,简单的说就是异步操作数据。view 层通过store.dispath
来分发action
。 -
modules => 模块化Vuex
项目特别复杂的时候,可以让每一个模块拥有自己的state、mutation、action、getters,
使得结构非常清晰,方便管理。
Vue.js中ajax请求代码应该写在组件的methods中还是vuex的actions中?
- 如果请求来的数据是不是要被其他组件公用,仅仅在请求的组件内使用,就不需要放入
vuex
的state
里。 - 如果被其他地方复用,这个很大几率上是需要的,如果需要,请将请求放入
action
里,方便复用。
$NextTick 是做什么的
$nextTick
是在下次DOM
更新循环结束之后执行延迟回调,在修改数据之后使用$nextTcik
,则可以在回调中获取更新后的DOM
。- 当你修改了
data
的值然后马上获取这个dom
元素的值,是不能获取到更新后的值, 你需要使用$nextTick
这个回调,让修改后的data
值渲染更新到dom
元素之后在获取,才能成功。 - 应用场景:需要在视图更新之后,基于新的视图进行操作。
- 例如:点击按钮显示原本以
v-show = false
隐藏起来的输入框,并获取焦点。
- 例如:点击按钮显示原本以
showsou(){
this.showit = true //修改 v-show
document.getElementById("keywords").focus()
//在第一个 tick 里,获取不到输入框,自然也获取不到焦点
}
修改为:
showsou(){
this.showit = true
this.$nextTick(function () {
// DOM 更新了
document.getElementById("keywords").focus()
})
}
- 具体可参考官方文档:深入响应式原理
(https://cn.vuejs/v2/guide/reactivity.html)
。
Vue 组件 data 为什么必须是函数
- 因为
JS
本身的特性带来的,如果data
是一个对象,那么由于对象本身属于引用类型,当我们修改其中的一个属性时,会影响到所有Vue
实例的数据,如果将data
作为一个函数返回一个对象,那么每一个实例的data
属性都是独立的,不会互相影响了。
vue中的 methods,computed,watcher
- 我们可以将同一函数定义为一个
method
或者一个computed
,对于最终结果,两种方式是相同的。 - 不同点:
- computed:计算属性时基于它们的依赖进行缓存的,只有在它的相关依赖发生改变时才会重新求值。(场景:引用一些经过操作的数据,购物车商品结算的时候)
- methods:只要发生重新渲染,
method
调用总会执行该函数(场景:方法的调用)。 - watcher:可以用来监测
Vue
实例上的数据变动(场景:监听路由地址,搜索数据)
对比 jQuery ,Vue 有什么不同
jQuery
专注视图层,通过操作DOM
去实现页面的一些逻辑渲染;Vue
专注于数据层,通过数据的双向绑定,最终表现在DOM
层面,减少了DOM
操作。Vue
将数据和View完全分离,使用了组件化思想,使得项目子集职责清晰,提高了开发效率,方便重复利用,便于协同开发。
Vue中怎么自定义指令
- 全局注册
<body>
<div id="app">
<div class="txt" v-test:aaa.trim="100+2"></div>
</div>
<script src="vue.js"></script>
<script>
Vue.directive('test', {
inserted: function(el, binding) {
el.innerText = binding.value
console.log(el) // 绑定的元素: <div class="txt"></div>
console.log(binding.name) // 指令名字: test
console.log(binding.value) // 值: 102
console.log(binding.expression) // 表达式: 100+2
console.log(binding.arg) // 指令参数: aaa
console.log(binding.modifiers) // 指令修饰符: {trim: true}
}
})
new Vue({
el: '#app'
})
</script>
</body>
- 局部注册
<body>
<div id="app">
<div class="box">
<input type="text" v-focus>
</div>
</div>
<script src="vue.js"></script>
<script>
new Vue({
el: '#app',
data: {},
directives: {
focus: {
// 当被绑定的元素插入到 DOM 中时……
inserted: function(el, binding) {
el.focus() // 聚焦元素
}
}
}
})
</script>
</body>
Vue 中怎么自定义过滤器
- 可以用全局方法
Vue.filter()
注册一个自定义过滤器,它接收两个参数:过滤器 ID 和过滤器函数。过滤器函数以值为参数,返回转换后的值。 - 过滤器也同样接受全局注册和局部注册。
<body>
<div id="app">
<h1>{{通过管道传递的数据 | 对应过滤器的方法名('参数1',‘参数2’)}}</h1>
<h1>{{price | myCurrency('¥',‘$’)}}</h1>
</div>
<script src="vue.js"></script>
<script>
//过滤器的本质 就是一个有参数有返回值的方法
Vue.filters:{
//myInput是通过管道传来的数据
//arg1在调用过滤器时在圆括号中第一个参数
//arg2在调用过滤器时在圆括号中第二个参数
myCurrency:function(myInput,arg1,arg2){
console.log(arg1,arg2);
//根据业务需要,对传来的数据进行处理
// 并返回处理后的结果
var result = arg1+myInput+arg2;
return result;
}
}
new Vue({
el: '#app',
data: {
price:356
}
})
</script>
</body>
</html>
axios
axios及安装?
答:请求后台资源的模块。npm install axios —save
装好, js
中使用 import
进来,然后 .get
或 .post
。返回在 .then
函数中如果成功,失败则是在 .catch
函数中。
特点有哪些?
- 从浏览器中创建
XMLHttpRequests
; node.js
创建http
请求;- 支持
Promise API
; - 拦截请求和响应;
- 转换请求数据和响应数据;
- 取消请求;
- 自动换成
json
。 axios
中的发送字段的参数是data
跟params
两个,两者的区别在于params
是跟请求地址一起发送的,data
的作为一个请求体进行发送params
一般适用于get
请求,data
一般适用于post put
请求。
对 keep-alive 的了解
<keep-alive>
是 Vue 内置的一个组件,可以使被包含的组件保留状态,或避免重新渲染。<keep-alive>
生命周期钩子函数:activated
、deactivated
- 使用会将数据保留在内存中,如果要在每次进入页面的时候获取最新的数据,需要在
activated
阶段获取数据,承担原来created
钩子中获取数据的任务。 - 被包含在 中创建的组件,会多出两个生命周期的钩子:
activated
与deactivated
activated
:在组件被激活时调用,在组件第一次渲染时也会被调用,之后每次<keep-alive>
激活时被调用。deactivated
:在组件被停用时调用。- 注意:只有组件被
<keep-alive>
包裹时,这两个生命周期才会被调用,如果作为正常组件使用,是不会被调用,以及在 2.1.0 版本之后,使用exclude
排除之后,就算被包裹在<keep-alive>
中,这两个钩子依然不会被调用!另外在服务端渲染时此钩子也不会被调用的。 - 什么时候获取数据?
- 当引入
<keep-alive>
的时候,页面第一次进入,钩子的触发顺序created
=>mounted
=>activated
,退出时触发deactivated
。当再次进入(前进或者后退)时,只触发activated
。
- 当引入
- 使用会将数据保留在内存中,如果要在每次进入页面的时候获取最新的数据,需要在
<keep-alive>
的 props :- include:定义缓存白名单,会缓存名单里面的组件
- exclude:定义缓存黑名单,被命中的组件不会被缓存
- max:定义缓存组件的上限
<keep-alive include='include_components' exclude='exclude_components'>
<component>
<!-- 该组件是否缓存取决于include和exclude属性 -->
</component>
</keep-alive>
- include - 字符串或正则表达式,只有名称匹配的组件会被缓存
- exclude - 字符串或正则表达式,任何名称匹配的组件都不会被缓存
- include 和 exclude 的属性允许组件有条件地缓存。二者都可以用“,”分隔字符串、正则表达式、数组。当使用正则或者是数组时,要记得使用v-bind 。
<!-- 逗号分隔字符串,只有组件a与b被缓存。 -->
<keep-alive include="a,b">
<component></component>
</keep-alive>
<!-- 正则表达式 (需要使用 v-bind,符合匹配规则的都会被缓存) -->
<keep-alive :include="/a|b/">
<component></component>
</keep-alive>
<!-- Array (需要使用 v-bind,被包含的都会被缓存) -->
<keep-alive :include="['a', 'b']">
<component></component>
</keep-alive>
Vue与Angular以及React的区别?
-
与AngularJS的区别
相同点:
都支持指令:内置指令和自定义指令;都支持过滤器:内置过滤器和自定义过滤器;都支持双向数据绑定;都不支持低端浏览器。不同点:
AngularJS的学习成本高,比如增加了Dependency Injection特性,而Vue.js本身提供的API都比较简单、直观;在性能上,AngularJS依赖对数据做脏检查,所以Watcher越多越慢;Vue.js使用基于依赖追踪的观察并且使用异步队列更新,所有的数据都是独立触发的。 -
与React的区别
相同点:
React采用特殊的JSX语法,Vue.js在组件开发中也推崇编写.vue特殊文件格式,对文件内容都有一些约定,两者都需要编译后使用;中心思想相同:一切都是组件,组件实例之间可以嵌套;都提供合理的钩子函数,可以让开发者定制化地去处理需求;都不内置列数AJAX,Route等功能到核心包,而是以插件的方式加载;在组件开发中都支持mixins的特性。
不同点:
React采用的Virtual DOM会对渲染出来的结果做脏检查;Vue.js在模板中提供了指令,过滤器等,可以非常方便,快捷地操作Virtual DOM。
一句话就能回答的面试题
css只在当前组件起作用
答:在 style
标签中写入 scoped
即可 例如:<style scoped></style>
v-if和v-for的优先级
答:当 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-show 区别
答:v-if
按照条件是否渲染,v-show
是 display
的 block
或 none
;
-
使用
v-if
的时候,如果值为false
,那么页面将不会有这个html
标签生成。 -
v-show
则是不管值为true
还是false
,html
元素都会存在,只是CSS
中的display
显示或隐藏。 -
共同点: 都能控制元素的显示和隐藏;
-
不同点: 实现本质方法不同,
v-show
本质就是通过控制css
中的display
设置为none
,控制隐藏,只会编译一次;v-if
是动态的向DOM
树内添加或者删除DOM
元素,若初始值为false
,就不会编译了。而且v-if
不停的销毁和创建比较消耗性能。总结:如果要频繁切换某节点,使用v-show
(切换开销比较小,初始开销较大)。如果不需要频繁切换某节点使用v-if
(初始渲染开销较小,切换开销比较大)
vue.js的两个核心是什么?
答:数据驱动、组件系统
数据驱动: ViewModel
,保证数据和视图的一致性。
组件系统: 应用类UI可以看作全部是由组件树构成的。
vue几种常用的指令
答:
- v-once: 只绑定一次。
- v-on: 事件绑定(
v-on
可以监听多个方法)。 - v-if,v-show: 显示与隐藏;
- v-for: 循环;
- v-model: v-model使用在表单中,实现双向数据绑定的,在表单元素外使用不起作用;
- v-bind: 用来绑定数据和属性以及表达式,缩写为’:’
vue常用的修饰符?
答:
.prevent:
等同于JavaScript
中的event.preventDefault()
,防止执行预设的行为(如果事件可取消,则取消该事件,而不停止事件的进一步传播);.stop:
等同于JavaScript
中的event.stopPropagation()
,阻止单击事件冒泡;.self:
当事件发生在该元素本身而不是子元素的时候会触发;.capture:
事件侦听,事件发生的时候会调用,与事件冒泡的方向相反,事件捕获由外到内.once:
只会触发一次。
v-on 可以绑定多个方法吗?
答:可以
vue中 key 值的作用?
答:key
的作用主要是为了高效的更新虚拟 DOM
。
key
的特殊属性主要用在Vue
的虚拟DOM
算法,在新旧nodes
对比时辨识VNodes
。如果不使用key
,Vue
会使用一种最大限度减少动态元素并且尽可能的尝试修复/再利用相同类型元素的算法。使用key
,它会基于key
的变化重新排列元素顺序,并且会移除key
不存在的元素。- 有相同父元素的子元素必须有独特的
key
。重复的key
会造成渲染错误。
什么是vue的计算属性?
答:在模板中放入太多的逻辑会让模板过重且难以维护,在需要对数据进行复杂处理,且可能多次使用的情况下,尽量采取计算属性的方式。好处:
①使得数据处理结构清晰;
②依赖于数据,数据更新,处理结果自动更新;
③计算属性内部this指向vm实例;
④在template调用时,直接写计算属性名即可;
⑤常用的是getter方法,获取数据,也可以使用set方法改变数据;
⑥相较于methods,不管依赖的数据变不变,methods都会重新计算,但是依赖数据不变的时候computed从缓存中获取,不会重新计算。
如何获取dom?
答:ref="domName"
用法:this.$refs.domName
你们vue项目是打包了一个js文件,一个css文件,还是有多个文件?
根据vue-cli
脚手架规范,一个js
文件,一个CSS
文件。
vue初始化页面闪动问题
使用vue
开发时,在vue
初始化之前,由于 div
是不归 vue
管的,所以我们写的代码在还没有解析的情况下会容易出现花屏现象,看到类似于 {{message}}
的字样,虽然一般情况下这个时间很短暂,但是我们还是有必要让解决这个问题的。首先:在css
里加上 [v-cloak] { display: none; }
。如果没有彻底解决问题,则在根元素加上 style="display: none;" :style="{display: block }"
vue更新数组时触发视图更新的方法
push();pop();shift();unshift();splice();sort();reverse()
版权声明:本文标题:vue面试题整理 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://m.elefans.com/dianzi/1727532209a1119635.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论