1.Vue实现数据双向绑定的原理
vue.js是采用数据劫持结合发布者 - 订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。
2.Vue的生命周期
beforeCreate(创建前) 在数据观测和初始化事件还未开始
created(创建后) 完成数据观测,属性和方法的运算,初始化事件,$el属性还没有显示出来
beforeMount(载入前) 在挂载开始之前被调用,相关的render函数首次被调用。实例已完成以下的配置:编译模板,把data里面的数据和模板生成html。注意此时还没有挂载html到页面上。
mounted(载入后) 在el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用。实例已完成以下的配置:用上面编译好的html内容替换el属性指向的DOM对象。完成模板中的html渲染到html页面中。此过程中进行ajax交互。
beforeUpdate(更新前) 在数据更新之前调用,发生在虚拟DOM重新渲染和打补丁之前。可以在该钩子中进一步地更改状态,不会触发附加的重渲染过程。
updated(更新后) 在由于数据更改导致的虚拟DOM重新渲染和打补丁之后调用。调用时,组件DOM已经更新,所以可以执行依赖于DOM的操作。然而在大多数情况下,应该避免在此期间更改状态,因为这可能会导致更新无限循环。该钩子在服务器端渲染期间不被调用。
beforeDestroy(销毁前) 在实例销毁之前调用。实例仍然完全可用。
destroyed(销毁后) 在实例销毁之后调用。调用后,所有的事件监听器会被移除,所有的子实例也会被销毁。该钩子在服务器端渲染期间不被调用。
a.什么是vue生命周期?
答: Vue 实例从创建到销毁的过程,就是生命周期。从开始创建、初始化数据、编译模板、挂载Dom→渲染、更新→渲染、销毁等一系列过程,称之为 Vue 的生命周期。
b.vue生命周期的作用是什么?
答:它的生命周期中有多个事件钩子,让我们在控制整个Vue实例的过程时更容易形成好的逻辑。
c.第一次页面加载会触发哪几个钩子?
答:会触发 beforeCreate, created, beforeMount, mounted 。
d.DOM 渲染在 哪个周期中就已经完成?
答:DOM 渲染在 mounted 中就已经完成了。
3.vue中 key 值的作用
使用key来给每个节点做一个唯一标识
key的作用主要是为了高效的更新虚拟DOM。另外vue中在使用相同标签名元素的过渡切换时,也会使用到key属性,其目的也是为了让vue可以区分它们,
否则vue只会替换其内部属性而不会触发过渡效果。
4.Vue 组件中 data 为什么必须是函数
在 new Vue() 中,data 是可以作为一个对象进行操作的,然而在 component 中,data 只能以函数的形式存在,不能直接将对象赋值给它。
当data选项是一个函数的时候,每个实例可以维护一份被返回对象的独立的拷贝,这样各个实例中的data不会相互影响,是独立的
5.v-if 和 v-show 有什么区别?
相同点: 两者都是在判断DOM节点是否要显示
不同点:
a.实现方式: v-if是根据后面数据的真假值判断直接从Dom树上删除或重建元素节点。 v-show只是在修改元素的css样式,也就是display的属性值,元素始终在Dom树上。
b.编译过程:v-if切换有一个局部编译/卸载的过程,切换过程中合适地销毁和重建内部的事件监听和子组件; v-show只是简单的基于css切换;
c.编译条件:v-if是惰性的,如果初始条件为假,则什么也不做;只有在条件第一次变为真时才开始局部编译; v-show是在任何条件下(首次条件是否为真)都被编译,然后被缓存,而且DOM元素始终被保留;
d.性能消耗:v-if有更高的切换消耗,不适合做频繁的切换; v-show有更高的初始渲染消耗,适合做频繁的额切换;
6.请简述下Vuex的原理和使用方法
数据单向流动
一个应用可以看作是由上面三部分组成: View, Actions,State,数据的流动也是从View => Actions => State =>View 以此达到数据的单向流动.
但是项目较大的, 组件嵌套过多的时候, 多组件共享同一个State会在数据传递时出现很多问题.Vuex就是为了解决这些问题而产生的.
Vuex可以被看作项目中所有组件的数据中心,我们将所有组件中共享的State抽离出来,任何组件都可以访问和操作我们的数据中心
Vuex的组成:一个实例化的Vuex.Store由state, mutations和actions三个属性组成:
state中保存着共有数据
改变state中的数据有且只有通过mutations中的方法,且mutations中的方法必须是同步的
如果要写异步的方法,需要些在actions中, 并通过commit到mutations中进行state中数据的更改.
7.<keep-alive></keep-alive>
的作用是什么?
<keep-alive></keep-alive>
包裹动态组件时,会缓存不活动的组件实例,主要用于保留组件状态或避免重新渲染。
缓存: <keep-alive include=”组件名”></keep-alive>
不缓存:<keep-alive exclude=”组件名”></keep-alive>
8.axios是什么?怎么使用?描述使用它实现登录功能的流程?
请求后台资源的模块。npm install axios -S装好,然后发送的是跨域,需在配置文件中config/index.js进行设置。后台如果是Tp5则定义一个资源路由。js中使用import进来,然后.get或.post。返回在.then函数中如果成功,失败则是在.catch函数中
9.MVVM和MVC区别?和其他框架(jquery)区别?那些场景适用?
MVVM和MVC都是一种设计思想,主要就是MVC中的Controller演变成ViewModel,,MVVM主要通过数据来显示视图层而不是操作节点,解决了MVC中大量的DOM操作使页面渲染性能降低,加载速度慢,影响用户体验问题。主要用于数据操作比较多的场景。
场景:数据操作比较多的场景,更加便捷
10.computed和watch有什么区别?
computed:
computed计算属性是用来声明式的描述一个值依赖了其它的值。当你在模板里把数据绑定到一个计算属性上时,Vue 会在其依赖的任何值导致该计算属性改变时更新 DOM。这个功能非常强大,它可以让你的代码更加声明式、数据驱动并且易于维护。 // 计算属性computed,计算的是Name依赖的值,它不能计算在data中已经定义过的变量。
watch监听的是你定义的变量,当你定义的变量的值发生变化时,调用对应的方法。// 当num的值发生变化时,就会调用num的方法,方法里面的形参对应的是num的新值和旧值
一个数据属性在它所依赖的属性发生变化时,也要发生变化,这种情况下,我们最好使用计算属性。
watch函数适用于,当数据发生变化时,执行异步操作或较大开销操作的情况。
11.vue的优点是什么?
低耦合。视图(View)可以独立于Model变化和修改,一个ViewModel可以绑定到不同的"View"上,当View变化的时候Model可以不变,当Model变化的时候View也可以不变。
· 可重用性。你可以把一些视图逻辑放在一个ViewModel里面,让很多view重用这段视图逻辑。
· 独立开发。开发人员可以专注于业务逻辑和数据的开发(ViewModel),设计人员可以专注于页面设计。
· 可测试。界面素来是比较难于测试的,而现在测试可以针对ViewModel来写。
12.组件之间的传值?
父组件给子组件传值:
a.父组件在调用子组件的地方,添加一个自定义的属性,属性的值就是你要传递给子组件的值,如果属性的值是number类型,boolean类型,或者是变量,需要使用到绑定属性
b.在子组件定义的地方,给他添加一个选项 props,props的值可以为数组以及对象
如果是数组, 元素则为父组件中自定义的属性名
如果是对象,对象的形式有两种写法
c.在子组件中就可以通过 你自定义的属性名 得到父组件传递过来的数据
写法一:验证传递数据的有效性
props: {
test: String,
}
写法二:既要验证数据的类型,又要设定属性的默认值,如果默认值是对象或者是数组,值为一个函数
props: {
test: {
type: String,
default: '测试数据了'
}
}
子组件给父组件传值
a.父组件调用子组件的地方,给他绑定一个自定义的事件, 事件不要加()
<my-content @myevent="getData"/>
b.在父组件选项methods中实现此事件,默认参数为你将从子组件得到的值
methods: {
getData (val) { // val为从子组件中获取到的值
console.log(val)
}
},
c.在子组件中,可以是生命周期钩子函数,也可以是组件自己的事件 去 触发 父组件中的自定义事件
this.$emit('myevent', 10000)
非父子组件传值
a.中央事件总线传值 1. const bus = new Vue()
b.在接收端通过 bus.
o
n
(
′
收
信
信
号
′
,
f
u
n
c
t
i
o
n
(
v
a
l
)
)
c
.
在
发
送
端
通
过
b
u
s
.
on('收信信号', function (val) { }) c.在发送端通过 bus.
on(′收信信号′,function(val))c.在发送端通过bus.emit(‘收信信号’, val)
13.怎么定义 vue-router 的动态路由? 怎么获取传过来的值
在 router 目录下的 index.js 文件中,对 path 属性加上 /:id,使用 router 对象的 params.id 获取。
14.为什么避免v-if和v-for用在一起?
当vue处理指令时,v-for比v-if具有更高的优先级,通过v-if移动到容器的元素,不会在重复遍历列表中的每个值,取而代之的是,我们只检查它一次,且不会v-if为否的时候运算v-for
15.router如何实现跳转
1.声明式跳转:标签跳转
<router-link></router-link>
2.编程式跳转 :js跳转
router.push(‘/’)
3router.go(0)
16.单页面和多页面的区别
单页面:
整个项目中只有一个完整的HTML页面,其它"页面"只是一段HTML片断而已
优: 请求少
缺: 不利于搜索引擎优化
页面跳转本质:把当前DOM树中某个DIV删除,下载并挂载另一个div片断
多页面:
项目中有多个独立的完整的HTML页面
缺: 请求次数多,效率低
页面跳转本质:
删除旧的DOM树,重新下载新的DOM树
17.Vue和vuex 有什么区别
Vue是框架,vuex是插件,vuex是专门为vue应用程序开发的状态管理模式
18.说出至少4种vue当中的指令和用法?
V-if:判断是否隐藏 v-for:数据循环 v-bind:绑定属性
v-model:双向绑定 v-is:动态组件特殊特性 v-on:事件绑定
19.v-on和v-bind的区别
v-bind指令用于设置HTML属性:v-bind:href 缩写为 :href
v-on 指令用于绑定HTML事件 :v-on:click 缩写为 @click
20.vue-router有哪几种导航钩子?
三种,一种是全局导航钩子:router.beforeEach(to,from,next),作用:跳转前进行判断拦截。第二种:组件内的钩子;第三种:单独路由独享组件
21.$route
和$router的区别
$route
是“路由信息对象”,包括path,params,hash,query,fullPath,matched,name等路由信息参数。而$router
是“路由实例”对象包括了路由的跳转方法,钩子函数等
22.vue路由hash模式与history模式的区别
a、hash ——即地址栏URL中的#符号(此hsah 不是密码学里的散列运算)。
比如这个URL:http://www.abc.com/#/hello, hash 的值为#/hello。
它的特点在于:hash 虽然出现URL中,但不会被包含在HTTP请求中,
对后端完全没有影响,因此改变hash不会重新加载页面。
b、history ——利用了HTML5 History Interface 中新增的pushState() 和replaceState() 方法。(需要特定浏览器支持)
history模式,会出现404 的情况,需要后台配置。
404 错误
1、hash模式下,仅hash符号之前的内容会被包含在请求中,
如 http://www.abc.com, 因此对于后端来说,即使没有做到对路由的全覆盖,
也不会返回404错误;
2、history模式下,前端的url必须和实际向后端发起请求的url 一致,
如http://www.abc.com/book/id 。如果后端缺少对/book/id 的路由处理,
将返回404错误。
23.在Vue中使用插件的步骤
采用ES6的import … from …语法或CommonJS的require()方法引入插件
使用全局方法Vue.use( plugin )使用插件,可以传入一个选项对象Vue.use(MyPlugin, { someOption: true })
24.对比 jQuery ,Vue 有什么不同
jQuery 专注视图层,通过操作 DOM 去实现页面的一些逻辑渲染; Vue 专注于数据层,通过数据的双向绑定,最终表现在 DOM 层面,减少了 DOM 操作。
Vue 使用了组件化思想,使得项目子集职责清晰,提高了开发效率,方便重复利用,便于协同开发。