1、v-show和v-if的区别
v-show 操作的是元素的display属性
v-if 操作的是元素的创建和插入
v-if有更高的开销,而v-show有更高的初始渲染开销,如果需要非常频繁的切换,则使用v-show更好,如果在运行时条件很少改变,则使用v-if更好
使用场景:v-show----前台数据的展示 v-if----管理系统权限列表的展示
2、methods、computed、watch三者的区别
三者的共同点:
methods、computed、watch都是以函数为基础的
computed与watch都是以vue的依赖为基础,当所依赖的数据发生变化的时候会触发相关的函数去实现数据的变动
methods里是用来定义函数的,需要手动才能执行,不想computed和watch是“自动执行”函数
三者的不同点:
computed是计算属性,computed所依赖的属性发生变化是,计算属性才会重新计算,并进行缓存。当其他数据发生改变的时候computed属性不会重新计算,从而提升性能
watch:
a、watch类似于事件监听+事件机制
b、watch的方法默认是不会执行的,只有依赖的属性发生变化才会执行
c、watch默认第一次是不会执行的,通过声明immediate选项为true可以立即执行一次handler
d、watch用在监听数据变化,给后台发送数据请求
e、watch中的handler默认只能监听属性引用的变化,但内部属性是监听不到的,设置deep为true可以进行深度监听,但是性能开销也会变大
f、watch无法监听数据值的变化(特殊情况下)
computed和watch的使用场景:
computed一个数据受多个数据的影响 例如:商品购物车的结算,过滤某些商品数据
watch一个数据影响多个数据 例如:网络请求、浏览器自适应、监控路由对象
3、watch无法监听数组的情况,以及解决方案
无法监听数组的情况:
a、利用索引直接设置一个数组项时,例如:arr[indexOfItem]=newValue
b、修改数组的长度时,例如:arr.length=newLength
解决方案:
a、this.$set(arr,index,newVal)
b、使用数组splice方法
4、如何给一个响应式对象中添加一个属性?如何删除响应式对象中的属性?
import Vue from "vue" new Vue({ data:{ obj:{ } } }) Vue.set(obj,name,"孙艺珍") Vue.delete(obj,"name")
5、vue中自定义指令如何使用
Vue.directive()
参数一:指令名称
参数二:指令实现的函数,在回调函数中参数一是指令绑定的元素,参数二是一个对象,对象中有value属性代表的是表达式返回的结果,还有modifiers属性是指令的修饰符
6、vue中组件创建的方式有哪些
全局组件:Vue.component()
参数一:组件名称
参数二:组件的配置项
局部组件:new Vue({
components:{} key值为组件名称,val值为组件的配置项
})
7、vue中的过滤器如何使用
vue.filter()
参数一:过滤器名称
参数二:过滤器实现的方法,该方法中有两个参数,分别为需要过滤的数据、过滤器传递的参数
8、vue中组件通讯的方式有哪些
父传子:
通过绑定自定义属性,通过props接收
子传父:
a、通过绑定自定义事件
b、通过插槽作用域
非父子组件传值:
a、创建公共的vue实例对象
b、EventBus
c、手动封装事件订阅
d、vuex
9、vue的生命周期
beforeCreate() 组件刚刚被创建(el和data未初始化)
created() 组件创建已完成,属性已绑定,但DOM还未生成($el属性还不存在)
beforeMount() 模板挂载前(el和data初始化)
mounted() 挂载后
beforeUpdate() 组件更新前
updated() 组件更新后
beforeDestroy() 组件销毁前
destroyed() 组件销毁后
10、vue中的单向数据流
数据从父组件传递给子组件,只能单向绑定,子组件不能直接修改从父级传递过来的数据
数据只能从一个方向来修改状态,如果父组件给n个子组件进行了数据传递,那么某一个子组件中修改了这个数据,那么就会导致其他组件中的数据也会发生改变。这样会防止从子组件中意外改变父组件的状态,从而导致你的应用数据的流向难以理解,因此数据只能从一个方向来修改状态
11、什么是动态组件,如何使用,以及keep-alive的作用
动态组件:让多个组件使用同一个挂载点,并动态进行切换
实现动态组件:通过保留<component></component>元素,动态的绑定它的is属性,可以实现动态组件
<keep-alive></keep-alive>是一个抽象组件,它自身不会渲染成一个DOM元素
常用的一些属性:
include:类型:字符串或者正则表达式
解释:只有名称匹配的组件会被缓存
exclude:类型:字符串或者正则表达式
解释:任何名称匹配的组件都不会缓存
max:类型:数字
解释:最多可以缓存多少个组件实例
12、当使用keep-alive内置组件后会增加哪两个生命周期
activated:当组件为活跃状态时候触发(进入页面的时候)
deactivated:缓存状态的时候触发
13、vue中slot的使用方式,以及slot作用域插槽的用法
当组件当做标签使用的时候,如果需要在组件标签内部进行嵌套内容的时候,需要通过template组件包裹嵌套的内容,在组件内部通过<slot></slot>进行接收
14、为什么组件内部的data是一个函数而不是一个对象
因为每次调用组件的时候都会重新生成一个对象,如果是一个对象的情况下,data数据会进行复用,因为对象是引用类型数据,而当data是一个函数时,每次调用会返回一个新的对象
15、vue中动画如何实现
给需要动画的元素添加<transition></transition>标签,
进入时class类 <name>-enter <name>-enter-active <name>-enter-to
离开时class类 <name>-leave <name>-leave-active <name>-leave-to
16、浅谈对路由的理解
什么是路由:根据不同的url地址展示不同的页面或者数据
路由分为前端路由和后端路由
前端路由:
a、前端路由用于单页面开发,SPA
b、前端路由是不涉及到服务器的,是前端利用hash或者h5的historyAPI来实现的,一般用于不同的内容展示和切换
17、路由跳转的方式
①a标签进行跳转 <a href="#/home">首页</a>
②router-link进行跳转 <router-link to="/home">首页</router-link>
③编程式路由 this.$router.push()
18、路由传值的方式有哪几种
①动态路由传值 path="/home/:id/name" 通过this.$route.params接收
②query传值 在url中?后面的参数不会被解析,所以可以通过query传值 通过this.$route.query接收
③路由解耦 在配置路由的时候添加props属性为true,在需要接收参数的组件页面通过props接收
④编程式导航 this.$router.push({path:"/home",query:{}})
19、路由常用配置项及作用
path 跳转路径
component 路径相对于的组件
name 命名路由
meta 路由元信息
children 子路由的配置参数(路由嵌套)
props 路由解耦
redirect 路由重定向
20、编程式导航常用的方法
路由跳转 this.$router.push()
路由替换 this.$router.replace()
后退 this.$router.back()
请进 this.$router.forward()
21、如何重定向路由?如何实现路由解耦?
通过配置路由项中的redirect进行重定向
在路由的配置项中设置props:true,在需要接收的组件内部通过props接收
22、如何检测路由参数的变化
通过属性监听来实现或者beforeRouteUpdate()
watch: { "$route"(){ } } beforeRouteUpdate(to,from,next)
23、什么是路由守卫?路由的钩子函数有哪些?分别说出使用的场景及用法
什么是路由守卫:路由跳转前后的一些验证
路由常见的钩子函数:beforeRouteEnter、beforeRouteUpdate、beforeRouteLeave
使用场景:
beforeRouteEnter:当路由进入之前。登录验证、热力图的记录
beforeRouteUpdate:当路由更新的时。如果当前路由发生了变化,但是不需要组件的创建和销毁的过程的时候,就需要用到这个钩子函数
beforeRouteLeave:当路由离开时。支付、退出
24、什么是全局守卫
beforeEach 验证用户是否登录
25、axios和jQuery的ajax有什么不同
axios的优点:
①支持PromiseAPI
②自动转换json数据
③提供了一些并发请求的接口
④客户端支持防止csrf、xsrf
⑤从nodejs中创建http请求
ajax的优缺点:
①jQuery项目庞大,单纯的使用ajax引入整个jQuery不合理
②基于原生的XHR开发,但是XHR架构并不清晰
26、简述vuex的数据传递流程
当组件进行数据修改的时候,我们需要调用dispatch来触发actions中的方法
actions中的方法中有一个commit方法,通过调用commit来触发mutations中的方法进行数据修改
mutations中的方法中有一个state参数,当修改完毕后,因为数据是响应式的,会传导给页面。
27、双向数据绑定的原理
vue.js是采用数据劫持结合发布者-订阅者的方式,通过Object.defineProperty()来劫持各个属性的setter和getter,在数据变动时发布消息给订阅者,触发相应的监听回调。
第一步:需要observer的数据对象进行递归遍历,包括子属性的对象的属性,都加上setter和getter,这样的话,给这个对象的某个值赋值,就会触发setter,那么就能监听到了数据变化
第二步:compile解析模板指令,将模板中的变量替换成数据,然后初始化渲染页面视图,并将每个指令对应的节点绑定更新函数,添加监听数据的订阅者,一旦数据有变动,收到通知更新视图
第三步:watcher订阅者是observer和compile之间通信的桥梁,这要做的事情是:
①在自身实例化时往属性订阅器(dep)里面添加自己
②自身必须有一个update方法
③待属性变动dep.notice()通知时,能调用自身的update方法,并触发compile中绑定的回调,则功成身退
28、使用vue的时候会一下子加载所有的东西使得初始化页面很卡,该如何解决
①路由懒加载
②服务端渲染
③骨架屏注入
像vue这种单页面应用,如果没有应用懒加载,运用webpack打包后的文件将会异常的大,造成进入首页时,需要加载的内容过多,时间过长,会出现长时间的白屏,即使做了loading也是不利于用户体验。而运用懒加载则可以将页面进行划分,需要的时间加载页面,可以有效的分担首页所承担的加载压力,减少首次加载用时。
29、如何在vue中实现css私有化
vue组件中在style标签上添加scoped属性,可以使css私有化。但是这种方法会造成样式不可修改,因为很多时候需要对公共组件的样式做微调,所以慎用。
30、常见的跨域方式
①服务器代理 http-proxy-middleware 原理:服务器之间的请求不存在跨域问题
②nginx proxy-pass后面跟一个跨域的地址
③cors 服务端的代理方式 设置响应头:header(Access-Control-Allow-Origin:*)
④jsonp 原理:表单中的action、script中的src、a标签和link标签中的href都会造成页面的跳转,所以这不存在跨域的问题。jsonP的原理是利用script的src进行跳转,前端将函数传到服务端,服务端将函数加工后再返回,所以jsonp和ajax不是一回事。 缺点:只支持get
31、vue中使用插件的流程
import Vue from "vue" import 插件 from "插件" Vue.use(插件)
32、列举3个vue中常用的生命周期钩子函数
created:实例已经创建完成之后调用,这里实例已经完成数据观测,属性和方法的运算,watch/event事件回调。挂载阶段还未开始,$el属性目前还不可见
mounted:el被创建的vm.$el替换,并挂载到实例上后调用该钩子。如果root实例挂载了一个文档内元素,当mounted调用时vm.$el也在文档内
activated:keep-alive组件激活时调用