Comments (12)
使用 Object.defineProperty() 来进行数据劫持有什么缺点?
- 无法监听新增属性和删除属性: Object.defineProperty() 只能劫持已经存在的属性。
- 深度监听问题: 假如对象的属性值是对象或数组,那么需要递归地为每个嵌套属性添加 getter 和 setter。这会导致性能问题和复杂的代码维护。
- 性能开销: 由于 Object.defineProperty() 需要为每个属性创建一个 getter 和一个 setter,当属性较多时,会产生较大的性能开销。
- 无法监听数组索引和 length 属性: Object.defineProperty() 无法直接监听数组的索引和 length 属性的变化。 Vue 内部通过重写函数的方式解决了这个问题。
from dailyr-ecord.
组件通信
Vue组件之间的通信方式都有哪些?
- 父子关系的组件数据传递选择 props 与 emit进行传递,也可选择ref
- 兄弟关系的组件数据传递可选择eventBus ,其次可以选择$parent进行传递
- 祖先与后代组件数据传递可选择attrs与listeners或者 Provide与 Inject
- 复杂关系的组件数据传递可以通过vuex存放共享的变量
(1)父子组件间通信
● 子组件通过 props 属性来接受父组件的数据,然后父组件在子组件上注册监听事件,子组件通过 emit 触发事件来向父组件发送数据。
● 通过 ref 属性给子组件设置一个名字。父组件通过 $refs 组件名来获得子组件,子组件通过 $parent 获得父组件,这样也可以实现通信。
● 使用 provide/inject,在父组件中通过 provide提供变量,在子组件中通过 inject 来将变量注入到组件中。不论子组件有多深,只要调用了 inject 那么就可以注入 provide中的数据。
(2)兄弟组件间通信
● 使用 eventBus 的方法,它的本质是通过创建一个空的 Vue 实例来作为消息传递的对象,通信的组件引入这个实例,通信的组件通过在这个实例上监听和触发事件,来实现消息的传递。
● 通过 $parent/$refs 来获取到兄弟组件,也可以进行通信。
import Vue from 'vue';
export const eventBus = new Vue();
<!-- ComponentA.vue -->
<template>
<button @click="sendMessage">Send Message</button>
</template>
<script>
import { eventBus } from './EventBus.js';
export default {
methods: {
sendMessage() {
eventBus.$emit('message-sent', 'Hello from Component A');
}
}
};
</script>
<!-- ComponentB.vue -->
<template>
<div>{{ message }}</div>
</template>
<script>
import { eventBus } from './EventBus.js';
export default {
data() {
return {
message: ''
};
},
mounted() {
eventBus.$on('message-sent', message => {
this.message = message;
});
}
};
</script>
from dailyr-ecord.
Computed 和 Watch 的区别
对于Computed:
- 它支持缓存,只有依赖的数据发生了变化,才会重新计算
- 不支持异步,当Computed中有异步操作时,无法监听数据的变化
- 如果一个属性是由其他属性计算而来的,这个属性依赖其他的属性,一般会使用computed
- 如果computed属性的属性值是函数,那么默认使用get方法,函数的返回值就是属性的属性值;在computed中,属性有一个get方法和一个set方法,当数据发生变化时,会调用set方法。
对于Watch:
- 它不支持缓存,数据变化时,它就会触发相应的操作
- 支持异步监听
- 监听的函数接收两个参数,第一个参数是最新的值,第二个是变化之前的值
- 监听数据必须是data中声明的或者父组件传递过来的props中的数据,当发生变化时,会触发操作,函数有两个的参数:
- immediate:组件加载立即触发回调函数
- deep:深度监听,发现数据内部的变化,在复杂数据类型中使用,例如数组中的对象发生变化。需要注意的是,deep无法监听到数组和对象内部的变化。
当想要执行异步或者昂贵的操作以响应不断的变化时,就需要使用watch。
from dailyr-ecord.
Vue 中 key 值的作用是什么?
v-for 正在更新已渲染过的元素列表时,它默认用“就地复用”策略。如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序, 而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素。key 的作用主要是为了高效的更新虚拟 DOM。
为什么不建议用index作为key?
使用index 作为 key和没写基本上没区别,因为不管数组的顺序怎么颠倒,index 都是 0, 1, 2...这样排列,导致 Vue 会复用错误的旧子节点。
from dailyr-ecord.
如何对项目进行性能优化
- 使用路由懒加载组件
- 图片懒加载
- 很多时候我们需要将页面内未出现在可视区域内的图片先不做加载, 等到滚动到可视区域后再去加载
- 将引入的js文件放在body底部加载
- computed 和 watch 区分使用场景利用 computed 的缓存特性,避免每次获取值时,都要重新计算;当数据变化时执行异步或开销较大的操作时,应该使用 watch
- v-for 遍历添加唯一key值
- v-for 和 v-if避免同时使用 v-for优先级大于v-if 必要的情况下应该替换成 computed属性处理
- 第三方插件按需引入如果我们直接引入整个插件,会导致项目的体积太大,我们可以借助 babel-plugin-component
- 优化无限长列表使用虚拟滚动加载dom节点只加载可视区域
- webpack的优化资源文件进行压缩。对于很小的图标转化为base64格式提取公共代码提取第三方库不经常改动的库使用cdn加载方式
白屏优化
首页加 loading 或 骨架屏 (仅仅是优化体验)
如何对Vue 首屏加载实现优化?
1、把不常改变的库放到 index.html 中,通过 cdn 引入
2、Vue 路由的懒加载
3、不生成 map 文件
4、Vue 组件尽量不要全局引入
5、使用更轻量级的工具库
6、开启 gzip 压缩
7、首页单独做服务端渲染
from dailyr-ecord.
一般在哪个生命周期请求异步数据
我们可以在钩子函数 created、beforeMount、mounted 中进行调用,因为在这三个钩子函数中,data 已经创建,可以将服务端端返回的数据进行赋值。
from dailyr-ecord.
slot插槽有几种使用方式?
插槽(Slots)是用于在父组件中传递内容到子组件的机制,用于构建更具灵活性和可重用性的组件。
- 默认插槽:又名匿名查抄,当slot没有指定name属性值的时候一个默认显示插槽,一个组件内只有有一个匿名插槽。
- 具名插槽:带有具体名字的插槽,也就是带有name属性的slot,一个组件可以出现多个具名插槽。
- 作用域插槽:作用域插槽是一个高级特性,它允许子组件向父组件提供数据,从而在父组件中自定义插槽内容。通过作用域插槽,子组件可以将数据传递给父组件,然后父组件可以根据这些数据来渲染插槽内容。
<!-- 子组件 MyComponent.vue -->
<template>
<div>
<slot :item="item"></slot>
</div>
</template>
<script>
export default {
props: {
item: Object
}
}
</script>
<template>
<div>
<child-component :item="dataItem">
<template v-slot="slotProps">
<p>Item Name: {{ slotProps.item.name }}</p>
<p>Item Price: {{ slotProps.item.price }}</p>
</template>
</child-component>
</div>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: {
ChildComponent
},
data() {
return {
dataItem: {
name: 'Product A',
price: 50
}
};
}
}
</script>
from dailyr-ecord.
Vuex 有哪几种属性?
有五种,分别是State、Getter、Mutation 、Action、Module
state => 基本数据(数据源存放地)
getters => 从基本数据派生出来的数据
mutations => 提交更改数据的方法,同步
actions => 像一个装饰器,包裹mutations,使之可以异步。
modules => 模块化Vuex
computed:mapState, mapGetters,
methods:mapMutations, mapActions
from dailyr-ecord.
Vue 的路由实现模式:hash 模式和 history 模式
1)hash 模式:在浏览器中符号“#”,#以及#后面的字符称之为 hash,
用 window.location.hash 读取。特点:hash 虽然在 URL 中,但不被包括在HTTP请求中;用来指导浏览器动作,对服务端安全无用,hash 不会重加载页面。
2) history 模式:history 采用 HTML5 的新特性;且提供了两个新方法: pushState(), replaceState()可以对浏览器历史记录栈进行修改,以及popState 事件的监听到状态变更
编程式导航使用的方法以及常用的方法
路由跳转 : this.$router.push()
路由替换 : this.$router.replace()
后退: this.$router.back()
前进 :this.$router.forward()
from dailyr-ecord.
$nextTick 原理及作用
在 Vue.js 中,DOM 更新是异步的。如果你在数据修改后立即访问 DOM 元素,可能会得到之前的状态。这时就需要 $nextTick 来确保你在 DOM 更新后执行操作,以获取到最新的 DOM 状态。
当你调用 $nextTick(callback) 方法时,Vue.js 会将这个回调函数推入一个队列中。这个队列会在下一次 DOM 更新循环时执行,确保在更新后执行回调函数。
from dailyr-ecord.
vue3 常用api
响应式: 核心
ref: ref 函数用于创建一个响应式的数据引用,类似于 Vue 2 的 data 中的属性。它返回一个包装后的对象,使您可以通过 .value 访问和修改数据。
reactive: reactive 函数用于创建一个响应式对象,类似于 Vue 2 的 data 对象。与 ref 不同,reactive 可以用于创建包含多个属性的对象。
computed: computed 函数用于创建计算属性。与 Vue 2 中的计算属性类似,computed 计算属性会根据其依赖的响应式数据进行自动更新。
readOnly接受一个对象 (不论是响应式还是普通的) 或是一个 [ref],返回一个原值的只读代理。
watchEffect: watchEffect 函数会自动追踪其内部使用的响应式数据,并在其中的任何数据变化时执行回调函数。它不需要明确指定依赖,会自动收集使用的依赖。
watch: watch 函数用于侦听响应式数据的变化,并在变化时执行回调函数。它可以替代 Vue 2 的 watch 选项和 $watch 方法。
响应式: 工具
isRef()
unref()
toRef()
toValue()
toRefs()
isProxy()
isReactive()
isReadonly()
from dailyr-ecord.
vue3与vue2做了哪些优化
Vue3在编译阶段,做了进一步优化。
- diff算法优化 静态标记,会发生变化的地方添加一个flag标记,下次发生变化的时候直接比较
- 静态提升 对不参与更新的元素,会做静态提升,只会被创建一次,在渲染时直接复用
- 事件监听缓存 开启了缓存后,没有静态标记。也就是说下次diff算法的时候直接使用
源码体积相比Vue2,Vue3整体体积变小了,除了移出一些不常用的API
任何一个函数,如ref、reavtived、computed等,仅仅在用到的时候才打包,没用到的模块都被树摇掉,打包的整体体积变小
Object.defineProperty 只是 Vue 内部通过重写函数的方式解决了这个问题。
- 检测不到对象属性的添加和删除
- 数组API方法无法监听到
- 需要对每个属性进行遍历监听,如果嵌套对象,需要深层监听,造成性能问题
Proxy
vue3采用proxy重写了响应式系统,因为proxy可以对整个对象进行监听,所以不需要深度遍历
- 可以监听动态属性的添加
- 可以监听到数组的索引和数组length属性
- 可以监听删除属性
from dailyr-ecord.
Related Issues (9)
- 2022年8月8号学习记录
- vue3 基础知识
- ES6面试题汇总 HOT 17
- Vue3学习 HOT 9
- React学习记录 HOT 16
- angular 面试总结 HOT 13
- Css知识积累 HOT 1
- 常见http问题
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from dailyr-ecord.