1.说一下什么是mvvm模式
Model代表数据模型,数据和业务逻辑都在Model层中定义;View代表UI视图,负责数据的展示;ViewModel负责监听Model中数据的改变并且控制视图的更新,处理用户交互操作;
View 的变化会自动更新到 ViewModel , ViewModel 的变化也会自动同步到 View 上显示。这种自动同步是因为 ViewModel 中的属性实现了 Observer ,当属性变更时都能触发对应的操作。
- v-text v-html 区别?
1.v-text:会把标签转义输出,不解析HTML标签。即原模原样输出,h1标签没效果
2.v-html:会直接输出结果,解析HTML标签。即h1标签会出效果
- new Vue() 中的Vue是什么?其内部的this指向谁?
Vue 是一个构造函数,其内部的this指向实例化出来的对象,因此我们可以通过this调用data中的变量和 methods
中的方法。
l
- Vue 常见的指令有哪些?
v-cloak 防止页面加载闪烁
v-html 可以把html的内容填充到标签中去
v-text 指令用于将数据填充到标签中,作用于插值表达式类似
v-pre 显示指令中原始信息,静态的内容不需要编译,可以加快渲染
v-once 执行一次性的插值【当数据改变时,插值处的内容不会继续更新】
v-on 用来进行事件的绑定
v-if 判断 是否创建或销毁dom元素
v-else 给 v-if 添加一个 "else" 块,必须跟在 v-if之后
v-show 是否显示/隐藏dom元素
v-for 循环
v-model 数据双向绑定
v-bind 动态绑定属性
- v-cloak指令的作用?使用步骤?
防止页面加载时出现闪烁问题。
- 在出现闪烁的标签中添加 v-cloak 指令
- 利用属性选择器,选择有v-cloak的标签并设置样式,如:[v-cloak]{ display:none}
- v-if和v-show的区别?以及使用场景
v-if和v-show都是控制元素的显示与隐藏,
不过v-if控制元素的显示和隐藏的时候会创建或删除对应的dom元素,当每一个显示的时候,都会重新创建dom和渲染.
而v-show则是通过css的display来控制元素的显示与隐藏.
v-if比较耗费性能,所以我们涉及到频繁的显示/隐藏操作建议使用v-show,如果不是频繁操作的话,我们可以v-if
- 什么是双向数据绑定?
当数据发生变化的时候,视图也就发生变化
当视图发生变化的时候,数据也会跟着同步变化
- Vue2中双向数据绑定原理?
主要采用:数据劫持结合“发布-订阅”模式的方式,通过Object.defineProperty()的 set 和 get,在数据变动时发布消息给订阅者触发监听。
- Vue2 v-model 为什么称为语法糖?
举个例子:
<input v-model="str" />
// 等同于
<input :value="str" @input="str = $event.target.value" />
通过实例可以看出,明显上面的写法更简单,所以我们称v-model为语法糖。
- 列举出三个常见的表单修饰符?并说出作用。
.lazy 当输入框失去焦点,再去同步输入框中的数据
.number自动将用户的输入值转为数值类型
.trim自动过滤用户输入的首尾空白字符
- 说一下v-bind的作用?
v-bind 主要用于属性绑定,比方class属性,style属性,value属性等等,只要是属性,就可以用v-bind指令进行绑定。
其简写形式是” : ”
- 动态绑定的用法
对象方法 v-bind:class="{'orange': true}"
数组方法v-bind:class="[class1, class2]"
行内 v-bind:style="{color: color, fontSize: fontSize+'px' }"
- 说一些v-for能循环的数据类型有哪些,语法解构是什么?
v-for 可以循环字符串,数字,对象,数组。
语法解构:<标签 v-for="(每项数据,索引)in 要循环的数据" :key="唯一标识">{{每项数据}}</标签 >
- 说一下key值的作用?
避免dom元素重复渲染. 我们一般在设置key的时候首先尽量会设置为id,或者index下标
1.在v-if中使用key
首先我们先看在vue中出现的一种情况,我们在vue中如果使用v-if进行切换时,此时Vue为了更加高效的渲染,此时会进行前后比较,如果切换前后都存在的元素,则直接复用
1.在v-for中使用key
对于用v-for渲染的列表数据来说,v-for默认使用就地复用的策略,列表数据修改的时候,他会根据key值去判断某一个值是否修改,如果修改则重新渲染该项,否则复用之前的元素。在v-for中我们的key一般为id,也就是唯一的值,但是一般不要使用index作为key。
为什么不建议用index作为key?
使用index 作为 key和没写基本上没区别,因为不管数组的顺序怎么颠倒,index 都是 0, 1, 2...这样排列,导致 Vue 会复用错误的旧子节点,做很多额外的工作。
- 常见的事件修饰符有哪些?其作用是什么?
.stop 阻止事件冒泡
.once 只渲染一次
.self 事件只作用在元素本身
.capture 组件之间捕获
.prevent 阻止元素的默认行为
.native 事件穿透,让我们可以在自定义组件上定义事件和方法
- 计算属性有哪些优点?
.使用计算属性可以让模板更加的简洁
.计算属性是基于它们的响应式依赖进行缓存的
.computed比较适合对多个变量或者对象进行处理后返回一个结果值,也就是说多个变量中的某一个值发生了变化则我们监控的这个值也就会发生变化
- Methods、 computed 、watch的区别?
1.methods是用来定义方法的区域,computed是计算属性;watch是监听,监听data中的数据变化。
2.methods定义的方法需要调用才能触发. 不具备缓存;computed支持缓存,只有当其依赖的属性的值发生变化时,才会重新计算,否则使用缓存中的属性值;watch不支持缓存,当对应属性发生变化的时候,响应执行。
3.computed不支持异步,有异步操作时无法监听数据变化;watch支持异步操作。computed第一次加载时就监听;watch默认第一次加载时不监听(immediate 组件创建时刻执行与否, immediate: true,第一次加载时监听(默认为false),deep 深度监听 不推荐使用(非常的消耗性能))
4.computed中的函数必须调用return;watch不是。
使用场景:
-methods:事件处理函数
- computed:一个属性受到多个属性影响,如:购物车商品结算。
- watch:一个数据影响多条数据,如:搜索数据。
- 数据变化响应,执行异步操作,或高性能消耗的操作,watch为最佳选择
- 写出watch监听对象,并且开启第一次监听的代码?
watch: {
Obj: {
handler(val {
console.log('obj.a changed');
},
immediate: true, // 开启第一次监听
deep:true // 开启深度监听
}
}
- 什么是过滤器?怎么定义全局过滤器和局部过滤器?
所谓的vue过滤器就是将数据进行二次处理,得到我们想要的结果数据
vue的过滤器分为两种,第一种是全局过滤器,通过Vue.filter来进行定义,第二种是局部过滤器,需要定义在组件内部。项目中我们通过过滤器将后台返回的状态0 和1 转化为支付或者未支付
- Vue2自定义指令有哪些参数?
el: 指令所绑定的元素,可以用来直接操作DOM。
binding: 一个对象,包含指令的很多信息。
vnode: Vue编译生成的虚拟节点。
- Vue2自定义指令有哪些钩子函数?
(1)bind:只调用一次,指令第一次绑定到元素时调用
(2)inserted:被绑定元素插入父节点时调用
(3)update:所在组件的虚拟节点更新时调用
(4)componentUpdated:所在组件的虚拟节点及子虚拟节点全部更新后调用
(5)unbind:只调用一次,指令与元素解绑时调用
- 解释一下vue 中组件的概念?
封装可重用的代码,通常一个组件就是一个功能体,便于在多个地方都能够调用这个功能体
特点:1.具有独立功能的代码片段
2.方便维护,便于团队作战
- Vue 中注册组件,应该注意的事项有哪些?
1.data必须是函数,必须有返回值:return {}
2.组件模板必须是单个根元素
3.至少包含template
4.组件模板的内容可以是模板字符串
- v-for与v-if的优先级那个高?如果同时使用v-for和v-if怎么解决?
v-for的优先级高. 因为v-for的时候我们才开始渲染dom元素,这个v-if还无法进行判断.v-for和v-if不能同时使用,我们可以通过标签,比如div或者template标签来进行包裹,把v-if写到包裹的标签上面
- Vue 脚手架安装创建项目步骤?
搭建node环境根据操作系统选择相应安装包
检验是否安装成功,命令行中直接输入node -v,返回版本号
npm install @vue/cli -g
检验是否安装成功,命令行中直接输入vue -V,返回版本号
vue create 项目名称
- Vue 文件的组成部分?
template 结构(html代码)
script行为
style样式
- Vue 常用的8个生命周期函数有哪些?
创建阶段的四个:
beforeCreate:实例创建之前。 在此生命周期函数执行的时候,data 和 methods 中的数据都还没有初始化。
created:实例创建之后。一般在这里发送http请求
beforeMount:组件挂载之前。
mounted:组件挂载之后。
运行阶段的两个:
beforeUpdate:数据改变,视图更新之前。
updated:试图更新之后。
销毁阶段的两个:
beforeDestroy:实例销毁之前。
destroyed:实例销毁之后。
- Vue 中父子组件创建执行顺序是什么样的?
> 父 beforeCreate -> 父 created -> 父 beforeMount -> 子 beforeCreate -> 子 created -> 子 beforeMount -> 子 mounted -> 父mounted
- Vue 中父子组件销毁顺序是什么样的?
父 beforeUpdate -> 子 beforeUpdate -> 子 updated -> 父 updated
父beforeDestroy→ 子beforeDestroy→ 子destroyed→ 父destroyed
- 说一下你对 NextTick 的理解?
$nextTick也叫做异步更新队列方法,而$nextTick方法的主要作用就是等待dom元素加载完毕之后才会执行的回调函数,我们经常会在$nextTick方法里面获取dom元素
比如:beforeCreated获取DOM元素、获取最新的滚动列表
- 父传递子如何传递
在子组件的标签上定义属性 子组件通过props来进行接受,可以通过数组的方式进行接受,也可以通过对象的方式来进行接收,如果父组件没有传递属性,子组件可以default来设置默认值
- 子传递父如何传递
子组件通过this.$emit("自定义的事件",要传给父组件的数据), 父组件通过子组件的标签监听自定义的事件,通过方法来接收传递的数据
- 兄弟组件如何通信
通过中央事件总线,我们也称之为eventBus,
1.我们需要创建一个空的js文件,导出这个空的vue实例
2.传数据的时候使用this.$bus.$emit
3.接数据的时候是在created中使用this.$bus.$on接收 第一个参数是事件名称 第二个参数是一个回调函数包含了要接受的数据,
- Props验证类型都有哪些
number、boolean、string、object、array、function、date、symbol
- Vue-Routervue路由有几种模式?有什么区别?原理是什么?
vue的路由模式一共有两种,分别是哈希和history.
hash 就是指 url 尾巴后的#号以及后面的字符,history没有带#,外观上比hash 模式好看些.
hash模式不会重新加载页面,主要原理就是onhashchange()事件;而history模式,如果前端的url和后端发起请求的url不一致的话,会报404错误,所以使用history模块的话我们需要和后端进行配合.
history api可以分为两大部分,切换历史状态和修改历史状态:
修改历史状态:包括了 HTML5 中新增的 pushState() 和 replaceState() 方法,
切换历史状态: 包括forward()、back()、go()三个方法
- vue中$router和$route区别
$router是VueRouter的一个实例对象,用于控制路由跳转等;
$route是一个跳转的路由对象,可以获取当前的路由参数等
- Params和query的区别
(1) query可以使用name和path,而params只能使用name
(2) 使用params传参刷新后不会保存,而query传参刷新后可以保存
(3) Params在地址栏中不会显示,query会显示
(4) Params可以和动态路由一起使用,query不可以
- 为什么vue中data必须是⼀个函数?
如果data是一个函数的话,这样每复用一次组件,就会返回一份新的data,类似于给每个组件实例创建一个私有的数据空间,让各个组件实例维护各自的数据。而单纯的写成对象形式,就使得所有组件实例共用了一份data,就会造成一个变了全都会变的结果。所以说vue组件的data必须是函数。这都是因为js的特性带来的,跟vue本身设计无关。
- 怎么定义vue-router的动态路由?怎么获取传过来的值
使用动态路径参数,以冒号开头,如下:
{
path: '/details/:id'
name: 'Details'
components: Details
}
访问details目录下的所有文件,如details/a,details/b等,都会映射到Details组件上。
当匹配到/details下的路由时,参数值会被设置到this.$route.params下,所以通过这个属性可以获取动态参数
this.$route.params.id
- 说⼀下你对slot插槽的理解
首先呢,所谓的插槽就是一个占位符,将自定义组件的内容展示出来.我们知道自定义的组件里面如果写内容的话,页面是不会显示出来的,如果我们想让自定义组件里面的内容显示出来,我们就需要使用slot的插槽.
●默认插槽:又名匿名插槽,当slot没有指定name属性值的时候一个默认显示插槽,一个组件内只有一个匿名插槽。
●具名插槽:带有具体名字的插槽,也就是带有name属性的slot,一个组件可以出现多个具名插槽。
●作用域插槽:默认插槽、具名插槽的一个变体,不同点是可以将子组件内部的数据传递给父组件,让父组件根据子组件的传递过来的数据决定如何渲染该插槽。
1.js的数据类型以及区别
JavaScript共有八种数据类型
基本数据类型: Undefined、Null、Boolean、Number、String
引用数据类型:object,function,array
2.JS判断数据类型的方法
typeof 只能检查除null外的基本数据类型和function,其他引用类型和null会返回object
instanceof 不能检查基本数据类型
construct 能检查除null和undefined外的类型
Object.prototype.toString.call 能检查所有类型
3.什么是原型对象,说说对它的理解
构造函数的内部的 prototype 属性指向的对象,就是构造函数的原型对象。
原型对象包含了可以由该构造函数的所有实例共享的属性和方法。当使用构造函数新建一个实例对象后,在这个对象的内部将包含一个指针,这个指针指向构造函数的原型对象,在 ES5 中这个指针被称为对象的原型。
4.数组常用的操作方法(5个以上)
join() 将一个数组转成字符串。返回一个字符串
reverse() 将数组中各元素颠倒顺序
shift()删除数组中第一个元素,返回删除的那个值,并将长度减 1
pop()删除数组中最后一个元素,返回删除的那个值,并将长度减 1
unshift() 往数组前面添加一个或多个数组元素,长度会改变
push() 往数组结尾添加一个或多个数组元素,长度会改变
concat() 连接数组
slice() 切割数组,返回数组的一部分
splice()插入、删除或替换数组的元素
forEach()遍历所有元素
every()判断所有元素是否都符合条件
sort()对数组元素进行排序
map()对元素重新组装,生成新数组
filter()过滤符合条件的元素
find() 查找 返回满足提供的测试函数的第一个元素的值。否则返回 undefined。
some() 判断是否有一个满足条件 ,返回布尔值0
能影响原来数组的方法 splice() push() pop() shift() unshift() reverse() sort() ...
不会影响原来数组的方法
concat() slice() forEach() join() reduce() map() filter() slice() findIndex() ...
无返回值的:
forEach()
返回值为新数组的:
splice()、concat()、slice()、sort()、reverse()、map()、filter()
5.什么是递归函数
如果一个函数在内部调用自身本身,这个函数就是递归函数
其核心思想是把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解
一般来说,递归需要有边界条件、递归前进阶段和递归返回阶段。当边界条件不满足时,递归前进;当边界条件满足时,递归返回
优点:结构清晰、可读性强
缺点:效率低、调用栈可能会溢出,其实每一次函数调用会在内存栈中分配空间,而每个进程的栈的容量是有限的,当调用的层次太多时,就会超出栈的容量,从而导致栈溢出。
6.cookie和localStorage、sessionStorage的区别
cookie:一般不超过4K,一般由服务器生成,可以设置失效时间;若没有设置时间,关闭浏览器cookie失效,若设置了时间,cookie就会存放在硬盘里,过期才失效
localStorage:5M或者更大,永久有效,窗口或者浏览器关闭也会一直保存,除非手动永久清除,因此用作持久数据
sessionStorage:5M或者更大,仅在当前浏览器窗口关闭之前有效,关闭页面或者浏览器会被清除
7.vue中data发⽣变化,视图不更新如何解决
因为Vue实例中的数据是响应式的,而我们新增的属性并不是响应式的,所以有时无法实时的更新到视图上。一般是通过this.$set方法解决. this.$set方法一共有三个参数,分别是目前对象,新增属性,新增的值
8.怎样理解 Vue 的单向数据流
数据一般从父组件传到子组件,子组件没有权利直接修改父组件传来的数据,即子组件从 props 中直接获取的数据,只能请求父组件修改数据再传给子组件。
9.vue路由守卫?
所谓的路由守卫就是当我们进行页面跳转的时候会触发的钩子函数。在项目中我们经常使用全局前置路由守卫实现页面的鉴权。
全局路由守卫:beforeEach 前置守卫,beforeResolve 解析守卫,afterEach 后置守卫 ,
组件内路由守卫:beforeRouteEnter 进入之前,beforeRouteUpdate 更新之前,beforeRouteLeave 离开之前,
路由独享守卫:beforEnter 进入之前
这些回调函数里面会有三个参数,分别是`to,from,next`,分别对应的是要进入的路由、离开之前的路由,以及进入写一个路由。
10.简述Object.defineProperty
Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性。
Object.defineproperty方法需要传递3个参数:需要定义属性的当前对象、当前需要定义的属性名、描述符 一般是一个对象
Vue2 通过 Object.defineProperty() 来劫持数据变化,实现数据的双向绑定。
11.计算属性的get和set方法
set:设置值时触发。
get:获取值时触发。
12.简述单页面应用和多页面应用
单页面:只有一个html页面,跳转方式是组件之间的切换
优点:跳转流畅、组件化开发、组件可复用、开发便捷
缺点:首屏加载过慢
多页面:有多个页面,跳转方式是页面之间的跳转
优点:首屏加载块
缺点:跳转速度慢
13.简述keep-alive
keep-alive是Vue的内置组件,能在组件切换过程中将状态保留在内存中,防止重复渲染DOM。
包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们,它自身不会渲染一个DOM元素,也不会出现在父组件中
使用方式:包裹在需要缓存的组件外
14.简述vue的内置组件
component 动态组件
transition 动画
transition-group 动画
keep-alive 缓存
slot 插槽
15.列表跳详情页面的思路 (跳转/传参数/接受)
(1)在列表页中给某个元素一个点击事件,并传递一个值,在methods的方法中写跳转(this.$router.push({name:”xiang”,params:{zhi:值}}))
(2)在详情页 data获取传递过来的值(this.$route.params.值)
16.虚拟 DOM 原理
虚拟dom 是根据模板生成一个js对象,根据这个js对象再去生成真实的dom,对复杂的文档DOM结构,提供一种方便的工具,进行最小化DOM操作(使用createElement方法)
17. Vue2.0 响应式数据的原理(同理论8)
主要采用:数据劫持结合“发布-订阅”模式的方式,通过Object.defineProperty()的 set 和 get,在数据变动时发布消息给订阅者触发监听。
18.vue中data发生变化,视图不更新如何解决(同面试7)?
因为Vue实例中的数据是响应式的,而我们新增的属性并不是响应式的,所以有时无法实时的更新到视图上。一般是通过this.$set方法解决. this.$set方法一共有三个参数,分别是目前对象,新增属性,新增的值
19.请说出 vue.cli 项目中 src 目录每个文件夹和文件的用法
src
assets 静态资源文件 图片、图标、样式等
components 公共组件
router 路由配置
store vuex配置
views 视图,路由对应的组件
App.vue 所有vue文件的公共
main.js 程序主入口,全局配置
Vue.config.js 项目配置,跨域、分包等
- Vue.js 的特点
Vue.js 是一个优秀的前端界面开发 JavaScript 库。
1) 轻量级的框架
Vue.js 能够自动追踪依赖的模板表达式和计算属性,提供 MVVM 数据绑定和一个可组合的组件系统,具有简单、灵活的 API,使读者更加容易理解,能够更快上手。
2) 双向数据绑定
声明式渲染是数据双向绑定的主要体现,同样也是 Vue.js 的核心,它允许采用简洁的模板语法将数据声明式渲染整合进 DOM。
3) 指令
Vue.js 与页面进行交互,主要就是通过内置指令来完成的,指令的作用是当其表达式的值改变时相应地将某些行为应用到 DOM 上。
4) 组件化
组件(Component)是 Vue.js 最强大的功能之一。在 Vue 中,父子组件通过 props 传递通信,从父向子单向传递。子组件与父组件通信,通过触发事件通知父组件改变数据。这样就形成了一个基本的父子通信模式。
5) 客户端路由
Vue-router 是 Vue.js 官方的路由插件,与 Vue.js 深度集成,用于构建单页面应用。Vue 单页面应用是基于路由和组件的,路由用于设定访问路径,并将路径和组件映射起来,传统的页面是通过超链接实现页面的切换和跳转的。
6) 状态管理
状态管理实际就是一个单向的数据流,State 驱动 View 的渲染,而用户对 View 进行操作产生 Action,使 State 产生变化,从而使 View 重新渲染,形成一个单独的组件。