对于前端的开发,我一直有在关注,Vue的写法有点多,是好事还是坏事,我也搞不懂了,几种写法我也都试了一试,可能是TS的原因,觉得并不是很完美,默认的写法对TS兼容性应该是最好的,兼容的场景还是蛮多的,但是监听自定义事件的时候,没有提示。
<script setup lang="ts">
的写法监听自定义事件的提示十分友好,但这种写法访问子组件里的属性时也不友好。但是转念想一想,组件之间应该是独立的,况且Vue也提供了父子组件交互的方法,父组件直接操作子组件这种行为并不推荐。这种写法代码的简洁度很高,按常理来说,代码越少越易维护。自己斟酌。
我是期望前端发展如后端的springboot一样,写法规范统一起来,不管从维护上,还是开发上都能减少一些没有必要的工作量。
默认组合式API写法
响应式
简单的响应式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| <template> <h3>{{ name}}</h3> <h3>{{sum}}</h3> </template> <script lang="ts"> import { defineComponent, toRefs, reactive, computed, watch, ref } from 'vue';
export default defineComponent({ name: 'HelloWorld',
setup() { const sum = ref(200) const name = ref('hahahahah') return { sum,name }
} }) </script>
|
复杂的响应式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| <template> <h3>{{user.name}}</h3> <h3>{{user.age}}</h3> <h3>{{user.sex}}</h3> </template> <script lang="ts"> import { defineComponent, toRefs, reactive, computed, watch, ref } from 'vue';
export default defineComponent({ name: 'HelloWorld', setup() { const user = reactive({ name: '小红', age: 23, sex: '男' }) return { user } } }) </script> <style scoped> </style>
|
一些小妙招
不想在return中写太多的感觉没啥意义的代码,这时候我们就可以这样写
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| <template> <h3>{{ user.name }}</h3> <h3>{{ user.age }}</h3> <h3>{{ user.sex }}</h3>
<h3>{{ sum }}</h3>
<button type="button" @click="sunc('233')">按钮</button> </template> <script lang="ts"> import { defineComponent, toRefs, reactive, computed, watch, ref } from 'vue'; export default defineComponent({ name: 'HelloWorld', setup() { const data = reactive({ user: { name: '小红', age: 23, sex: '男' }, sum: 200, sunc(id:string):void { console.log('id=' + id); }, }) return { ...toRefs(data) } } }) </script> <style scoped> </style>
|
监听事件
关于监听的API还挺多的,这里不过多介绍,只介绍常见的。
简单的监听
1 2 3 4 5 6 7 8 9
| setup() { const fastName = ref('3222') watch(fastName,(newVal,oldVal)=>{ console.log(newVal +'---'+oldVal); }) return { fastName } }
|
侦听一个Getter函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| setup() { const data = reactive({ user: { name: '小红', age: 23, sex: '男' }, sum: 200 }) watch(() => data.user.name, (newVal, oldVal) => { console.log(newVal + '---' + oldVal); }) return { ...toRefs(data) } }
|
监听多个源
1 2 3 4 5 6 7
| setup() { const fooRef = ref("foo") const barRef = ref("bar") watch([fooRef, barRef], ([foo, bar], [prevFoo, prevBar]) => { console.log('newVal = ' + foo+ '-' + bar+',,,oldVal' + prevFoo+ '-' + prevBar); }) }
|
定义Props
简单的定义
父组件传值时会有类型校验。
1 2 3 4 5 6 7 8 9 10 11 12
| export default defineComponent({ name: 'HelloWorld', props: { msg: { type: String, }, }, setup(props,ctx) { } })
|
高端的定义
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| interface Book { title: string author: string year: number } export default defineComponent({ name: 'HelloWorld', props: { msg: { type: String, default: () => ('这是默认值'), validator: (msg: String) => { return msg.length > 3 } }, book: { type: Object as PropType<Book>, default: () => ({ title: '这是一个错误' }), validator: (book: Book) => !!book.title } }, })
|
自定义事件
props和自定义事件都属于组件化常用的,自定义事件的历史包袱过重,在setup的写法中得到了解决,这个组合式API中没啥好的办法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| setup(props, ctx) { const aaaa = reactive({ changeTaa() { ctx.emit('del', 233) }, }) return { ...toRefs(aaaa) } }
<!-- 监听部分 --> <HelloWorld ref="model" @del="testEmit"/>
testEmit(id:string) { console.log('自定义事件触发了'); console.log('id='+id); }
|
到这,常用的组合式API的写法其实就已经差不多了。
封面