在几天前开启的 SFC Improvements #182 中, yyx990803 提交了 3 个改进开发者体验的征求意见稿.
虽然看上去都不是体量很大的改动, 但都相当实用, 开发者谁用谁知道! 一起来先睹为快:
1. <component> 组件导入语法糖
在目前的写法中, 要引入其它组件, 就得先在 <script> 中 import, 再将其模块名放入组件的 components: {} 属性对象中. 比如:
- <template>
- <Foo/>
- </template>
- <script>
- import Foo from './Foo.vue'
- export default {
- components: {
- Foo
- }
- }
- </script>
又或者异步组件:
- <template>
- <Foo/>
- </template>
- <script>
- import { defineAsyncComponent } from 'vue'
- export default {
- components: {
- Foo: defineAsyncComponent(() => import('./Foo.vue'))
- }
- }
- </script>
这样写起来既费力, 又在使用新的 Composition API 显得不那么 "新", 还是要 props,components 写一大堆.
有鉴于此, 新的提案设计成这样:
- <component src="./Foo.vue"/>
- <component async src="./Bar.vue"/>
- <component src="./Baz.vue" as="Qux" />
- <template>
- <Foo/>
- <Bar/>
- <Qux/>
- </template>
2. 简化 Composition API 的 <script setup>
正如上面提到过的, 在使用新的 Composition API 时, 对于不用引入其它组件的, 相对简单的那些组件来说, 只包含一个 setup() 的组件声明对象也很常见. 比如:
- import { ref } from 'vue'
- export default {
- setup() {
- const count = ref(0)
- const inc = () => count.value++
- return {
- count,
- inc
- }
- }
- }
新提案将其简化为:
- <template>
- <button @click="inc">{{ count }}</button>
- </template>
- <script setup>
- import { ref } from 'vue'
- export const count = ref(0)
- export const inc = () => count.value++
- </script>
另外, <script setup> 中将隐式注入几个对象:
- $props
- $attrs
- $slots
- $emit
比如之前的写法为:
- import { watchEffect } from 'vue'
- export default {
- setup($props, { emit: $emit }) {
- watchEffect(() => console.log($props.msg))
- $emit('foo')
- return {}
- }
- }
简化后 <script setup> 中写为:
- import {
- watchEffect
- } from 'vue'
- watchEffect(() => console.log($props.msg))
- $emit('foo')
声明其它组件选项
使用 <script setup> 后, 如果还想手动指定 props 等组件选项, 可以用一个 export default 解决, 即:
- <script setup>
- import { computed } from 'vue'
- export default {
- props: {
- msg: String
- },
- inheritAttrs: false
- }
- export const computedMsg = computed(() => $props.msg + '!!!')
- </script>
结合 TypeScript
要声明 $props 或 $emit 等隐式对象的 TS 类型, 采用下面的语法:
- <script setup lang="ts">
- import { computed } from 'vue'
- // 使用 TypeScript 语法声明 props
- declare const $props: {
- msg: string
- }
- export const computedMsg = computed(() => $props.msg + '!!!')
- </script>
重要的是, 这些 TS 声明会被自动编译成等价的运行时声明. 如以上代码将转化为:
- <script lang="ts">
- import { computed, defineComponent } from 'vue'
- type __$props__ = { msg: string }
- export default defineComponent({
- props: (['msg'] as unknown) as undefined,
- setup($props: __$props__) {
- const computedMsg = computed(() => $props.msg + '!!!')
- return {
- computedMsg
- }
- }
- })
- </script>
这样也避免了为静态检查和运行时写两遍重复的声明.
3. 状态驱动的 <style> 中 CSS 变量注入
以往要根据状态或属性来影响样式的话, 还是比较麻烦的. 首先要提前在 <style> 中写好几种 className 对应的样式, 再利用脚本动态在模版中赋相应的 className 才行.
新提案结合原生的 CSS variables 特性, 提供了更方便的联动方案:
- <template>
- <div class="text">hello</div>
- </template>
- <script>
- export default {
- data() {
- return {
- color: 'red'
- }
- }
- }
- </script>
- <style :vars="{ color }">
- .text {
- color: var(--color);
- }
- </style>
总结
再次重复, 这几个特性仅仅是最新的提案, 并不一定是最终的样子; 但鉴于其实用性, 开发者还是有必要早做了解, 多提建议.
提案地址如下: https://github.com/vuejs/rfcs/pull/182
--End--
查看更多前端好文
请搜索 fewelife 关注公众号
来源: http://www.tuicool.com/articles/yUvY7fr