Vue必备面试题
- 1.vuex的作用?
- 2.axios是什么,它的作用?
- 3.列举vue的常见指令
- 4.v-if 和 v-show的区别
- 5.vue中key值的作用
- 6.vue组件间参数传递
- 7.请说说封装vue组件的过程
- 8.详细说一下你对vue生命周期的理解
- 9.vue-loader是什么?使用它的用途有哪些?
- 10.vue-router是什么?它有哪些组件?
- 11.Vue实现数据双向绑定的原理:Object.defineProperty()
- 12.vue-cli如何新增自定义指令
- 13.对keep-alive 的了解?
- 14.vue.js的两个核心是什么?
- 15.如何让CSS只在当前组件中起作用?
- 16.vue的优缺点
- 17.在Vue中使用插件的步骤
- 18. vue watch的高级用法--监听对象的属性变化
- 19.请说出vue.cli项目中src目录每个文件夹和文件的用法?
- 20.vue常见修饰符
- 21.MVVM和MVC的区别?
- 22.说一下vue封装组件中的slot作用
- 23.说一下你对单向数据流的理解
- 24.说一下vue中methods,computed,watch的区别:
- 25.说一下vue和jquey的区别
- 25.axios如何发同步请求?
- 26.axios如何封装?
- 27.vue.extend的理解?
- 28.前端路由和后端路由的区别
- 29.前端渲染和后端渲染的优缺点?
- 30.对vue.js中template编译的理解
1.vuex的作用?
vuex是专门为vue.js应用程序开发的状态管理模式,状态就是结果,样式,数据等,实现了对应用中所有组件的状态的全局管理。
vuex的几个核心概念
store,全局状态管理,主要包括state,mutations,actions,modules,getters五大属性。
- state : 用于存储数据,数据是全局的,都可以通过$store.state.名字来使用。
- mutations:用于操作state中的数据,是同步操作,通过**$store.commit**来触发。
- actions:用于操作mutations里面的函数,是异步操作,通过$store.dispatch来触发。
- modulus:模块化操作,项目比较复杂的时候使用。
- getters:把简单的数据(state中的数据)派生出复杂的数据,类似于计算属性,调用的时候直接$store.getters.名字就可以。
2.axios是什么,它的作用?
axios相当于vue中的ajax,用于向后端请求数据。
先安装,然后全局引入。
安装:
npm i axios -S
引入:
import axios from 'axios';
Vue.prototype.$axios = axios
使用:
this.$axios.get("路径").then( () => {
}
).catch( () => {} )
3.列举vue的常见指令
- 文本插值 : {{}}
- 属性绑定 : v-bind (:)
- 事件绑定 : v-on (@)
- 数据双向绑定 : v-model (主要是表单数据)
- 遍历 (列表渲染) : v-for
- 显示隐藏 : v-show
- 判断 : v-if 、v-else-if 、 v-else
4.v-if 和 v-show的区别
都可以用来控制元素的显示或隐藏,v-if根据条件通过操作dom节点的创建和删除来控制,而v-show通过display: none/block来控制,显然,频繁的创建和删除节点很耗性能,v-show的性能会更高一点。
5.vue中key值的作用
key值通常和v-for结合在一起使用,当vue用v-for更新已经被渲染过的元素时,vue不再重新渲染元素,而是根据它的唯一key值来显示每一个已经被渲染过的元素。主要就是更高效地更新虚拟DOM。
6.vue组件间参数传递
- 父向子传递 :通过参数,子组件通过props方法,定义好要接收的数据的类型,然后直接接收父级传递过来的数据。
- 子向父传递 : 通过方法,子组件通过$emit()来触发。这个方法里面可以有两个参数,第一个参数为触发的父级的事件名,第二个参数为传递给父级的参数。
7.请说说封装vue组件的过程
首先创建一个组件,然后通过props对象定义属性,并限制其类型,在要使用该组件的地方使用import引入该组件,然后使用components注册,就可以使用了这个自定义组件了。
组件可以提升整个项目的开发效率,能把抽象成多个相对独立的模块,即低耦合,解决了效率低,难维护的缺点。
使用自定义组件:
第一步:在components目录新建你的组件文件(smithButton.vue)
第二步:在需要用的页面(组件)中导入:import smithButton from ‘…/components/smithButton.vue’
第三步:注入到vue的子组件的components属性上面,components:{smithButton} 或者 components:{“smith-button” : smithButton} ,注意冒号前面的名字是你自定义的组件的名字,冒号后面的名字必须和你引入该组件时的名字一致(就是上面加粗的黑体必须保持一致)。
第四步:在template视图view中使用,< smith-button> < /smith-button>
8.详细说一下你对vue生命周期的理解
Vue 实例有一个完整的生命周期,也就是从开始创建、初始化数据、编译模版、挂载 Dom -> 渲染、更新 ->
渲染、卸载等一系列过程,我们称这是 Vue 的生命周期。 vue声明周期分为八个阶段,
创建前/后 :
在beforeCreate阶段,vue实例的挂载点el和数据对象data,都为undefined;created阶段之后,vue实例的data对象有了,但是el还是没有。
挂载前/后:
在beforeMount阶段,vue实例的el和data都有了,但是还是挂载之前,data。message还没有渲染,为虚拟DOM;mounted阶段之后,vue实例成功挂载,data.message成功渲染。
更新前/后:
当data变化时,会触发beforeUpdate和updated函数
销毁前/后:
在执行destroy函数后,对data的改变不会再触发周期函数,说明此时vue实例已经解除了事件监听以及DOM的绑定。
另外,使用keep-alive标签包裹动态组件,就会有activated和deactivated两个钩子函数,activated在被keep-alive缓存的组件被激活时调用,deactivated在被keep-alive缓存的组件被停用时调用。
最后还有一个捕获异常的生命周期函数:errorCaputered(err){}.
9.vue-loader是什么?使用它的用途有哪些?
解析.vue文件的一个加载器,跟template/js/style转换成js模块。
用途:js可以写es6、style样式可以scss或less、template可以加jade等
10.vue-router是什么?它有哪些组件?
vue用来写路由一个插件。router-link、router-view
11.Vue实现数据双向绑定的原理:Object.defineProperty()
采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各属性的setter和getter,在数据变动是发布消息给订阅者,触发相应的监听回调函数。
Vue 主要通过以下 4 个步骤来实现数据双向绑定的:
- 实现一个监听器 Observer:对数据对象进行遍历,包括子属性对象的属性,利用 Object.defineProperty() 对属性都加上 setter 和 getter。这样的话,给这个对象的某个值赋值,就会触发 setter,那么就能监听到了数据变化。
- 实现一个解析器 Compile:解析 Vue 模板指令,将模板中的变量都替换成数据,然后初始化渲染页面视图,并将每个指令对应的节点绑定更新函数,添加监听数据的订阅者,一旦数据有变动,收到通知,调用更新函数进行数据更新。
- 实现一个订阅者 Watcher:Watcher 订阅者是 Observer 和 Compile 之间通信的桥梁 ,主要的任务是订阅 Observer 中的属性值变化的消息,当收到属性值变化的消息时,触发解析器 Compile 中对应的更新函数。
- 实现一个订阅器 Dep:订阅器采用 发布-订阅 设计模式,用来收集订阅者 Watcher,对监听器 Observer 和 订阅者 Watcher 进行统一管理。
12.vue-cli如何新增自定义指令
使用选项directive
<div id="app">
<input type="text" v-focus>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var app = new Vue({
el: '#app',
data: {
},
// 创建指令(可以多个)
directives: {
// 指令名称
focus: {
// 指令的定义
inserted: function (el) {
el.focus()
}
}
}
})
</script>
上面的自定义指令是局部的,也可以定义全局的自定义指令
// 注册一个全局自定义指令 `v-focus`
Vue.directive('focus', {
// 当被绑定的元素插入到 DOM 中时……
inserted: function (el) {
// 聚焦元素
el.focus()
}
})
这个自定义指令的意思是输入框自动聚焦,当页面加载完成,输入框会自动获取焦点。
13.对keep-alive 的了解?
- 包裹在该标签内的动态组件失活的时候将会被缓存,而不是被销毁。当一些组件被频繁切换的时候,你有时会想保持这些组件的状态,以避免反复渲染造成的性能问题。
- 被该标签包裹的组件被激活时,将会触发actived生命周期函数;被停用时触发deactived生命周期函数。
- 该标签上有三个属性:
- include : 指定组件可以被缓存
- exclude : 指定组件会被销毁
- max : 指定最多可以缓存几个组件(会把最早的那个切换)
<template>
<div>
<button @click="changeCom('com-A')">A组件</button>
<button @click="changeCom('com-B')">B组件</button>
<button @click="changeCom('com-C')">C组件</button>
<keep-alive include="com-A,com-B,com-C" exclude="com-C" :max="1">
<component v-bind:is="coms"></component>
</keep-alive>
</div>
</template>
<script>
import comA from '@/components/comA'
import comB from '@/components/comB'
import comC from '@/components/comC'
export default {
components: {
'com-A': comA,
'com-B': comB,
'com-C': comC
},
data(){
return {
coms: 'com-A'
}
},
methods:{
changeCom(name){
this.coms = name
}
}
}
</script>
14.vue.js的两个核心是什么?
数据驱动、组件系统
15.如何让CSS只在当前组件中起作用?
将当前组件的< style >修改为< style scoped>
scoped:作用域
16.vue的优缺点
优点:
1、具有桌面应用的即时性、网站的可移植性和可访问性。
2、用户体验好、快,内容的改变不需要重新加载整个页面。
3、基于上面一点,SPA相对对服务器压力小。
4、良好的前后端分离。SPA和RESTful架构一起使用,后端不再负责模板渲染、输出页面工作,web前端和各种移动终端地位对等,后端API通用化。
5、同一套后端程序代码,不用修改就可以用于Web界面、手机、平板等多种客户端;
缺点:
1、不利于SEO。(如果你看中SEO,那就不应该在页面上使用JavaScript,你应该使用网站而不是Web应用)
2、初次加载耗时相对增多。
3、导航不可用,如果一定要导航需要自行实现前进、后退。
17.在Vue中使用插件的步骤
- 安装
- 全局引入
- 全局使用
注意,如果有样式的话样式也一定要记得引入进来
举个例子
ElementUI 的使用
npm i element-ui -S
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI);
Vant UI 的使用
npm i vant -S
import Vant from 'vant';
import 'vant/lib/index.css';
Vue.use(Vant);
axios 的使用
npm i axios -S
import axios from 'axios'
Vue.prototype.$axios = axios;
18. vue watch的高级用法–监听对象的属性变化
1.监听对象需要深度监听 ,如下代码可以监听整个msg对象的变化
watch: {
msg: {
handler(newValue, oldValue) {
console.log(newValue)
},
deep: true
}
}
2.监听对象里面某个属性的变化,通过computed做中间层实现
computed: {
channel() {
return this.msg.channel
}
},
watch:{
channel(newValue, oldValue) {
console.log('new: %s, old: %s', newval, oldVal)
//这里面可以执行一旦监听的值发生变化你想做的操作
}
}
19.请说出vue.cli项目中src目录每个文件夹和文件的用法?
- assets :存放图片等静态资源。
- components : 定义公共组件
- router :路由
- store : 全局静态资源管理
- view : 定义视图组件
- APP.vue : 根组件
- main.js : 入口文件
20.vue常见修饰符
- .self : 只有当触发事件的元素是当前自身元素时才触发处理函数
- .once :事件只触发一次
- .capture : 改变触发事件的先后顺序,优先捕获事件,优先执行被捕获的事件。
- .prevent : 取消默认行为
- .stop : 阻止事件冒泡
- 还有按键修饰符 : .enter(按下回车触发事件),.space(按下空格触发事件),.right,.left等。
21.MVVM和MVC的区别?
MVVM即Model-View-ViewModel的简写。即模型-视图-视图模型。模型(Model)指的是后端传递的数据。视图(View)指的是所看到的页面。视图模型(ViewModel)是mvvm模式的核心,它是连接view和model的桥梁。它有两个方向:一是将模型(Model)转化成视图(View),即将后端传递的数据转化成所看到的页面。实现的方式是:数据绑定。二是将视图(View)转化成模型(Model),即将所看到的页面转化成后端的数据。实现的方式是:DOM 事件监听。这两个方向都实现的,我们称之为数据的双向绑定。
MVC是Model-View- Controller的简写。即模型-视图-控制器。M和V指的意思和MVVM中的M和V意思一样。C即Controller指的是页面业务逻辑。使用MVC的目的就是将M和V的代码分离。MVC是单向通信。也就是View跟Model,必须通过Controller来承上启下。MVC和MVVM的区别并不是VM完全取代了C,只是在MVC的基础上增加了一层VM,只不过是弱化了C的概念,ViewModel存在目的在于抽离Controller中展示的业务逻辑,而不是替代Controller,其它视图操作业务等还是应该放在Controller中实现。
使用MVC,当 Model 频繁发生变化,开发者需要主动更新到 View。MVVM会自动双向数据绑定更新,实现的是业务逻辑组件的重用,使开发更高效,结构更清晰,增加代码的复用性。
22.说一下vue封装组件中的slot作用
vue封装组件涉及三个东西:
一是事件(v-on,$emit),
二是传参通过props,
三是slot:slot作用主要是可以实现内容分发,组件标签内嵌套内容,可通过来定义占位的内容。分为具名的slot和匿名的slot。
在编写可复用组件的时候,时刻考虑组件是否可复用是有好处的。一次性组件跟其他组件紧密耦合没关系,但是可复用组件一定要定义一个清晰的公开接口。
Vue.js组件 API 来自 三部分:prop、事件、slot:
prop 允许外部环境传递数据给组件,在vue-cli工程中也可以使用vuex等传递数据。 事件允许组件触发外部环境的
action(就是行为,也就是方法的意思) slot 允许外部环境将内容插入到组件的视图结构内。
23.说一下你对单向数据流的理解
答:单向数据流主要是vue 组件间传递数据是单向的,即数据总是由父组件传递给子组件,子组件在其内部维护自己的数据,但它无权修改父组件传递给它的数据,当开发者尝试这样做的时候,vue 将会报错。这样做是为了组件间更好的维护。
在开发中可能有多个子组件依赖于父组件的某个数据,假如子组件可以修改父组件数据的话,一个子组件变化会引发所有依赖这个数据的子组件发生变化,所以 vue 不推荐子组件修改父组件的数据
24.说一下vue中methods,computed,watch的区别:
答:methods中都是封装好的函数,无论是否有变化只要触发就会执行
computed:是vue独有的特性计算属性,可以对data中的依赖项再重新计算,得到一个新值,应用到视图中,和methods本质区别是computed是可缓存的,也就是说computed中的依赖项没有变化,则computed中的值就不会重新计算,而methods中的函数是没有缓存的。Watch是监听data和计算属性中的新旧变化。
25.说一下vue和jquey的区别
答:jquery主要是玩dom操作的“神器“,强大的选择器,封装了好多好用的dom操作方法和如何获取ajax方法 例如:$.ajax()非常好用
vue:主要用于数据驱动和组件化,很少操作dom,当然vue可能通过ref来选择一个dom或组件
25.axios如何发同步请求?
- axios基本用法
axios请求后得到的是promise对象,axios中的数据放在res.data中,需要.then一下,才能得到。
axios.post('getsomething').then(
res => {
// 进行一些操作
}
)
- async/await
async/await 是一种建立在Promise之上的编写异步或非阻塞代码的新方法。async 是异步的意思,而 await 是 async wait的简写,即异步等待。所以从语义上就很好理解 async 用于声明一个 函数 是异步的,而await 用于等待一个异步方法执行完成。
那么想要同步使用数据的话,就可以使用 async+await 。通过await可以直接取到promit实例对象的结果,而不用再.then来获取,这样一来,就相当于将异步的请求变成了同步任务;
async函数返回一个Promise实例对象
await后面可以直接跟一个 Promise实例对象
axios.defaults.baseURL = 'http://localhost:3000';
async function queryDate() {
// await的作用就是将异步函数变成同步操作
var ret = await axios.get('/adata')
console.log(ret.data);
}
queryDate();
26.axios如何封装?
27.vue.extend的理解?
vue基础构造器,创建一个“子类”,参数是一个包含组件选项的对象
<div id="mount-point"></div>
// 创建构造器
var Profile = Vue.extend({
template: '<p>{{firstName}} {{lastName}} aka {{alias}}</p>',
data: function () {
return {
firstName: 'Walter',
lastName: 'White',
alias: 'Heisenberg'
}
}
})
// 创建 Profile 实例,并挂载到一个元素上。
new Profile().$mount('#mount-point')
结果如下:
<p>Walter White aka Heisenberg</p>
28.前端路由和后端路由的区别
路由:
路由是根据不同的 url 地址展示不同的内容或页面
前端路由:
前端路由很重要的一点是页面不刷新,前端路由就是把不同路由对应不同的内容或页面的任务交给前端来做,每跳转到不同的URL都是使用前端的锚点路由. 随着(SPA)单页应用的不断普及,前后端开发分离,目前项目基本都使用前端路由,在项目使用期间页面不会重新加载 。hash有一个特点:http请求中不会包含hash相关的内容;所以,单页面程序中的页面跳转主要用hash实现;
后端路由:
通过用户请求的url导航到具体的html页面;每跳转到不同的URL,都是重新访问服务端,然后服务端返回页面,页面也可以是服务端获取数据,然后和模板组合,返回HTML,也可以是直接返回模板HTML,然后由前端js再去请求数据,使用前端模板和数据进行组合,生成想要的HTML
对比:
1.从性能和用户体验的层面来比较的话,后端路由每次访问一个新页面的时候都要向服务器发送请求,然后服务器再响应请求,这个过程肯定会有延迟。而前端路由在访问一个新页面的时候仅仅是变换了一下路径而已,没有了网络延迟,对于用户体验来说会有相当大的提升。
2.在某些场合中,用ajax请求,可以让页面无刷新,页面变了但Url没有变化,用户就不能复制到想要的地址,用前端路由做单页面网页就很好的解决了这个问题。但是前端路由使用浏览器的前进,后退键的时候会重新发送请求,没有合理地利用缓存。
29.前端渲染和后端渲染的优缺点?
前端渲染:
定义:
指的是后端返回JSON数据,前端利用预先写的html模板,循环读取JSON数据,拼接字符串,并插入页面。
好处:
1、前后端分离。前端专注于前端UI,后端专注于api开发,且前端有更多的选择性,而不需要遵循后端特定的模板。
2、体验更好。比如,我们将网站做成SPA或者部分内容做成SPA,这样,尤其是移动端,可以使体验更接近于原生app。
坏处:
1、前端响应较慢。如果是客户端渲染,前端还要进行拼接字符串的过程,需要耗费额外的时间,不如服务器端渲染速度快。
2、不利于SEO。目前比如百度、谷歌的爬虫对于SPA都是不认的,只是记录了一个页面,所以SEO很差。因为服务器端可能没有保存完整的html,而是前端通过js进行dom的拼接,那么爬虫无法爬取信息。 除非搜索引擎的seo可以增加对于JavaScript的爬取能力,这才能保证seo。
服务端渲染:
定义:
前端请求,后端用后台模板引擎直接生成html,前端接受到数据之后,直接插入页面。
好处:
1、前端耗时少,即减少了首屏时间
2、有利于SEO。因为在后端有完整的html页面,所以爬虫更容易爬取获得信息,更有利于seo。
3、无需占用客户端资源。即解析模板的工作完全交由后端来做,客户端只要解析标准的html页面即可,这样对于客户端的资源占用更少,尤其是移动端,也可以更省电。
4、后端生成静态化文件。即生成缓存片段,这样就可以减少数据库查询浪费的时间了,且对于数据变化不大的页面非常高效
坏处:
1、不利于前后端分离,开发效率低 2、占用服务器端资源
30.对vue.js中template编译的理解
个人简单理解,就是在mounted的生命周期开始渲染页面,当没有render函数的时候,会将template运行编译得到render。而render function在运行编译后会返回VNode(VNode是vue的虚拟DOM节点)节点,共页面渲染。