mounted(vue2)
在Vue 2的组件中,mounted钩子用于执行那些需要在组件实例挂载到DOM之后运行的代码,这通常包括DOM操作、数据请求等
onMounted(vue3)
Vue 2:使用mounted作为组件的一个选项来执行挂载后的代码。
Vue 3:使用onMounted作为Composition API的钩子来执行挂载后的代码。
在Vue3中,onMounted是Composition API的一部分,它提供了更灵活的方式来组织组件的逻辑。
Vue3的onMounted与Vue 2的mounted在功能上相似,都是在组件挂载完成后执行,
但onMounted作为Composition API的一部分,可以更好地与其它Composition API一起使用,提供更细粒度的控制和更好的组合性。
如果你需要执行一次性的副作用(side effect),onMounted 是一个理想的地方。
"副作用"(side effect)是指函数在执行时除了返回值之外对外部环境产生的影响。这些影响可能包括但不限于:
修改全局变量:改变在函数外部定义的变量的值。
执行I/O操作:如读写文件、网络请求、控制台日志输出等。
修改外部对象或数组:影响传入函数的参数对象或数组的状态。
触发事件:如点击事件、网络事件等。
定时器设置:设置 setTimeout 或 setInterval。
并行执行多个异步操作
onMounted 也常用于执行并行异步操作,也可以发起网络请求。但据我实际使用的经历来看,异步操作能在首屏加载、大量图片等资源加载时发挥不错的作用。
import { ref, onMounted } from 'vue';
import axios from 'axios';
export default {
setup() {
// 声明响应式数据引用
const data = ref(null);
const data2 = ref(null);
const data3 = ref(null);
const data4 = ref(null);
onMounted(async () => {
// 使用Promise.all来处理并发的axios请求
await Promise.all([
axios.get('https://api.example.com/data'),
axios.get('https://api.example.com/data2'),
axios.get('https://api.example.com/data3'),
axios.get('https://api.example.com/data4')
]).then(responses => {
// 所有请求成功完成后,更新响应式数据
data.value = responses[0].data;
data2.value = responses[1].data;
data3.value = responses[2].data;
data4.value = responses[3].data;
// 这里可以放置所有异步任务完成后的代码...
}).catch(error => {
// 处理请求中出现的任何错误
console.error('请求错误:', error);
});
});
// 返回响应式状态供模板或其他Composition API使用
return {
data,
data2,
data3,
data4
};
}
};
reactive
eactive 是一个函数,用于将一个普通的 JavaScript 对象转换为响应式对象
当对象的属性发生变化时,Vue 会自动追踪这些变化,并触发相应的更新
响应式数据绑定:Vue 3 通过 reactive 实现了更高效的响应式系统
组合式 API:相比于 Vue 2 的选项式 API,组合式 API 提供了更好的逻辑复用和代码组织方式
更细粒度的 reactivity:通过 reactive,可以实现更细粒度的响应式数据追踪
import { reactive } from 'vue';
const state = reactive({
message: 'Hello Vue 3!'
});
console.log(state.message); // 输出: Hello Vue 3!
state.message = 'Hello World!';
console.log(state.message); // 输出: Hello World!
Pinia
Vue3 Pinia是一个基于Vue3的状态管理库,它提供了一种简单、直观的方式来管理应用程序的状态。
3.0 要创建一个store,你需要使用Pinia提供的defineStore函数。首先,确保你已经在Vue应用中安装并配置了Pinia。
// main.js
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'
const app = createApp(App)
const pinia = createPinia()
app.use(pinia)
app.mount('#app')
3.1 创建一个store
在使用Vue3 Pinia之前,我们需要先创建一个store。一个store是一个包含应用程序状态的对象。我们可以使用defineStore函数来创建一个store。
import { defineStore } from 'pinia'
export const useCounterStore = defineStore({
id: 'counter',
state: () => ({ // 在store中定义state,可以将它看作是组件的data选项。state是一个函数,返回一个对象,这个对象包含你的状态
count: 0
}),
getters: { //getters是store的计算属性,用来派生出一些状态 比如例子里*2
getCount: (state) => state.count * 2 // 获取count *2
},
actions: { // actions是用来执行状态更改的函数,可以是同步的,也可以是异步的
increment() {
this.count++
}
}
})
在上面的代码中,我们使用defineStore函数来创建一个名为useCounterStore的store。id属性是store的唯一标识符。
state属性是一个函数,它返回一个包含应用程序状态的对象。actions属性是一个包含store操作的对象。
在这个例子中,我们定义了一个名为increment的操作,它将count属性增加1。
3.2 在组件中使用store
import { useCounterStore } from './store'
export default {
setup() {
const counterStore = useCounterStore()
return {
counterStore
}
}
}
在上面的代码中,我们使用useCounterStore函数来获取useCounterStore的实例。我们可以将它存储在组件的setup函数中,并将它返回给模板。
现在我们可以在模板中使用store的状态和操作。
Count: {{ counterStore.count }}
在上面的代码中,我们使用counterStore.count来获取count属性的值,并使用counterStore.increment()来调用increment操作。
3.3 在组件之间共享store
在某些情况下,我们可能需要在多个组件之间共享store。为了实现这一点,我们可以使用createPinia函数来创建一个全局的store实例。
import { createPinia } from 'pinia'
const pinia = createPinia()
export default pinia
在上面的代码中,我们使用createPinia函数来创建一个全局的store实例,并将它导出。现在我们可以在多个组件中使用这个store。
import { useStore } from 'pinia'
import pinia from './pinia'
export default {
setup() {
const counterStore = useStore(pinia)
return {
counterStore
}
}
}
在上面的代码中,我们使用useStore函数来获取全局store实例的实例。我们将pinia作为参数传递给useStore函数。
defineProps
defineProps是Vue3中的一种新的组件数据传递方式,可以用于在子组件中定义接收哪些父组件的props。当父组件的props发生变化时,子组件也会随之响应
vue-router
请求并发 Promise.all、Promise.allSettled
一个并发控制的优化方案
const urls = [
'https://jsonplaceholder.typicode.com/posts/1',
'https://jsonplaceholder.typicode.com/posts/2',
'https://jsonplaceholder.typicode.com/posts/3',
// ... 更多 URL
];
function limitConcurrency(urls, limit) {
const results = [];
const executing = [];
async function enqueue() {
if (urls.length === 0) return Promise.resolve();
const url = urls.shift();
const promise = request(url).then(response => response.json());
results.push(promise);
const e = promise.then(() => executing.splice(executing.indexOf(e), 1));
executing.push(e);
let r = Promise.resolve();
if (executing.length >= limit) {
r = Promise.race(executing);
}
await r;
return enqueue();
}
return enqueue().then(() => Promise.all(results));
}
limitConcurrency(urls, 2)
.then(results => {
console.log('所有请求完成:', results);
})
.catch(error => {
console.error('请求失败:', error);
});