1.v-if 与v-show(基础)
v-if
初始渲染
初始值为 false 组件不会渲染,生命周期钩子不会执行,v-if 的渲染是惰性的。
初始值为 true 时,组件会进行渲染,并依次执行 beforeCreate,created,beforeMount,mounted 钩子。
切换
false => true
依次执行 beforeCreate,created,beforeMount,mounted 钩子。
true => false
依次执行 beforeDestroy,destroyed 钩子
v-show
渲染
无论初始状态,组件都会渲染,依次执行 beforeCreate,created,beforeMount,mounted 钩子,v-show 的渲染是非惰性的。
切换
对生命周期钩子无影响,切换时组件始终保持在 mounted 钩子
2、Vue的双向数据绑定原理是什么?(中高级)
答:(vue2.0)
vue.js 是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。简要盖述:
第一步:需要observe的数据对象进行递归遍历,包括子属性对象的属性,都加上 setter和getter
这样的话,给这个对象的某个值赋值,就会触发setter,那么就能监听到了数据变化(递归遍历对象)
第二步:compile解析模板指令,将模板中的变量替换成数据,然后初始化渲染页面视图,并将每个指令对应的节点绑定更新函数,添加监听数据的订阅者,一旦数据有变动,收到通知,更新视图(解析指令,监听数据变化)
第三步:Watcher订阅者是Observer和Compile之间通信的桥梁,主要做的事情是:
1、在自身实例化时往属性订阅器(dep)里面添加自己
2、自身必须有一个update()方法
3、待属性变动dep.notice()通知时,能调用自身的update()方法,并触发Compile中绑定的回调,则功成身退。
第四步:MVVM作为数据绑定的入口,整合Observer、Compile和Watcher三者,通过Observer来监听自己的model数据变化,通过Compile来解析编译模板指令,最终利用Watcher搭起Observer和Compile之间的通信桥梁,达到数据变化 -> 视图更新;视图交互变化(input) -> 数据model变更的双向绑定效果。
实现代码:
<!-- 1.Vue2.x采用的数据双向绑定原理 -->
<input type="text" v-model>
<p v-bind></p>
<script>
// 1.获取行内属性[v-model]
let txt = document.querySelector('[v-model]');
// 2.input框实现输入值
txt.oninput = function(){
// 3.将获取到的值赋给obj.name
obj.name = txt.value;
}
let obj = {};
// 4.IE8以及以下浏览器不识别该用法,自带了get和set方法
// get的得到值变化,set是设置值的变化
Object.defineProperty(obj,'name', {
get(){
console.log('get被调用了');
},
// set自带一个参数
set(value){
console.log('set被调用了');
// 获取到p的属性
let p = document.querySelectorAll('[v-bind]')[0];
// 赋值
p.innerHTML = value;
}
});
// obj.name = 'summer'; // 触发了set
// console.log(obj.name); // 触发了get
</script>
(vue3.0)
Vue3.0实现数据的双向绑定原理:采用的是Proxy方法,proxy是个对象
实现代码:
<input type="text" v-model>
<p v-bind></p>
<script>
let txt = document.querySelector('[v-model]');
txt.oninput = function(){
p.obj = txt.value;
}
let obj = {};
let p = new Proxy(obj,{
// 1.目标对象
// 2.被获取的属性值
// 3.Proxy或继承Proxy
get(data, property, receiver){
// console.log('get被调用了');
},
// 1.目标对象
// 2.被获取的属性值
// 3.被获取的value值
// 4.最初被调用的对象Proxy
set(data, property, value, receiver){
// console.log('set被调用了');
let p = document.querySelectorAll('[v-bind]')[0];
p.innerHTML = value;
}
});
// p.name = 'summer'; // set被调用了
// console.log(p.name); // get被调用了
</script>
优势劣势:
3.proxy比Object.defineProperty好在哪里?
proxy优势:
A.可以直接监听对象而非属性
B.可以直接监听数组的变化
C.Proxy有多达13种拦截方式,不限于apply、ownKeys、deleteProperty、has等等是Object.defineProperty不具备的
D.Proxy返回的是一个新对象,可以只操作新的对象达到目的,而Object.defineProperty只能遍历对象属性直接修改
Object.defineProperty的优势:
A.兼容性好,支持IE9,而Proxy的存在浏览器兼容性问题,而且无法用polyfill磨平。
3. vue-router 有哪几种导航守卫?
1.全局守卫
2.路由独享守卫
3.路由组件内的守
4.组件之间的通信
1.父组件通过props向下传递数据给子组件。注:组件中的数据共有三种形式:data、props、computed
2.子组件通过events给父组件发送消息,实际上就是子组件把自己的数据发送到父组件。
3.
e
m
i
t
/
emit/
emit/on
这种方法通过一个空的Vue实例作为中央事件总线(事件中心),用它来触发事件和监听事件,巧妙而轻量地实现了任何组件间的通信,包括父子、兄弟、跨级
- $attrs/ $listeners(中高级)
attrs:包含了父作用域中不被prop所识别(且获取)的特性绑定(class和style除外)。当一个组件没有声明任何prop时,这里会包含所有父作用域的绑定(class和style除外),并且可以通过v−bind=“attrs” 传入内部组件。通常配合 interitAttrs 选项一起使用。
listeners:包含了父作用域中的(不含.native修饰器的)v−on事件监听器。它可以通过v−on=“listeners”包含了父作用域中的(不含.native修饰器的)v−on事件监听器。它可以通过v−on=“listeners” 传入内部组件
5.provide/inject
祖先组件中通过provider来提供变量,然后在子孙组件中通过inject来注入变量。provide / inject API 主要解决了跨级组件间的通信问题,不过它的使用场景,主要是子组件获取上级组件的状态,跨级组件间建立了一种主动提供与依赖注入的关系
5.简要介绍Vuex原理(j基础)
HTML页面上,负责接收用户操作等交互行为,执行dispatch方法触发对应action进行回应。
dispatch:操作行为触发方法,是唯一能执行action的方法。
actions:操作行为处理模块,由组件中的$store.dispatch(‘action 名称’, data1)来触发。然后由commit()来触发mutation的调用 , 间接更新 state。负责处理Vue Components接收到的所有交互行为。包含同步/异步操作,支持多个同名方法,按照注册的顺序依次触发。向后台API请求的操作就在这个模块中进行,包括触发其他action以及提交mutation的操作。该模块提供了Promise的封装,以支持action的链式触发。
commit:状态改变提交操作方法。对mutation进行提交,是唯一能执行mutation的方法。
mutations:状态改变操作方法,由actions中的commit(‘mutation 名称’)来触发。是Vuex修改state的唯一推荐方法。该方法只能进行同步操作,且方法名只能全局唯一。操作之中会有一些hook暴露出来,以进行state的监控等。
state:页面状态管理容器对象。集中存储Vue components中data对象的零散数据,全局唯一,以进行统一的状态管理。页面显示所需的数据从该对象中进行读取,利用Vue的细粒度数据响应机制来进行高效的状态更新。
getters:state对象读取方法。图中没有单独列出该模块,应该被包含在了render中,Vue Components通过该方法读取全局state对象。
6.watch与computed的区别(中级)
1、区别
watch中的函数是不需要调用的
computed内部的函数调用的时候不需要加()
watch 属性监听 监听属性的变化
computed:计算属性通过属性计算而得来的属性
computed 属性的结果会被缓存,除非依赖的响应式属性变化才会重新计算。主要当作属性来使用;
computed中的函数必须用return返回最终的结果
当computed中的函数所依赖的属性如果没有发生改变的时候,那么调用当前函数的时候结果会从缓存中读取
watch 一个对象,键是需要观察的表达式,值是对应回调函数。主要用来监听某些特定数据的变化,从而进行某些具体的业务逻辑操作
7.vue静态路由和静态路由的区别
定义:
静态路由:静态路由是在路由器中设置固定的路由表;除非网络管理员进行干预,否则静 态路由表不会发生变化。
动态路由:由网络中的路由器之间相互通信,传递路由信息,利用收到的路由信息更新路由表的路由方式。
使用场景:
静态路由:网络规模不大,拓扑结构固定的网络中。
动态路由:网络规模大,网络拓扑机构复杂的网络。
8.从a页面到b页面,会经过那些生命周期
之前一直以为先是index页面的beforeDestroy、destroyed生命周期函数执行完才会开始secondIndex页面的beforeCreate、created等,验证的事实是先新页面的beforeCreate、created、beforeMount,然后旧页面的beforeDestroy、destroyed,再然后新页面的mounted等
9.nextTick的作用
Vue 实现响应式并不是数据发生变化之后 DOM 立即变化,而是按一定的策略进行 DOM 的更新。
$nextTick 是在下次 DOM 更新循环结束之后执行延迟回调,在修改数据之后使用 $nextTick,则可以在回调中获取更新后的 DOM
10.页面切换
- 1.跳转:$router.go(-1)
- 2.后退:$router.back()
- 3.前进:$router.forward()
- 4.新加历史记录切换页面:$router.push()
- 5.替换当前页面(不留历史记录):$router.replace()