1. 解释单向数据流和双向数据绑定
单向数据流: 数据流是单向的。数据流动方向可以跟踪,流动单一,追查问题的时候可以更快捷。缺点就是写起来不太方便。要使UI发生变更就必须创建各种 action 来维护对应的 state。
双向数据绑定:数据之间是相通的,将数据变更的操作隐藏在框架内部。优点是在表单交互较多的场景下,会简化大量与业务无关的代码。缺点就是无法追踪局部状态的变化,增加了出错时 debug 的难度。
2.Vue 如何去除url中的 #
vue-router 默认使用 hash 模式,所以在路由加载的时候,项目中的 url 会自带 #。如果不想使用 #, 可以使用 vue-router 的另一种模式 history
new Router({
mode: 'history',
routes: [ ]
})
需要注意的是,当我们启用 history 模式的时候,由于我们的项目是一个单页面应用,所以在路由跳转的时候,就会出现访问不到静态资源而出现 404 的情况,这时候就需要服务端增加一个覆盖所有情况的候选资源:如果 URL 匹配不到任何静态资源,则应该返回同一个 index.html 页面
3.对 MVC、MVVM的理解
MVC
: 所有通信都是单向的.
View 传送指令到 Controller
Controller 完成业务逻辑后,要求 Model 改变状态
Model 将新的数据发送到 View,用户得到反馈
MVVM
:
各部分之间的通信,都是双向的
采用双向绑定:View 的变动,自动反映在 ViewModel,反之亦然
4. v-if 和 v-show 区别
答:v-if 按照条件决定是否渲染,如果为false,页面不会有该html标签生成。
v-show,html元素一定存在,是css中,display的block或none;
5. $route
和$router
的区别
$router
:路由实例,包括了路由的跳转方法,钩子函数等。想要导航到不同 URL,使用 $router.push
方法
$route
: 路由信息对象,包括 name、path、hash、query、params、matched等
6, NextTick 是做什么的
$nextTick
是在下次 DOM 更新循环结束之后执行延迟回调,在修改数据之后使用 $nextTick,则可以在回调中获取更新后的 DOM
7. Vue 组件 data 为什么必须是函数
因为js本身的特性带来的,如果 data 是一个对象,那么由于对象本身属于引用类型,当我们修改其中的一个属性时,会影响到所有Vue实例的数据。如果将 data 作为一个函数返回一个对象,那么每一个实例的 data 属性都是独立的,不会相互影响了
8, 计算属性computed 和事件 methods 有什么区别
相同点
: 我们可以将同一函数定义为一个 method 或者一个计算属性。对于最终的结果,两种方式是相同的
不同点
: computed: 计算属性是基于它们的依赖进行缓存的,只有在它的相关依赖发生改变时才会重新求值;对于 method ,只要发生重新渲染,method 调用总会执行该函数
9. 对比 jQuery ,Vue 有什么不同
jQuery 专注视图层,通过操作 DOM 去实现页面的一些逻辑渲染;
Vue 专注于数据层,通过数据的双向绑定,最终表现在 DOM 层面,减少了 DOM 操作
Vue 使用了组件化思想,使得项目子集职责清晰,提高了开发效率,方便重复利用,便于协同开发
10. Vue 中 key 的作用
key的作用主要是为了高效的更新虚拟DOM。
用 v-for 正在更新已渲染过的元素列表时,如果数据项的顺序被改变,它会基于 key 的变化重新排列元素顺序,并且会移除 key 不存在的元素。有相同父元素的子元素必须有独特的 key。重复的 key 会造成渲染错误。它默认用“就地复用”策略。
11. Vue 的核心是什么
数据驱动 组件系统
12. vue 等单页面应用的优缺点
优点:
良好的交互体验
良好的前后端工作分离模式
减轻服务器压力
缺点:
SEO难度较高
前进、后退管理
初次加载耗时多
Q: css只在当前组件起作用
A:在style标签中写入scoped即可 例如:<style scoped></style>
Q:vue几种常用的指令
A:v-for 、 v-if 、v-bind、v-on、v-show、v-else
Q:v-on 可以绑定多个方法吗?
A: 可以
Q:Vue-cli2.0和Vue-cli3.0的区别?
A: vue-cli3.0与2.0版本相比,文件目录少了很多 eg:build、config。
vue-cli 2.* 之前关于端口号的配置、打包之后的路径的配置、图片的配置等,vue-cli 3.0 在项目的根目录下新建一个 vue.config.js 文件,进行直接配置。
3.0能直接运行单个组件(待更新)
3.0有一个可视化管理界面, 可用于创建项目,安装插件,快速搭建适合个性化项目的脚手架,项目管理,项目打包等;
Q:vue常用的修饰符?
A:
prevent: 提交事件不再重载页面;
.stop: 阻止单击事件冒泡;
.self: 当事件发生在该元素本身而不是子元素的时候会触发;
.capture: 事件侦听,事件发生的时候会调用
Q:什么是vue的计算属性?
A:在模板中放入太多的逻辑会让模板过重且难以维护,在需要对数据进行复杂处理,且可能多次使用的情况下,尽量采取计算属性的方式。
好处:①使得数据处理结构清晰;
②依赖于数据,数据更新,处理结果自动更新;
③计算属性内部this指向vm实例;
④在template调用时,直接写计算属性名即可;
⑤常用的是getter方法,获取数据,也可以使用set方法改变数据;
⑥相较于methods,不管依赖的数据变不变,methods都会重新计算,但是依赖数据不变的时候computed从缓存中获取,不会重新计算。
Q:vue等单页面应用及其优缺点
A:
优点:Vue 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件,核心是一个响应的数据绑定系统。MVVM、数据驱动、组件化、轻量、简洁、高效、快速、模块友好。
缺点:不支持低版本的浏览器,最低只支持到IE9;不利于SEO的优化(如果要支持SEO,建议通过服务端来进行渲染组件);第一次加载首页耗时相对长一些;不可以使用浏览器的导航按钮需要自行实现前进、后退。
Q:怎么定义 vue-router 的动态路由? 怎么获取传过来的值
A: 在 router 目录下的 index.js 文件中,对 path 属性加上 /:id,使用 router 对象的 params.id 获取。
Q:vue路由的钩子函数
A:首页可以控制导航跳转,beforeEach,afterEach等,一般用于页面title的修改。一些需要登录才能调整页面的重定向功能。
beforeEach主要有3个参数to,from,next:
to:route即将进入的目标路由对象,
from:route当前导航正要离开的路由
next:function一定要调用该方法resolve这个钩子。执行效果依赖next方法的调用参数。可以控制网页的跳转。
Q:Vue中如何监控某个属性值的变化?
A:比如现在需要监控data中,obj.a 的变化。Vue中监控对象属性的变化你可以这样:
watch: {
'obj.a': {
handler (newName, oldName) {
console.log('obj.a changed')
}
}
}
deep属性表示深层遍历,会监控obj的所有属性变化.
另外,也可以利用计算属性的特性来实现,当依赖改变时,便会重新计算一个新值。
computed: {
a1 () {
return this.obj.a
}
}
Q:Vue中给data中的对象属性添加一个新的属性时会发生什么,如何解决?
A:
<template>
<div>
<ul>
<li v-for="value in obj" :key="value">
{{value}}
</li>
</ul>
<button @click="addObjB">添加obj.b</button>
</div>
</template>
<script>
export default {
data () {
return {
obj: {
a: 'obj.a'
}
}
},
methods: {
addObjB () {
this.obj.b = 'obj.b'
console.log(this.obj)
}
}
}
</script>
<style></style>
点击button会发现,obj.b 已经成功添加,但是视图并未刷新:
原因在于在Vue实例创建时,obj.b并未声明,因此就没有被Vue转换为响应式的属性,自然就不会触发视图的更新,这时就需要使用Vue的全局api $set():
addObjB () {
// this.obj.b = 'obj.b'
this.$set(this.obj, 'b', 'obj.b')
console.log(this.obj)
}
$set()方法相当于手动的去把obj.b处理成一个响应式的属性,此时视图也会跟着改变了:
Q:delete和Vue.delete删除数组的区别
A:delete只是被删除的元素变成了 empty/undefined 其他的元素的键值还是不变。
Vue.delete直接删除了数组 改变了数组的键值。
var a=[1,2,3,4]
var b=[1,2,3,4]
delete a[1]
console.log(a)
this.$delete(b,1)
console.log(b)
Q:如何优化SPA应用的首屏加载速度慢的问题?
A: 将公用的JS库通过script标签外部引入,减小app.bundel的大小,让浏览器并行下载资源文件,提高下载速度;
在配置 路由时,页面和组件使用懒加载的方式引入,进一步缩小 app.bundel 的体积,在调用某个组件时再加载对应的js文件;
加一个首屏 loading 图,提升用户体验;
Q: 插值表达式、v-text、v-html以及v-cloak的基本使用
A:
网络延迟
插值表达式存在网络延迟问题, 而v-cloak 能解决由于网络延迟导致的数据渲染显示问题, 网络延迟时,v-text,v-html 均不会渲染;
拼接渲染
插值表达式可以增加其他字符串内容,v-text、v-html只能根据data设置的内容渲染元素。
<p> {{msg}} + this is more you can see </p>
<div v-text="msg"> can i?</div>
<div v-html="msg"> can i ?</div>
// 浏览器中 只有第一行能正常显示msg外的内容
富文本
v-html 能用于富文本显示。 插值表达式和v-text会对msg内容进行转义。
10. Vue 中怎么自定义指令
全局注册
// 注册一个全局自定义指令 `v-focus`
Vue.directive('focus', {
// 当被绑定的元素插入到 DOM 中时……
inserted: function (el) {
// 聚焦元素
el.focus()
}
})
局部注册
directives: {
focus: {
// 指令的定义
inserted: function (el) {
el.focus()
}
}
}
16. Vue 中怎么自定义过滤器
可以用全局方法 Vue.filter() 注册一个自定义过滤器,它接收两个参数:过滤器 ID 和过滤器函数。过滤器函数以值为参数,返回转换后的值
// html代码
<div id="app">
<input type="text" v-model="msg" />
{{msg| capitalize }}
</div>
// js代码
var vm=new Vue({
el:"#app",
data:{
msg:''
},
filters: {
capitalize: function (value) {
if (!value) return ''
value = value.toString()
return value.charAt(0).toUpperCase() + value.slice(1)
}
}
})
// 全局定义过滤器
Vue.filter('capitalize', function (value) {
if (!value) return ''
value = value.toString()
return value.charAt(0).toUpperCase() + value.slice(1)
})
17. 对 keep-alive 的了解
keep-alive 是 Vue 内置的一个组件,可以使被包含的组件保留状态,或避免重新渲染
在vue 2.1.0 版本之后,keep-alive新加入了两个属性: include(包含的组件缓存) 与 exclude(排除的组件不缓存,优先级大于include) 。
使用方法
<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>