Vue 3 Composition API data() 函数解析
技术背景
Vue 3引入了全新的Composition API,这是一种更灵活、更具逻辑性的组织和复用组件逻辑的方式。在Vue 2中,data()
函数用于定义组件的数据状态,但在Vue 3的Composition API文档中,data()
函数未被提及,这引发了开发者的疑惑。
实现步骤
从 data()
到 setup()
在Vue 2中,使用 data()
函数定义组件数据,示例如下:
1 2 3 4 5 6
| data() { return { foo: 1, bar: { name: "hi" } } }
|
在Vue 3的Composition API中,使用 setup()
函数替代 data()
函数。setup()
函数在组件创建之前执行,在解析完props后作为Composition API的入口。将上述示例转换为Vue 3的 setup()
函数如下:
1 2 3 4 5 6 7 8
| import { ref, reactive } from 'vue';
setup() { const foo = ref(1); const bar = reactive({ name: "hi" });
return { foo, bar } }
|
其他逻辑定义
- 计算属性和监听器:在Vue 3中,计算属性和监听器可以使用
computed()
和 watch()
函数来定义。例如:
1 2 3 4 5 6 7 8 9 10 11 12
| import { ref, computed, watch } from 'vue';
setup() { const count = ref(0); const doubleCount = computed(() => count.value * 2);
watch(count, (newValue, oldValue) => { console.log(`count 从 ${oldValue} 变为 ${newValue}`); });
return { count, doubleCount }; }
|
- 方法定义:在Vue 3的Composition API中,方法可以定义为普通的JavaScript函数。例如:
1 2 3 4 5 6 7 8 9 10 11
| import { ref } from 'vue';
setup() { const count = ref(0);
const increment = () => { count.value++; };
return { count, increment }; }
|
- 生命周期钩子:在Vue 3中,生命周期钩子可以使用
onXXX()
函数来调用。例如:
1 2 3 4 5 6 7
| import { onMounted } from 'vue';
setup() { onMounted(() => { console.log('组件已挂载'); }); }
|
使用 <script setup>
语法
<script setup>
是Vue 3.2引入的语法糖,它可以更简洁地使用Composition API。示例如下:
1 2 3 4 5 6 7 8
| <script setup> import { ref, reactive, computed } from 'vue'
const isActive = ref(false) const user = reactive({ firstName: 'John', lastName: 'Doe', age: 25 })
const fullName = computed(() => user.firstName + ' ' + user.lastName) </script>
|
核心代码
从 data()
到 setup()
的转换
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| data() { return { message: 'Hello, Vue 2!', count: 0 } }
import { ref } from 'vue';
setup() { const message = ref('Hello, Vue 3!'); const count = ref(0);
return { message, count }; }
|
<script setup>
语法示例
1 2 3 4 5 6 7 8 9 10
| <script setup> import { ref } from 'vue';
const message = ref('Hello, Vue 3!'); const count = ref(0);
const increment = () => { count.value++; }; </script>
|
最佳实践
- 逻辑复用:使用Composition API可以将相关的逻辑封装成独立的函数,提高代码的复用性。例如,将数据获取逻辑封装成一个自定义钩子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| import { ref, onMounted } from 'vue';
const useFetchData = () => { const data = ref(null); const isLoading = ref(true);
onMounted(async () => { try { const response = await fetch('https://api.example.com/data'); data.value = await response.json(); } catch (error) { console.error('数据获取失败:', error); } finally { isLoading.value = false; } });
return { data, isLoading }; };
export default useFetchData;
|
然后在组件中使用该钩子:
1 2 3 4 5
| <script setup> import useFetchData from './useFetchData';
const { data, isLoading } = useFetchData(); </script>
|
- 保持代码简洁:避免在
setup()
函数中编写过长的代码,将复杂的逻辑拆分成多个函数,提高代码的可读性和可维护性。
常见问题
data()
函数是否被废弃?
data()
函数并没有被废弃,Vue 3仍然支持Options API,其中包括 data()
函数。但在使用Composition API时,不再使用 data()
函数。
如何在Options API中访问 setup()
函数返回的变量?
可以使用 this
来访问 setup()
函数返回的变量。例如:
1 2 3 4 5 6 7 8 9 10 11
| export default { setup() { const count = ref(0); return { count }; }, methods: { increment() { this.count.value++; } } }
|
ref()
和 reactive()
的区别是什么?
ref()
用于包装非对象值(如数字、字符串等),使其具有响应式特性。访问 ref
的值时需要使用 .value
属性。reactive()
用于包装对象,使其具有响应式特性。访问 reactive
对象的属性时不需要使用 .value
属性。