Vue2和Vue3的双向数据绑定的原理
Vue2
的核心就是通过Object.defineProperty()方法设置set和get函数来实现数据的劫持
Vue3
的核心是使用new Proxy(对象,{get(),set()})方法来给对象的属性添加get/set方法实现的!
1.vue组件引用方式,插件引用方式
2.vue为什么在v-for中的键不推荐使用随机数或者索引呢?那要怎么使用才比较好呢?**
key的作用主要是为了高效地更新虚拟DOM,使用key来给每一个例程做一个唯一的标识;差异算法可以正确的识别此后的解码器,找到正确的位置进行异步进行操作;
在绑定键的时候,最好是一个唯一的值,如item.id而不能是简单的index;在插入数据或删除数据的时候,会导致后面的数据的键绑定的索引变化,长靴导致重新渲染,效率会降低;
3.怎么给vue定义全局的方法?**
第一种:挂载到Vue的prototype上。把全局方法写到一个文件里面,然后for循环挂载到Vue的prototype上,缺点是调用这个方法的时候没有提示
Object.keys(tools).forEach(key => {
Vue.prototype[key] = tools[key]
})
第二种:利用全局混入mixin,因为mixin里面的methods会和创建的每个单文件组件合并。这样做的优点是调用这个方法的时候有提示
Vue.mixin(mixin)
new Vue({
store,
router,
render: h => h(App),
}).$mount('#app')
import tools from "./tools"
import filters from "./filters"
import Config from '../config'
import CONSTANT from './const_var'
export default {
data() {
return {
CONFIG: Config,
CONSTANT: CONSTANT
}
},
methods: {
// //将tools里面的方法挂载到vue上,以方便调用,直接this.$xxx方法名就可以了
// Object.keys(tools).forEach(key => {
// Vue.prototype[key] = tools[key]
// })
//将tools里面的方法用对象展开符混入到mixin上,以方便调用,直接this.$xxx方法名就可以了
...tools
},
filters: {
// //将filter里面的方法添加了vue的筛选器上
// Object.keys(filters).forEach(key => {
// Vue.filter(key, filters[key])
// })
...filters
}
}
4.跟keep-alive有关的生命周期是哪些?描述下这些生命周期 ?**
1.activated: 页面第一次进入的时候,钩子触发的顺序是created->mounted->activated
2.deactivated: 页面退出的时候会触发deactivated,当再次前进或者后退的时候只触发activated
5.v-once的使用场景有什么?**
v-once只渲染元素和组件一次。随后的重新渲染,元素/组件及其所有的子例程将被视为静态内容并跳过。这可以用于优化更新性能。
单次触发的场景 :表单提交。可防止用户在请求未及时响应时,多次提交〜
6.怎么访问到子组件的实例或子元素?**
this.$children / this.$refs.xxx
7.vue组件里的定时器要怎么销毁?**
const timer = setInterval(() =>{
// 某些定时器操作
}, 500);
// 通过$once来监听定时器,在beforeDestroy钩子可以被清除。
this.$once('hook:beforeDestroy', () => {
clearInterval(timer);
})
8.vue组件会在什么时候下被销毁?**
页面关闭,路由重定向,v-if和更改键值
9.组件中写name选项有什么作用?**
项目使用keep-alive时,可搭配组件name进行缓存过滤
DOM做递归组件时需要调用自身name
vue-devtools调试工具里显示的组见名称是由vue中组件name决定的
10.prop验证的type类型有哪几种?**
type 可以是下列原生构造函数中的一个:
8种:字符串,数字,布尔值,数组,对象,日期,函数,符号,自定义构造函数
String、Number、Boolean、Array、Object、Date、Function、Symbol
11.prop是怎么做验证的?可以设置默认值吗?**
单个类型就用Number等基础类型,多个类型用数组,必填的话设置require为true,默认值的话设置default,对象和数组设置默认用工厂函数,自定义验证函数validator。
12.说说你对单向数据流和双向数据流的理解**
单向数据流:所有状态的改变可记录,可跟踪,源头易转换;所有数据只有一个,组件数据只有唯一的入口和出口,从而使程序更直观更容易理解,有利于应用的可维护性;一旦数据变化,就去更新页面(data-页面),但是没有(页面-data);如果用户在页面上做了变动,那么就手动收集起来(双向是自动),合并到内置的数据中。
双向数据流:无论数据改变,或是用户操作,都能带来互相的移位,自动更新。
模仿就是:父传子的props就是单向数据流,v-model就是双向数据流
13.写出你知道的表单修饰符和事件修饰符**
事件修饰符.stop .prevent .capture .self .once .passive
表单修饰符.number .lazy .trim
// 表单修饰符
.lazy - 我们输入完所有东西,光标离开才更新视图
.trim - 过滤首尾空格
.number - 自动将用户的输入值转为数值类型,如果你先输入数字,那它就会限制你输入的只能是数字。如果你先输入字符串,那它就相当于没有加.number
// 事件修饰符 (尽管我们可以在方法中轻松实现相关处理,但更好的方式是:方法只有纯粹的数据逻辑,而不是去处理 DOM 事件细节。)
.stop - 调用 event.stopPropagation(), 阻止事件冒泡(不触发父级事件)。
.prevent - 调用 event.preventDefault(), 阻止默认行为,比如点击链接会进行跳转;填写表单时按回车会自动提交到服务器;点击鼠标右键会呼出浏览器右键菜单。
.capture - 添加事件侦听器时使用 capture 模式。事件触发从包含这个元素的顶层开始往下触发,即内部元素触发的事件先在此处理,然后才交由内部元素进行处理。完整的事件机制是:捕获阶段--目标阶段--冒泡阶段
.self - 只当事件是从侦听器绑定的元素本身触发时才触发回调。
.native - 监听组件根元素的原生事件。把一个vue组件转化为一个普通的HTML标签。
.once - 只触发一次回调。
.passive - { passive: true } 模式添加侦听器。当我们在监听元素滚动事件的时候,会一直触发onscroll事件,在pc端是没啥问题的,但是在移动端,会让我们的网页变卡,因此我们使用这个修饰符的时候,相当于给onscroll事件整了一个.lazy修饰符。
// 鼠标按键修饰符
.left - (2.2.0) 只当点击鼠标左键时触发。
.right - (2.2.0) 只当点击鼠标右键时触发。
.middle - (2.2.0) 只当点击鼠标中键时触发。
// 键值修饰符
.keyCode - 只当事件是从特定键触发时才触发回调。
.exact - 只需要或者只能按一个系统修饰键来触发。
// 其他修饰符
.sync - 父子组件进行双向数据绑定,会扩展成一个更新父组件绑定值的 v-on 侦听器。
.camel - HTML 特性是不区分大小写的,该修饰符使属性被渲染为驼峰名
.prop - 作为一个 DOM property 绑定而不是作为 attribute 绑定。(差别在哪里?)
vue怎么获取DOM节点?**
1、document.getElementById("id")
2、this.$refs.xx
vue生命周期总共有几个阶段?**
beforeCreate:在 new 一个 vue 实例后,只有一些默认的生命周期钩子和默认事件,其他的东西都还没创建。
created:data 和 methods 都已经被初始化好了。(如果要调用 methods 中的方法,或者操作 data 中的数据,最早可以在这个阶段中操作)
beforeMount:在内存中已经编译好了模板了,但是还没有挂载到页面中,此时,页面还是旧的。
mounted:Vue 实例已经初始化完成了。此时组件脱离了创建阶段,进入到了运行阶段。 (如果我们想要通过插件操作页面上的 DOM 节点,最早可以在和这个阶段中进行)
beforeUpdate:页面中的显示的数据还是旧的,data 中的数据是更新后的, 页面还没有和最新的数据保持同步。
updated:页面显示的数据和 data 中的数据已经保持同步了,都是最新的。
beforeDestroy:Vue 实例从运行阶段进入到了销毁阶段,这个时候上所有的 data 和 methods , 指令, 过滤器 ……都是处于可用状态。还没有真正被销毁。
destroyed:这个时候上所有的 data 和 methods , 指令, 过滤器 ……都是处于不可用状态。组件已经被销毁了。
组件和插件有什么区别?
组件 (Component) 是用来构成你的 App 的业务模块,它的目标是 App.vue。
插件 (Plugin) 是用来增强你的技术栈的功能模块,它的目标是 Vue 本身。
删除数组用delete和Vue.delete有什么区别?**
delete:只是被删除数组成员变为 empty / undefined,其他元素键值不变
Vue.delete:直接删了数组成员,并改变了数组的键值(对象是响应式的,确保删除能触发更新视图,这个方法主要用于避开 Vue 不能检测到属性被删除的限制)
watch怎么深度监听对象变化**
immediate设置为true就可以监听开始之后立即被调用
deep设置为true 就可以监听到对象的变化
let vm=new Vue({
el:"#first",
data:{msg:{name:'北京'}},
watch:{
msg:{
handler (newMsg,oldMsg){
console.log(newMsg);
},
immediate:true,
deep:true
}
}
})
watch和computed有什么区别?
1.一个是侦听属性,一个是计算属性
2.一个是为了应对复杂的逻辑计算,一个是对数据的变化作出反应
3.一个是只有当缓存改变时才执行,一个是只要从新渲染就会执行
4.一个有缓存,一个没有缓存
watch可以深度监听复杂对象的变化;
computed只能监听简单简单对象的变化
能不用watch就不用watch, watch一般用在你要监听的属性与你要使用的属性没有太多关联的时候,一般在异步时使用
vue组件之间的通信都有哪些?
父子
props
$emit/$on
( $parents/$children ) / $refs
兄弟
Vuex
Bus
跨级
Vuex
Bus
( provide/inject )
( $attrs/$listeners )
在vue组件中怎么获取到当前的路由信息?
this.$route.path 或者 this.$router
route和router有什么区别?
route:代表当前路由信息对象,可以获取到当前路由的信息参数
router:代表路由实例的对象,包含了路由的跳转方法,钩子函数等
vue-router钩子函数有哪些?都有哪些参数?
1.全局:
前置守卫:beforeEach((to, from, next)=>{
to:即将进入的路由对象
form:当前导航正要离开的路由
next():进行管道中的下一个钩子
})
解析守卫:beforeResolve((to, from, next)=>{})
后置钩子:afterEach((to,form)=>{})
路由:beforeEnter((to, from, next)=>{})
组件:
beforeRouteEnter (to, from, next) {
// 在渲染该组件的对应路由被 confirm 前调用
// 不!能!获取组件实例 this
// 因为当守卫执行前,组件实例还没被创建
},
beforeRouteUpdate (to, from, next) {
// 在当前路由改变,但是该组件被复用时调用
// 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
// 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
// 可以访问组件实例 this
},
beforeRouteLeave (to, from, next) {
// 导航离开该组件的对应路由时调用
// 可以访问组件实例 this
}
有用过vuex吗?它主要解决的是什么问题?推荐在哪些场景用?
多个视图依赖同一个状态
来自不同视图的行为需要变更同一状态
适用于中大型的单页面应用
我主要还是当全局变量来用的,比如登录人信息、token、浏览记录、跨组件的较大临时数据传递。
以往需要调个方法取全局变量或缓存,其实反而增加了初始化流程,而会自动更新的 vuex 就很好用了。
vuex的store有几个属性值?分别讲讲它们的作用是什么?
state:存贮公共数据的地方
Getters:获取公共数据的地方,获取根据业务场景处理返回的数据
mutations:放的是同步的操作和reducer有点像 通过store的commit方法来让mutations执行;唯一修改state的方法,修改过程是同步的
action:放的是异步的操作 通过分发操作触发mutation
context是store的一个副本
module 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割
Vuex就是提供一个仓库,store仓库里面放了很多对象其中state即使数据源存放地,
vuex中actions和mutations有什么区别?
actions:主要用来处理异步,提交的是mutations,在组件中用dispatch()派发
mutations:用来直接修改state的在组件中用this.$store.commit()触发
其两个都可以用辅助函数mapActions
作者:lucky婧
链接:https://www.jianshu.com/p/6e52005e7d6d
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。