Vue 知识点及面试总结
1、 什么是MVVM
MVVM是Model-View-ViewModel 的缩写。mvvm是一种设计思想。Model 层代表数据模型,也可以在Model 中定义数据修改和操作的业务逻辑;View 代表UI组件,他负责将数据模型转化成UI展现出来,ViewModel是一个同步 View 和 Model 的对象。
在 MVVM 架构下, View 和 Model 之间并没有直接的联系,而是通过 ViewModel 进行交互,Model 和 ViewModel 之间的交互是双向的,因此 View 数据的变化会同步到 Model 中,而Model 数据的变化也会立即反应到 View 上。
ViewModel 通过双向数据绑定把 View 层和 Model 层连接了起来,而 View 和 Model 之间的同步工作完全是自动的,无需人为干涉,因此开发者只需关注业务逻辑,不需要手动操作 DOM ,不需要关注数据状态的同步问题,复杂的数据状态维护完全由 MVVM 来统一管理。
2、mvvm 和 mvc 的区别
mvvm 和 mvc 的区别并不大。都是一种设计思想。主要是mvc 中 Controller 演变成 mvvm 中的ViewModel。mvvm 主要解决了 mvc 中大量 DOM 操作是页面渲染性能降低,加载速度变慢,影响用户体验。
3、 Vue 的生命周期
beforeCreate (创建前)在数据观测和初始化事件还未开始
created (创建后)完成数据观测,属性和方法的运算,初始化事件,$el 属性还没有显示出来
beforeMout (挂载前)在挂载开始之前被调用,相关的 render 函数首次被调用。实例已完成以下配置:编译模板,把data里面的数据和模板生成 html;此时还没有挂载html到页面上
mounted(挂载后 e l 会 被 新 创 建 的 v m . el 会被新创建的 vm. el会被新创建的vm.el 替换,并挂载到实例上去之后调用。实例已完成以下的配置:把挂载前编译好的html内容替换 el 属性指向的 DOM 对象。完成模板中的 html 渲染到 html 页面中。此过程中进行ajax交互。
beforeUpdate(更新前)在数据更新之前调用,发生在虚拟 DOM 重新渲染和打补丁之前。可以在改钩子中进一步地更改状态,不会触发附加的重渲染过程。
updated(更新后)由于数据更改导致的虚拟 DOM 重新渲染和打补丁之后调用。调用时,组件DOM已经更新,所以可以执行依赖于DOM的操作。然而在大多数情况下,应该避免在此期间更改状态,因为这有可能会导致更新无限循环。该钩子在服务器渲染期间不被调用。
beforeDestroy (销毁前)在实例销毁之前调用,实例仍然完全可用。
destroyed(销毁后)在实例销毁之后调用。调用后,所有的事件监听器都会被移除,所有的子实例也会被销毁。该钩子在服务器渲染期间不会被调用
3.1、什么是vue生命周期
Vue 实例从创建到销毁的过程,就是vue的生命周期。从开始创建、初始化数据、编译模板、挂载DOM—渲染、更新—渲染、销毁等一系列过程,称之为vue的生命周期
3.2、vue 生命周期的作用是什么
它得生命周期中有多个事件钩子,让我们在控制整个Vue实例的过程时更容易形成好的逻辑
3.3、vue 生命周期总共有几个阶段
总共分为 8 个阶段:创建前 / 后,挂载前 / 后,更新前 / 后,销毁前 / 后
3.4、第一次页面加载会触发哪几个钩子
它会触发beforeCreate、created、beforeMount、mounted这几个钩子
3.5、DOM渲染在哪个周期中就已经完成
DOM渲染在 mounted 挂载中就已经完成了
4、Vue 组件之间的传值
4.1、父子组件的传值
父组件通过属性方式向子组件传值,子组件通过props来接收父子间传入的参数值;
子组件通过**$emit** 向外触发事件向父组件传值,父组件通过监听事件来监听子组件的向外触发事件来获取子 组件传过来的值。
4.2、非父子组件传值(兄弟组件)
eventBus(数据发布-订阅者模式),就是创建一个事件中心,相当于中转站,可以用它来传递事件和接收事件,如果项目较小时,用eventBus 比较合适
5、Vue 的双向绑定的原理是什么
vue.js 是采用数据劫持结合发布者-订阅者模式的方式,通过 Object.defineProperty() 来劫持各个属性的 setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。当把一个普通 JavaScript 对象传给Vue 实例来作为它的 data 选项时,Vue 将遍历它的属性, 用 Object.defineProperty 将它们转为 getter/setter。用户看不到getter/setter,但是在内部它们让Vue 追踪依赖,在属性被访问和修改时通知变化。
vue的数据双向绑定将 MVVM作为数据绑定的入口,整合Observer,Compile和Watcher三者, 通过Observer来监听自己的model的数据变化,通过Compile来解析编译模板指令(vue中是用来解析 {{}}),最终利用watcher搭起 Observer 和 Compile 之间的通信桥梁,达到数据变化—视图更新;视图交互变化(input)— 数据 model 变更双向绑定效果
<html>
....
<body>
<div id="app">
<input type="text" id="test" />
<p id="show"></p>
</div>
</body>
<script>
var obj = {}
Object.defineProperty(obj, 'test', {
get: function () {
return obj
},
set: function (newValue) {
document.getElementById('test').value = newValue
document.getElementById('show').innerHTML = newValue
}
})
document.addEventListener('keyup', function (e) {
obj.txt = e.target.value
})
</script>
</html>
6、active-class 是哪个组件的属性
vue-router 模块的router-link 组件
7、嵌套路由如何定义
在 VueRouter 的参数中使用 children 配置
<div id="app">
<!-- router-view 路由出口, 路由匹配到的组件将渲染在这里 -->
<router-view></router-view>
</div>
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
//引入两个组件
import home from "./home.vue"
import game from "./game.vue"
//定义路由
const routes = [
{ path: "/", redirect: "/home" },//重定向,指向了home组件
{
path: "/home", component: home,
children: [
{ path: "/home/game", component: game }
]
}
]
//创建路由实例
const router = new VueRouter({routes})
new Vue({
el: '#app',
data: {
},
methods: {
},
router
})
8、路由之间的跳转
声明式(标签跳转)
编程式(js 跳转)router.push(‘index’)
9、懒加载(按需加载路由)
webpack 中提供了 require.ensure() 来实现按需加载;以前引入路由是通过 import 的方式引入,改为const 定义的方式进行引入。
import引入方式:
{
path: '/login',
component: () => import(/* webpackChunkName: "login-view" */ '../views/login/login.vue')
// component: Login
}
require.ensure()引入方式:
const home = r => require.ensure( [], () => r (require('../../common/home.vue')))
9、vuex 是什么,怎么使用,哪种功能场景使用
vue 框架中的状态管理。在 main.js 引入 store 注入。新建一个目录 store , … export。场景有:单页应用中组件之间的状态;音乐播放、登录状态、加入购物车
// 新建 store.js
import vue from 'vue'
import vuex form 'vuex'
vue.use(vuex)
export default new vuex.store({
//...code
})
//main.js
import store from './store'
...
10、vue-router 有哪几种导航钩子
三种
全局导航钩子
router.beforeEach(to, from, next),
router.beforeEasolve(to, from, next),
router.afterEach(to, from, next)
组件内钩子
beforeRouteEnter
beforeRouteUpdate
beforeRouteLeave
单独路由独享组件
beforeEnter
11、自定义指令(v-check,v-focus)的方法有哪些,它有哪些钩子函数,有哪些钩子函数参数
全局定义指令:在vue 对象的 directive 方法里面有两个参数,一个是指令名称,另一个是函数
组件内定义指令:directives
钩子函数:bind(绑定事件触发)、inserted(节点插入时触发)、update(组件内相关更新)
钩子函数参数: el、binding
12、vuex 有哪几种属性
有5种,分别是state、getter、mutation、action、module
13、vuex 的 store 特性是什么
vuex 就是一个仓库,仓库里放了很多对象。其中state就是数据源存放地,对应于一般 vue 对象里面的data
state 里面存放的数据是响应式的,vue 组件从store读取数据,若是 store 中的数据发生改变,依赖这数据的组件也会发生改变
它通过 mapState 把全局的 state 和 getters 映射到当前组件的computed 计算属性
14、vuex 的 getter 特性是什么
getter 可以对 state 进行计算操作,是 store 的计算属性
在组件内可以做计算属性,getters 可以在多组件之间复用
如果一个状态只在一个组件内使用,是可以不用 getters
15、 vuex 的 mutation 特性是什么
action 类似于 mutation ,不同在于:action 提交的是 mutation, 而不是直接变更状态
action 可以包含任意异步操作
16、在 vue 中 ajax 请求代码应该写在组件的 methods 中还是 vuex 的 action 中
如果请求来的数据不是要被其他组件共用,仅仅在请求的组件内使用,就不需要放入 vuex 的 state 里
如果被其他组件复用,将请求放入 action 中,方便复用,并包装成 promise 返回
17、CSS只在当前组件器作用
在style标签中写入 scoped 即可
18、v-if 和 v-show 的区别
v-if 是按照条件是否渲染,v-show 是display的block或none
19、$route 和 $router 的区别
$route 是 ”路由信息对象“,包括path、params、hash、query、fullPath、matched、name 等路由信息参数。而 $router 是 ”路由实例“ 对象包括了路由的跳转方法,钩子函数等。
20、vue 的两个核心是什么
数据驱动、组件系统
21、vue 几种常用的指令
v-for、v-if、v-bind、v-on、v-show、v-else
22、vue常用的修饰符
.prevent:提交事件不再重载页面
.stop:阻止单击事件冒泡
.self:当事件发生在该元素本身而不是子元素的时候会触发
.capture:事件侦听,事件发生的时候会调用
23、v-on 可以绑定多个方法吗
可以
24、vue中 key 值的作用
当 vue 用 v-for 正在更新已渲染过的元素列表时,它默认用 “就地复用” 策略。如果数据项的顺序被改变,vue 将不会移动 DOM 元素来匹配数据项的顺序,而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素。key 的作用主要是为了高效的更新虚拟DOM
25、什么是Vue 的计算属性
在模板中放入太多的逻辑会让模板过重且难以维护,在需要对数据进行复杂处理,且可能多次使用的情况下,尽量采取计算属性的方式。
好处:
-
使数据处理结构清晰
-
依赖于数据,数据更新,处理结果自动更新
-
计算属性内部this指向vm 实例
-
在template 调用时,直接写计算属性名即可
-
常用的是 getter 方法获取数据,也可以使用 set 方法改变数据
-
相较于 methods,不管依赖的数据变不变,methods都会重新计算,但是依赖数据不变的时候 computed 从缓存中获取,不会重新计算
26、vue 等单页应用及其优缺点
优点:
vue 的目标是通过尽可能简单的API 实现响应的数据绑定和组合的视图组件,核心是一个响应的数据绑定系统。MVVM、数据驱动、组件化、轻量、简洁、高效、快速、模块友好
缺点:
不支持低版本的浏览器,最低支持到IE9;不利于SEO的优化(如果要支持SEO,建议通过服务端来进行渲染组件); 第一次加载首页耗时相对长一些;不可以使用浏览器的导航按钮需要自行实现前进、后退。
27、怎么定义 vue-router 的动态路由,怎么获取传过来的值
在router 目录下的 index.js 文件中,对 path 属性加上 /:id , 使用 router 对象的 param.id 获取