Vue 面试
MVVM
Model-View-ViewModel.
Model是数据, View是页面, ViewModel: 是视图模型, 这是数据驱动的核心.
当Model发生改变, 通知ViewModel, 对视图模型进行更新. 进一步修改View页面.
当用户操作View, 导致ViewModel发生改变, 也能即时通知Model更改数据.
双向数据绑定
数据劫持
observer
watcher
发布订阅模式
v-if, v-show 的区别
v-if判断后面的条件值真假切换的时候, 控制元素在DOM树中的存在与否. 如果初始值为假, 不编译, 不渲染.
v-show控制元素的display属性, 为显示或者隐藏.
如果频繁的切换显示隐藏, 使用v-show. 条件渲染使用v-if.
css 只在当前组件之内生效
<style scoped lang="sass">
*{margin: 0}
</style>
vue 组件的生命周期
四个阶段:
创建前后: beforeCreate / created
-
beforeCreate之前, 初始化数据, 事件, 声明周期函数 -
beforeCreate之后,created之前,data, methods都已经创建好, 可以读取. 实现数据劫持, 添加事件发射, 事件监听.
初始化工作完成.
挂载前后: beforeMount / mounted
-
beforeMount, 检查el:'#app'和template. 将template放进render函数中进行编译.虚拟DOM已经创建 -
mouned, 将Vue实例挂载到#app元素上
更新前后: beforeUpdate / updated
-
beforeUpdate, 即将完成更新操作, 在这里比对数据是否发生改变, 此生命周期钩子默认返回true. 如果返回false, 将不会触发更新. -
updated, 得到beforeUpdate的肯定回复, 完成了更新操作
销毁前后: beforeDestroy / destoryed
-
beforeDestroy, 组件将要销毁, 解绑事件, 定时器, 清除依赖, 子组件 -
destroyed, 组件完成销毁
如果考虑 keep-alive, 将会存在组件的激活和失活, 必须将组件放在keep-alive标签中, 不会渲染成html标签
<keep-alive>
<component v-bind:is="currentTabComponent"></component>
</keep-alive>
在组件的生命周期钩子中, 可以新增一个activated和deactivated.
分别在组件激活和失活的时候触发.
父子组件传值
父传子: 在子组件的标签上绑定
<div class="father">
<child :value="100"></child>
</div>
子组件通过 props 获取
子传父:
触发父组件绑定在自己身上的事件, 将需要传递的值作为参数传递给这个事件处理函数
methods, computed, watch
methods: 只要某个函数依赖的值发生改变, 里面所有的方法都会执行一次. 事件处理函数一般写在这里
computed: 基于methods的性能, 所以如果某个值是计算出来的, 那将这个值放在这里再适合不过了.
watch:
watch: {
key(new, old){
// code
}
}
如果 key 这个值发生了改变, 会立即出发这个函数, 执行里面的代码
循环中, key 的作用?
便于diff算法比对, 根据key的值, 能更精确的计算出那些东西是真正需要更新的, 能省去大部分不必要的DOM更新操作.
异步更新队列
Vue的数据更新是异步的, 当侦听器发现某个属性发生改变, Vue就会开启一个队列, 在一个事件循环中, 所有的属性如果被改变, 都会被push进这个队列, 在事件循环结束的时候, 执行更新任务并清空队列. 如果一个watcher 被触发多次, 只有最新的一次会被放进事件队列.
vue 对比 react
相同之处:
- 都使用 Virtual DOM
- 提供响应式和组件化
- 专注于核心, 将路由, 状态管理都交给其他的库
react 当某个组件的内容有更新, 将会以这个组件为根, 渲染这个组件之下的所有子组件, 如果希望避免不必要的更新, 那么需要手动实现shouldComponentUpdate方法
vue中, 组件的依赖是在渲染过程中自动追踪的,所以系统能精确知晓哪个组件确实需要被重渲染.
react中,jsx就是一切, html, css 都希望纳入到 javascript 中进行处理. 甚至一堆HTML标签组成的dom元素可以是一个变量, 可以随意使用.
vue则是更贴近传统的web开发, 从组件的模板就可以看出, 依旧是 html, css, js三板斧
<template>
<div id="main">
</div>
</template>
<script>
export default {
}
</script>
<style>
*{}
</style>
vue提供了render函数, 甚至也支持jsx语法, 但是推荐还是使用 vue模板毕竟更快, 更契合vue
react的路由react-router, 状态管理redux, 都是由其社区维护的, react的社区比vue更加繁荣
vue的vue-router, vuex都是由官方提供的. 社区方面相对来说没有 react 繁荣
react在原生方面 react-native 更加强大和成熟
vue 的 weex 也正在逐步发展, 而且也是有世界上最大的电商服务需求在驱动, 同样也在蓬勃发展.
hash 模式和 history 模式的区别?
hash 模式依赖 window.onhashchange 事件, 每次触发此事件, 都将被浏览器记录, 于是前进后退就可以使用history.go(), history.back(), history.forward(), 当hash值发生改变, 不会触发网络请求, 刷新页面. 注意, hash的底层是用history实现的.
history 利用了HTML5 History Interface中新增的 pushState() 和 replaceState()方法。(需要特定浏览器支持)
这两个方法应用于浏览器的历史记录栈,在当前已有的 back、forward、go 的基础之上,它们提供了对历史记录进行修改的功能。只是当它们执行修改时,虽然改变了当前的 URL,但浏览器不会立即向后端发送请求。
图截至
segmentfault的 Julian回答: https://segmentfault.com/q/1010000010340823/a-1020000010344787
查看14道真题和解析
