对Vue也算比较熟悉,熟悉的原因很简单,三大前端框架,只有Vue的官方文档中文最全。刚进入工作时用过Vue2,还是内嵌到HTML里面的形式,low是low了点,好处就是当时用(学)起来有没有什么负担,工作里的实践,闲暇中阅读文档,周末大致看看视频,到也不难理解,主要官方的中文文档很详细了,只要你耐得住性子去看,去学。
Vue3出来也挺长时间了,在Vue3的文档还没有中文翻译的时候我就去看了,当时对Vue这东西理解尚浅,加上一些琐事,没时间去学,学不动了,真的学不动了。不怎么忙的时间里,我于是静下心来了解了一下。
说升级,对于使用者来说,无外乎废弃了一些API,写法上多了些选择,至于性能提升,代码优化,这些东西我们并不太需要知道。Vue之所以保留旧版的写法,完全是为了照顾旧版本,让使用者就算打算升级也可以更平滑的升级。这对于前端框架来说非常难得,此处点名@angular, 完全不管旧版本的死活。
尤大官方也说,不建议使用旧版的语法,推荐使用组合式API,那就试试去理解学习组合式API。对于会Vue2的来说理解最重要的,升级的底层核心我们触碰不到,也不需要触碰到,理解Vue2的痛点,以及缺陷,再去理解Vue3新语法解决了什么问题,这个是目前主要需要做的事。
Vue3简单的说就是把Vue2中分的零零碎碎的代码放在了一起,首先我们回想Vue2中有哪几块代码,data (响应式的属性) methods (基本的代码逻辑)计算属性,还有一个监听属性,生命周期先不考虑,尤大认为这种写法逻辑太过分散,一个数据可能需要要经过三到四个不同的地方,这时候我们就需要在不同的块中找代码,这个一个块里上百行代码是非常常见的。需要跳来跳去的看代码,容易造成关注点混乱。
组合式写法就是为了解决这种情况,而且组合式的方向对了,没写过React,据说是很像,简单的一点组合式代码提示会更友好,明眼人一看,起码给IDE的计算负担减低不少。不管是JS还是TS。那么学习组合式需要注意什么呢,不要把它想的很难,什么简直都需要重学,实际上就是换了一种写法,定义data变成了ref以及reactive,加上一些奇奇怪怪的语法糖,定义methods,直接定义函数就行了,监听属性,计算属性,都有对应的写法,生命周期随便再看看。Vue3内嵌Html的用法就这些。组件化时加了两个东西一个props以及自定义事件( emit), 这两个东西没怎么变,至少基于JS来说。对于TS这两个变化略多,可以说一种写法一种定义或者声明方式,主要还是这两个东西历史包袱过重。
Vue3据我目前所了解的,算上旧版本的写法,这种写法不配拥有姓名,所以只能称之为旧版本写法,算上旧版本的写法有四种了。很多啊,我没有兴趣去研究那么多,基于目前来看,<script setup >
这种写法应该是最优雅的,尤大官方微博也说了,Vue3 + TS+ setup + Volar = 真香。下面主要代码介绍这种写法。
这种写法不能使用HTML来写,只能使用单文件方式来写,主要看写法
组件HelloWord
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 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
| <template> <div class="hello"> <h1>{{ msg }}</h1> <h3 v-if="visible">是否显示 {{ visible }} sumcom = {{ sumcom }}</h3> <button type="button" @click="test">点击抛出事件</button> </div> </template>
<script setup lang="ts"> import { watch, ref, computed, toRefs } from 'vue';
const props = defineProps<{ msg: string visible: boolean }>()
const emit = defineEmits<{ (e: 'change', id: number): void (e: 'update', value: string): void }>()
const test = () => { emit('update', '从前从前') }
const sum = ref(200)
const sumcom = computed((): number => { return sum.value * 4 })
watch(sum, (newVal, oldVal) => { console.log(newVal + "----" + oldVal); })
defineExpose({ sum }) </script>
<style scoped> </style>
|
组件APP
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 39 40 41 42
| <template> <img alt="Vue logo" src="./assets/logo.png" /> <HelloWorld msg="欢迎来到你的VUe+TS项目" :visible="flag" @update="upd" ref="model" /> </template>
<script setup lang="ts"> import { ref } from '@vue/reactivity'; import { onMounted } from '@vue/runtime-core'; import HelloWorld from './components/HelloWorld.vue';
const flag = ref(false)
const upd = (value: string): void => { console.log(value) flag.value = !flag.value }
interface expHello { sum: number }
const model = ref<InstanceType<typeof HelloWorld> & expHello>()
onMounted(() => { console.log(model.value?.sum);
})
</script>
<style> #app { font-family: Avenir, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } </style>
|
封面