1.v-if 和 v-show 区别
(1)手段:v-if是动态的向DOM树内添加或者删除DOM元素;v-show是通过设置DOM元素的display样式属性控制显隐;
(2)编译过程:v-if切换有一个局部编译/卸载的过程,切换过程中合适地销毁和重建内部的事件监听和子组件;v-show只是简单的基于css切换;
(3)编译条件:v-if是惰性的,如果初始条件为假则什么也不做,只有在条件第一次变为真时才开始局部编译;v-show是在任何条件下都被编译,然后被缓存,而且DOM元素保留;
(4)性能消耗:v-if有更高的切换消耗;v-show有更高的初始渲染消耗;
(5)使用场景:v-if适合运营条件不大可能改变;v-show适合频繁切换。
2.vue常用的修饰符
.prevent: 提交事件不再重载页面;
.stop: 阻止单击事件冒泡;
.self: 当事件发生在该元素本身而不是子元素的时候会触发;
.capture: 事件侦听,事件发生的时候会调用。
3.vue中 key 值的作用
当 Vue.js 用 v-for 正在更新已渲染过的元素列表时,默认用“就地复用”策略,如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序,而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素。key的作用主要是为了高效的更新虚拟DOM。
4.vue的单页面应用(SPA)的优缺点
优点:Vue是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件,核心是一个响应的数据绑定系统;组件化开发、轻量、简洁、高效、快速、模块友好。
缺点:不支持低版本的浏览器,最低只支持到IE9;不利于SEO的优化(如果要支持SEO,建议通过服务端来进行渲染组件);第一次加载首页耗时相对长一些;不可以使用浏览器的导航按钮需要自行实现前进、后退。
5.Vue的生命周期
(1)生命周期是什么?
Vue 实例有一个完整的生命周期,也就是从开始创建、初始化数据、编译模版、挂载 Dom 渲染 更新 渲染 卸载等一系列过程,我们称这是 Vue 的生命周期。
(2)生命周期的各个阶段作用
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(销毁后) 在实例销毁之后调用。调用后,所有的事件监听器会被移除,所有的子实例也会被销毁。该钩子在服务器端渲染期间不被调用。
6.Vue组件间的参数传递
父子组件间传参
父给子传参(父:自定义属性传递变量;子:用Props['父元素自定义属性']接受)
子给父传参(子:this.$emit(父元素自定义事件,传递的值) ;父:自定义事件用参数去接收传递来 的值)
兄弟间传参(除了以下方式也可直接用Vuex)
通过给eventbus注册事件,别的组件触发事件,实现通信。
①创建一个eventbus对象,即创造一个vue对象,用作传递信息。
②接收信息的一方将事件通过vm.$on(“事件名”,事件处理函数)添加在eventbus对象上。
③发送数据的一方,通过vm.$emit(“事件名”,传递的数据)触发事件,将数据传递。
路由传参
a.通过params
//需要在router的path后跟上参数 { path: "/two", name: "two", component: two } //跳转时 this.$router.push({ path: `/two` //直接把数据拼接在path后面 }) //接收时 this.$route.params
b.通过query
//跳转时 this.$router.push({ path: `/two`, query: { id: this.message, data: 456 } }); //接收时 this.$route.query
params 和 query 都是传递参数的,params不会在url上面出现,并且params参数是路由的一部分,是一定要存在的 , query是我们通常看到的url后面的跟在 ?后面的显示参数。
7.为什么vue中data必须是一个函数?
对象为引用类型,当重用组件时,由于数据对象都指向同一个data对象,当在一个组件中修改data时,其他重用的组件中的data会同时被修改;而使用返回对象的函数,由于每次返回的都是一个新对象(Object的实例),引用地址不同,则不会出现这个问题。
8.对MVVM模式的理解
MVVM 是 Model-View-ViewModel 的缩写;
Model 代表数据模型,也可以在Model中定义数据修改和操作的业务逻辑;
View 代表UI组件,负责将数据模型转化成UI展现出来;
ViewModel 监听模型数据的改变和控制视图行为、处理用户交互,简单理解就是一个同步View 和 Model的对象,连接Model和View。
在MVVM架构下,View 和 Model 之间并没有直接的联系,而是通过ViewModel进行交互,Model 和 ViewModel 之间的交互是双向的, 因此View 数据的变化会同步到Model中,而Model 数据的变化也会立即反应到View 上。
ViewModel 通过双向数据绑定把 View 层和 Model 层连接了起来,而View 和 Model 之间的同步工作完全是自动的,无需人为干涉,开发者只需关注业务逻辑,不需要手动操作DOM, 不需要关注数据状态的同步问题,复杂的数据状态维护完全由 MVVM 统一管理。
9. vue-router 有哪几种导航钩子?
10.路由嵌套
路由嵌套会将其他组件渲染到该组件内,而不是进行整个页面跳转;
router-view本身就是将组件渲染到该位置,想要进行页面跳转,就要将页面渲染到根组件,在起始配置路由时候写:
var App = Vue.extend({ root }); router.start(App,'#app');
11.axios的特点有哪些
(1)axios是一个基于promise的HTTP库,支持promise的所有API;
(2)它可以拦截请求和响应;
(3)它可以转换请求数据和响应数据,并对响应回来的内容自动转换为json类型的数据;
(4)它安全性更高,客户端支持防御XSRF。
12.页面刷新vuex被清空时的解决办法
(1)localStorage 存储到本地再回去;
(2)重新获取接口获取数据。
13.vue中的 ref 是什么
ref 被用来给元素或子组件注册引用信息。引用信息将会注册在父组件的 $refs 对象上;如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子组件上,引用就指向组件实例。
14.Promise对象是什么
Promise是异步编程的一种解决方案,它是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise 是一个对象,可以获取异步操作的消息;Promise 提供统一的 API,各种异步操作都可以用同样的方法进行处理;promise对象是一个构造函数,用来生成Promise实例;
promise的特点是对象状态不受外界影响且一旦状态改变,就不会再变,任何时候都可以得到结果。Promise有三种状态:
pending:初始状态,不是成功或失败状态。
fulfilled:意味着操作成功完成。
rejected:意味着操作失败。
优点是将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数,避免回调地狱。Promise 对象提供统一的接口,使得控制异步操作更加容易。
缺点是无法取消 Promise,一旦新建它就会立即执行,无法中途取消,如果不设置回调函数,Promise 内部抛出的错误,不会反应到外部。 当处于 Pending 状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。
15.什么是js的冒泡?Vue中如何阻止冒泡事件
js冒泡概念:当父元素内多级子元素绑定了同一个事件,js会依次从内往外或者从外往内执行每个元素的该事件,从而引发冒泡。
js解决冒泡:event.stopPropagation();
vue解决冒泡: 事件.stop,例如:@click.stop="" 、@mouseover.stop=""
16.指令周期
17.如何优化SPA应用的首屏加载速度慢的问题?
将公用的JS库通过script标签外部引入,减小app.bundel的大小,让浏览器并行下载资源文件,提高下载速度;
在配置路由时,页面和组件使用懒加载的方式引入,进一步缩小 app.bundel 的体积,在调用某个组件时再加载对应的js文件;
加一个首屏 loading 图,提升用户体验;
18.解释一下vuex
vuex是用来做状态管理的,有五个常用属性state, getter, actions, mutations, modules;
state是数据源,类似vue中的data,我们可以通过两种方式来获取它,mapStates, mapGerters。获取state必须放到computed中,这样才能保证state发生改变的时候该组件中用到state的地方都发生变化。
getters:相当于计算属性;
mutation:同步操作, 修改数据;
action:异步操作;
modules:模块化
补充:如何获取vuex的state对象中的属性?
方法1:直接从store实例中取值 this.$store.state.属性;
方法2:利用vuex的mapState方法来获取vuex的state对象中属性;
//先在组件中引入vuex的mapState方法 import { mapState } from 'vuex' //在computed中 computed:{ ...mapState({ count:state => state.count //使用ES6的箭头函数来给count赋值 }) } //在computed中也可写成数组格式 computed: ...mapState(['count']) }
19.说出至少4种vue当中的指令和它的用法?
补充:v-for为什么必须加:key
a.为每个元素添加唯一标识;
b.避免重建整个列表;
c.提高修改的效率。
20.vue.cli中怎样使用自定义组件?有遇到过哪些问题吗?
第一步:在components目录新建组件文件(smithButton.vue),在组件文件中的script代码中一定要用 export default 将组件导出;
第二步:在需要用的页面(组件)中导入:import smithButton from ‘../components/smithButton.vue’;
第三步:注入到vue的子组件的components属性上面,components:{smithButton};
第四步:在template视图view中使用,<smith-button> </smith-button>
问题:smithButton命名,使用的时候则smith-button(HTML不认识大写字母)。