关于Vue2中一些问题的简单补充或总结
1.data为什么必须是函数
这样子可以防止组件中的数据共享,防止数据污染问题。
当data是对象时候,如同时对某个组件实例多次使用,那多个组件实例会对同一对象引用,这会导致一个组件数据改变影响其他组件数据;
当data是函数时候,每个对象实例创建时候都会在堆中开辟出一块新的独立的空间用来存储数据,这样每个对象之间的数据就会做到互相不影响;
2.父子组件生命周期图
挂载: parent beforeCreate => parent created => parent beforeMount => child beforeCreate => child created => child beforeMount => child mounted => parent mounted
更新: parent beforeUpdate => child beforeUpdate=> child updated => parent updated
销毁: parent beforeDestroy=> child beforeDestroy => child destroyed => parent destroyed
3.多个组件有相同逻辑,如何抽离
vue2使用mixin对公共部分的逻辑进行抽离;vue3虽然也可以使用mixin,但推荐用hooks。
4.beforeDestroy里面可以做什么
- 解绑自定义事件
event.$off - 清除定时器
- 解绑自定义
dom事件,如windom.scroll等
5.Vue常见性能优化方式
- 合理使用
v-if和v-show - 合理使用
computed、watch v-for加key- 通知、
dom事件监听、定时器及时销毁 - 合理使用异步组件
- 合理使用
keepalive data层级不要太深- 第三方插件的按需引入
- 使用
vue-loader在开发环境做模板编译 - 前端通用性能优化(如图片懒加载/减少
HTTP请求数/合理设置HTTP缓存/资源合并与压缩/合并CSS图片/将CSS放在head中/避免重复的资源请求/切分到多个域名) - 使用服务端渲染或者预渲染
- …
6.解决非工程化项目初始化页面闪动问题
vue页面在加载的时候闪烁花括号{},v-cloak指令和css规则如[v-cloak]{display:none}一起用时,这个指令可以隐藏未编译的Mustache标签直到实例准备完毕。
7.Vue项目中怎么强制刷新页面
7.1 刷新整个页面
this.$router.go(0)
window.location.reload();
7.2 使用内置的this.$forceUpdate方法
注意:forceUpdate只会强制更新页面,不会更新现有的计算属性。
<template>
<div>
<button @click="handleUpdateClick()">Refresh当前组件</button>
</div>
</template>
export default {
methods: {
handleUpdateClick() {
// built-in
this.$forceUpdate()
}
}
}
7.3 使用key-changing
原理很简单,vue使用key标记组件身份,当key改变时就是释放原始组件,重新加载新的组件。
<template>
<div>
<Comps :key="componentKey"></Comps>
</div>
</template>
<script>
export default {
data() {
return {
componentKey: 0
}
},
methods: {
forceRerender() {
this.componentKey += 1 // 或者 this.componentKey = new Date();
}
}
}
</script>
7.4 使用v-if标记
<template>
<comp v-if="refresh"></comp>
<button @click="refreshComp()">刷新comp组件</button>
</template>
<script>
import comp from '@/views/comp.vue'
export default {
name: 'parentComp',
data() {
return {
refresh: true
}
},
methods: {
refreshComp() {
// 移除组件
this.refresh = false
// 在组件移除后,重新渲染组件
// this.$nextTick可实现在DOM 状态更新后,执行传入的方法。
this.$nextTick(() => {
this.refresh = true
})
}
}
}
</script>
8.说一下 Vue complier 的实现原理是什么样的
在使用 vue 的时候,我们有两种方式来创建我们的 HTML 页面,第一种情况,也是大多情况下,我们会使用模板 template 的方式,因为这更易读易懂也是官方推荐的方法;第二种情况是使用 render 函数来生成 HTML,它比 template 更接近最终结果。
complier 的主要作用是解析模板,生成渲染模板的 render, 而 render 的作用主要是为了生成 VNode
complier 主要分为 3 大块:
- parse:接受 template 原始模板,按着模板的节点和数据生成对应的 ast
- optimize:遍历 ast 的每一个节点,标记静态节点,这样就知道哪部分不会变化,于是在页面需要更新时,通过 diff 减少去对比这部分DOM,提升性能
- generate 把前两步生成完善的 ast,组成 render 字符串,然后将 render 字符串通过 new Function 的方式转换成渲染函数
9.组件中写 name 选项有哪些好处
- 可以通过名字找到对应的组件( 递归组件:组件自身调用自身 )
- 可以通过 name 属性实现缓存功能(keep-alive)
- 可以通过 name 来识别组件(跨级组件通信时非常重要)
- 使用 vue-devtools 调试工具里显示的组见名称是由 vue 中组件 name 决定的
10.Vue VS React
Vue和React在很多方面是相似的,但也存在一些关键区别。
相似之处
- 数据驱动视图:Vue和React都采用数据驱动视图的方式,这意味着它们通过数据的变化来更新视图,而不是直接操作DOM。这种方式减少了DOM的操作,提高了性能
- 组件化:两者都遵循组件化开发的思想,将页面拆分成多个小的组件,这些组件可以独立开发、测试和复用。组件之间可以通过props进行数据传递。
- 虚拟DOM:Vue和React都使用虚拟DOM来提高渲染效率。虚拟DOM是一个轻量级的JavaScript对象,用于表示真实的DOM结构。当数据变化时,虚拟DOM会重新生成,并通过Diff算法高效地更新真实的DOM。
- 响应式:两者都支持响应式开发,能够根据数据的变化自动更新视图。
不同之处
- 核心思想:Vue强调灵活易用,适合渐进式开发,支持双向数据绑定和组件的逐步引入。React则强调最佳实践,采用单向数据流,从顶部到底部的数据传递方式。
- 模板语法:Vue使用基于HTML的模板语法(如v-if、v-for等),而React使用JSX语法,将HTML直接写在JavaScript中。这种差异导致两者在开发体验上有所不同。
- 性能优化:Vue在Diff算法上进行了优化,通过双端比较来减少计算量,而React也在不断优化其Diff算法以提高性能。
- 适用场景:Vue适合小型项目和快速开发,而React由于其单向数据流和更好的可控性,更适合大型项目和复杂的应用开发。
11.说一下 Vue SSR的实现原理
SSR也就是服务端渲染,也就是将Vue在客户端把标签渲染成HTML的工作放在服务端完成,然后再把html直接返回给客户端。
SSR有着更好的SEO、并且首屏加载速度更快等优点。 不过它也有一些缺点,比如我们的开发条件会受到限制,服务器端渲染只支持beforeCreate和created两个钩子,当我们需要一些外部扩展库时需要特殊处理,服务端渲染应用程序也需要处于Node.js的运行环境。还有就是服务器会有更大的负载需求。
12.怎么重置vue中的data
有时候为了重置多个表单中的一些数据,使用重新加载页面显示又不友好,如果仅仅是为了重置页面的表单等数据,可以直接重置Vue中data对象:
this.$data:Vue 实例观察的数据对象this.$options.data()当前 Vue 实例的初始化data选项Object.assign(target, ...sources)object.assign()主要用于对象合并,将源对象中的属性复制到目标对象中,他将返回目标对象。有同名属性的话,后面的属性值会覆盖前面的属性值。
综上所述,可以使用下面方法:
Object.assign(this.$data, this.$options.data());
ps:如果你的vue实例的data方法里通过this引用了其他vue实例上的方法/属性等,需要改成下面这样,修复this指向问题导致的报错。
Object.assign(this.$data, this.$options.data.call(this));
下面是一个实例:
<template>
<div id="reset-data-area">
<div>{{ num }}</div>
<div>{{ a }}</div>
<div>{{ b }}</div>
<div>{{ c }}</div>
<button @click="increase">改变</button>
<button @click="reset">重置</button>
</div>
</template>
<script>
export default {
name: "test",
data() {
return {
num: 100,
a: 1,
b: 2,
c: 3,
}
},
methods: {
increase(){
this.num++;
this.a+=2;
this.b+=3;
this.c+=4;
},
reset() {
Object.assign(this.$data, this.$options.data());
}
}
}
</script>
<style scoped>
</style>


6万+

被折叠的 条评论
为什么被折叠?



