红宝书第四十一讲:关于Vue3的入门解读和与Vue2的区别
资料取自《JavaScript高级程序设计(第5版)》。
查看总目录:红宝书学习大纲
1. 什么是Vue3?
Vue3是一个用于构建用户界面的渐进式框架。它和Vue2类似,但进行了很多改进,比如更快的速度、更小的体积和更灵活的代码组织方式。
2. 如何安装Vue3?
你可以通过以下命令安装Vue3:
npm install vue@next
或者使用CDN:
<script src="https://unpkg.com/vue@next"></script>
3. 创建一个简单的Vue3应用
下面是一个简单的Vue3应用示例:
<div id="app">
<h1>{{ message }}</h1>
<button @click="changeMessage">点击我</button>
</div>
<script>
import { createApp, ref } from 'vue';
createApp({
setup() {
const message = ref('Hello, Vue3!');
const changeMessage = () => {
message.value = '消息已更改!';
};
return { message, changeMessage };
}
}).mount('#app');
</script>
createApp
是Vue3中用来创建应用实例的函数。ref
是用来定义响应式数据的函数,message.value
是获取和修改响应式数据的方式。
4. 组合式API(Composition API)
Vue3新增了组合式API,它通过setup
函数来组织代码。比如上面的代码中,setup
函数中定义了message
和changeMessage
,它们可以被模板直接使用。
5. 响应式系统
Vue3使用Proxy
来实现响应式系统,这比Vue2的Object.defineProperty
更强大,可以监听对象属性的动态添加和删除。
Vue3和Vue2的区别
特性 | Vue2 | Vue3 |
---|---|---|
响应式系统 | 使用Object.defineProperty ,无法监听对象属性的动态添加或删除 | 使用Proxy ,可以监听动态变化 |
API风格 | 选项式API(Options API),逻辑分散在data 、methods 等选项中 | 组合式API(Composition API),逻辑更集中,便于复用 |
性能 | 性能较好 | 性能大幅提升,虚拟DOM优化,打包体积更小 |
生命周期钩子 | beforeCreate 、created 、mounted 等 | setup 替代beforeCreate 和created ,其他钩子名前加on |
多根节点支持 | 不支持,必须有一个根节点 | 支持多根节点 |
TypeScript支持 | 需借助插件,原生支持较弱 | 完全用TypeScript重写,支持更好 |
全局API | new Vue() 创建实例,全局配置影响所有实例 | 使用createApp() 创建隔离实例,全局API改为实例方法 |
过滤器 | 支持 | 移除,推荐用计算属性或方法替代 |
案例对比
响应式数据
Vue2:
new Vue({ data() { return { message: 'Hello, Vue2!' }; } });
Vue3:
import { ref } from 'vue'; const message = ref('Hello, Vue3!');
在Vue3中,需要使用
ref
来定义响应式数据。
生命周期钩子
Vue2:
new Vue({ created() { console.log('组件创建完成'); } });
Vue3:
import { onMounted } from 'vue'; onMounted(() => { console.log('组件挂载完成'); });
Vue3中生命周期钩子名前加
on
,且需要在setup
中使用。
多根节点
Vue2:
<template> <div> <header></header> <main></main> <footer></footer> </div> </template>
Vue3:
<template> <header></header> <main></main> <footer></footer> </template>
Vue3支持多根节点,不需要额外的包裹元素。
Vue3常用生命周期钩子表格
钩子名称 | 触发时机 | 用途 |
---|---|---|
setup | 组件初始化时,替代beforeCreate 和created | 定义响应式数据、计算属性、方法 |
onBeforeMount | 组件挂载到DOM之前 | 执行挂载前的准备工作 |
onMounted | 组件挂载到DOM之后 | 访问DOM、发起网络请求、添加事件监听 |
onBeforeUpdate | 数据更新导致DOM更新之前 | 获取更新前的DOM状态 |
onUpdated | 数据更新导致DOM更新之后 | 访问更新后的DOM状态 |
onBeforeUnmount | 组件卸载之前 | 执行清理工作,如取消事件监听 |
onUnmounted | 组件卸载之后 | 执行卸载后的清理工作 |
onActivated | <keep-alive> 组件被激活时 | 激活缓存组件 |
onDeactivated | <keep-alive> 组件被停用时 | 停用缓存组件 |
onErrorCaptured | 组件内部捕获错误时 | 处理组件错误 |
Vue3生命周期钩子案例
1. setup
import { ref } from 'vue';
export default {
setup() {
const count = ref(0);
const increment = () => count.value++;
return { count, increment };
}
};
- 用途:在组件初始化时定义响应式数据和方法。
2. onMounted
import { ref, onMounted } from 'vue';
export default {
setup() {
const count = ref(0);
onMounted(() => {
console.log('组件已挂载');
// 操作DOM或发起网络请求
});
return { count };
}
};
- 用途:在组件挂载到DOM后执行,适合操作DOM或发起网络请求。
3. onUpdated
import { ref, onUpdated } from 'vue';
export default {
setup() {
const count = ref(0);
onUpdated(() => {
console.log('组件已更新');
// 注意避免在此修改响应式数据,以免造成无限循环
});
return { count };
}
};
- 用途:在组件更新后执行,适合访问更新后的DOM。
4. onUnmounted
import { ref, onUnmounted } from 'vue';
export default {
setup() {
const count = ref(0);
let timer = setInterval(() => {
count.value++;
}, 1000);
onUnmounted(() => {
console.log('组件已卸载');
clearInterval(timer); // 清除定时器
});
return { count };
}
};
- 用途:在组件卸载后执行,适合清理资源。
5. onActivated
和 onDeactivated
import { ref, onActivated, onDeactivated } from 'vue';
export default {
setup() {
const count = ref(0);
onActivated(() => {
console.log('组件被激活');
});
onDeactivated(() => {
console.log('组件被停用');
});
return { count };
}
};
- 用途:在
<keep-alive>
组件被激活或停用时执行。
Vue3常用Composition API表格列举
API名称 | 用途 | 示例 |
---|---|---|
ref | 创建一个响应式的基本类型数据 | const count = ref(0) |
reactive | 创建一个响应式的对象或数组 | const state = reactive({ name: '张三', age: 25 }) |
computed | 创建一个计算属性,基于其他响应式数据自动更新 | const doubleCount = computed(() => count.value * 2) |
watch | 监听响应式数据的变化,并在变化时执行回调 | watch(count, (newVal, oldVal) => { console.log( count 从 ${oldVal} 变为 ${newVal}) }) |
watchEffect | 自动运行一个副作用函数,并在依赖的响应式数据变化时重新运行 | watchEffect(() => console.log(count.value)) |
toRefs | 将响应式对象的属性转换为响应式的引用,便于在模板中直接使用 | const { name, age } = toRefs(state) |
provide /inject | 实现祖孙组件间的通信 | provide(ThemeSymbol, themeRef) 和 inject(ThemeSymbol) |
defineProps /defineEmits | 声明组件的props 和emits ,用于类型检查和代码提示 | defineProps(['modelValue']) 和 defineEmits(['update:modelValue']) |
Vue3 Composition API案例列举
1. 基础响应式数据
import { ref, reactive } from 'vue';
export default {
setup() {
const count = ref(0); // 基本类型响应式数据
const user = reactive({ name: '张三', age: 25 }); // 对象类型响应式数据
return { count, user };
}
};
- 用途:定义响应式数据,用于模板渲染。
2. 计算属性
import { ref, computed } from 'vue';
export default {
setup() {
const count = ref(0);
const doubleCount = computed(() => count.value * 2);
return { count, doubleCount };
}
};
- 用途:基于响应式数据计算派生值。
3. 监听数据变化
import { ref, watch } from 'vue';
export default {
setup() {
const count = ref(0);
watch(count, (newVal, oldVal) => {
console.log(`count 从 ${oldVal} 变为 ${newVal}`);
});
return { count };
}
};
- 用途:监听响应式数据的变化并执行回调。
4. 自动运行副作用
import { ref, watchEffect } from 'vue';
export default {
setup() {
const count = ref(0);
watchEffect(() => {
console.log(`当前 count 值为 ${count.value}`);
});
return { count };
}
};
- 用途:自动运行副作用函数,并在依赖的响应式数据变化时重新运行。
5. 提供和注入
// 父组件
import { provide, ref } from 'vue';
export default {
setup() {
const theme = ref('dark');
provide('theme', theme);
return { theme };
}
};
// 子组件
import { inject } from 'vue';
export default {
setup() {
const theme = inject('theme');
return { theme };
}
};
- 用途:实现祖孙组件间的通信。
6. 使用toRefs
import { reactive, toRefs } from 'vue';
export default {
setup() {
const state = reactive({ name: '张三', age: 25 });
const { name, age } = toRefs(state);
return { name, age };
}
};
- 用途:将响应式对象的属性转换为响应式的引用,便于在模板中直接使用。
7. 使用defineProps
和defineEmits
<script setup>
import { defineProps, defineEmits } from 'vue';
const props = defineProps(['modelValue']);
const emit = defineEmits(['update:modelValue']);
const handleChange = (event) => {
emit('update:modelValue', event.target.value);
};
</script>
<template>
<input :value="modelValue" @input="handleChange" />
</template>
- 用途:声明组件的
props
和emits
,用于类型检查和代码提示。
这些API和案例可以帮助你更好地理解和使用Vue3的Composition API,从而更灵活地组织和复用组件逻辑。
目录:总目录
上篇文章:红宝书第四十讲:React 核心概念:组件化 & 虚拟 DOM 简单教程
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。