简简单单写写不同风格的vue3代码,后续会带来不同写法具体分析,本文默认是TS写法
一、选项式
官方:使用选项式 API,我们可以用包含多个选项的对象来描述组件的逻辑,例如 data、methods 和 mounted。选项所定义的属性都会暴露在函数内部的 this 上,它会指向当前的组件实例
个人:和vue2写法一样,但不完全一样
import { defineComponent } from 'vue'
import type { PropType } from 'vue'
interface Book {
title: string
author: string
year: number
}
export default defineComponent({
props: {
book: {
// 提供相对 `Object` 更确定的类型
type: Object as PropType<Book>,
required: true
},
// 也可以标记函数
callback: Function as PropType<(id: number) => void>
},
mounted() {
this.book.title // string
this.book.year // number
// TS Error: argument of type 'string' is not
// assignable to parameter of type 'number'
this.callback?.('123')
}
})
选项式 API 中对 props 的类型推导需要用 defineComponent() 来包装组件
虽然vue3只是选项式写法,但是例如filter过滤器vue3中不支持,所以不能按照vue2那种写法,可以封装一个方法,所以选择这种写法的时候,要考察一下vue2的那种写法,在vue3中是不支持的
二、组合式
vue3组合式有三种写法:setup函数、setup语法糖、tsx(jsx)
setup函数
<script lang="ts">
import { defineComponent, ref } from 'vue'
import { IUseTodo, useTodo } from '../../hooks'
export default defineComponent({
name: 'Todoinput',
setup () {
const todoValue = ref<string>('')
const { setTodo }: IUseTodo = useTodo()
/**
* 添加数据:输入框输入数据,点击回车添加数据
*/
const setTodoValue = (e: KeyboardEvent): void => {
if (e.keyCode === 13 && todoValue.value.trim().length) {
setTodo(todoValue.value)
todoValue.value = ''
}
}
return {
todoValue,
setTodoValue
}
}
})
</script>
setup语法糖
<script setup lang="ts">
import { PropType } from 'vue'
import { ITodo, TODO_STATUS } from '@/typings'
interface IStatusState {
DOING: TODO_STATUS;
FINISHED: TODO_STATUS;
WILLDO: TODO_STATUS
}
const statusState: IStatusState = {
DOING: TODO_STATUS.DOING,
FINISHED: TODO_STATUS.FINISHED,
WILLDO: TODO_STATUS.WILLDO
}
const props = defineProps({
item: {
type: Object as PropType<ITodo>,
required: true
}
})
type emitType = {
(e: 'removeTodo', id: number): void
(e: 'setStatus', id: number): void
(e: 'setDoing', id: number): void
}
const emit = defineEmits<emitType>()
const removeTodo = (id: number): void => {
emit('removeTodo', id)
}
const setStatus = (id: number): void => {
emit('setStatus', id)
}
const setDoing = (id: number): void => {
emit('setDoing', id)
}
</script>
TSX
import { defineComponent, PropType } from 'vue'
import { ITodo } from '@/typings'
import TodoItem from '../TodoItem/index'
import { IUseTodo, useTodo } from '@/hooks'
export default defineComponent({
name: 'TodoList',
props: {
todoList: Array as PropType<ITodo[]>
},
components: {
TodoItem
},
setup () {
const {
removeTodo,
setStatus,
setDoing
}: IUseTodo = useTodo()
return {
removeTodo,
setStatus,
setDoing
}
},
render () {
const {
todoList,
removeTodo,
setStatus,
setDoing
} = this
return (
<div>
{
todoList?.map((item: ITodo) => {
return (
<todo-item key={item.id} item={item} onRemoveTodo={removeTodo} onSetStatus={setStatus} onSetDoing={setDoing}/>
)
})
}
</div>
)
}
})
简单比较
| setup函数 | setup语法糖 | TSX | |
|---|---|---|---|
| 变量 | 需要return | 不需要return | 1、render方式需要2、在setup中写dom不需要 |
| 方法 | 需要return | 不需要return | 1、render方式需要2、在setup中写dom不需要 |
| 组件 | 需要注册 | 不需要注册 | 需要注册 |
| 传参 | props | defineProps | props |
| 事件 | emit | defineEmits | emit |
使用体验
setup入口函数方式比较基础,setup语法糖使用比较简便,新增了一些API,也省去好多代码,两者社区活跃度较高
tsx写法与react相似,tsx有vue和@type/nodes版本要求
代码组织方面,合理使用hooks,其实代码不会很乱~
有问题请指出,共同进步!!!