优秀的编程知识分享平台

网站首页 > 技术文章 正文

关于Vue3的setup attribute标识是否是一个值得使用的语法糖?

nanyue 2024-09-10 16:07:08 技术文章 4 ℃

Vue3从2020年9月发布到现在也有3年多的时间,这期间相信各大企业先后陆续都会在新项目的选择上从Vue2转到了Vue3开发,原因毫无疑问两个方面的改变性能+组合式API的变化,性能提升暂且不谈后续有空我会单独说一下性能方面的,也并非讲组合式API的用法好处,本文重点要讨论的一个地方是关于<script setup>用法问题。 <script setup> 是什么? 有什么用? 在vue的官网中是这么写的

添加图片注释,不超过 140 字(可选)

网中写了这样的一个示例(官网中主要展示的是组合式API与Option API的区别)

<script setup>
import { ref, onMounted } from 'vue'

// 响应式状态
const count = ref(0)

// 用来修改状态、触发更新的函数
function increment() {
    count.value++
}

// 生命周期钩子
onMounted(() => {
    console.log(`The initial count is ${count.value}.`)
})
</script>

<template>
    <button @click="increment">Count is: {{ count }}</button>
</template>

其中第一行代码的setup就是一个语法糖的使用,那么如果没有加入setup关键字的话应该如何写呢?

<script>
import { ref, onMounted } from 'vue'

export default {
    setup () {
        // 响应式状态
        const count = ref(0)

        // 用来修改状态、触发更新的函数
        function increment() {
            count.value++
        }

        // 生命周期钩子
        onMounted(() => {
            console.log(`The initial count is ${count.value}.`)
        })
        
        return {
            count
        }
    }
}
</script>

<template>
    <button @click="increment">Count is: {{ count }}</button>
</template>

看起来是不是前者简便了一些,少写了export default也不再需要在setup方法中return,一共8行代码,随着<template>模板中的变量越多代return出去的代码也会越多,通常一个业务组件中大约是10~30行代码 <script setup>的得与失 使用setup标识的好处 如前面所说,节约代码,不需要在setup方法内使用return返回变量即可在template中直接使用 作为<script setup>使用的代价失去了什么? 在讲这方面之前我认为有必要先,抛出一个观点,是否越越简洁的代码就越好?显然我是不这么认为的,关于这点不仅仅体现在这一方面,后期可以单独针对这一点再举个例子讲一下,当前只针对setup单独讨论,在讨论这个问题之前我们需要对一下几个概念有一个清晰的认识。 通常我们在Vue中使用引入局部组件?

<script>
import componentA from '组件路径'

export default {
    components: {
        // 完成注册
        componentA
    }
}
</script>

<template>
    <div>
        <!--完成使用-->
        <componentA></componentA>
    </div>
</template>

想必这几行代码使用,早已深深刻入每一个使用Vue开发的人的DNA了。不知大家是否有想过尝试过通过console.log(componentA)在控制台输出一下componentA组件的本质是何物,或者他应该是何物? 我想了解这一点是比较重要的,或许他不影响着我们开发,直接按固定的套路import接收一个固定的变量,固定的写法,就能实现组件注册并实现业务逻辑开发,但作为一个开发人员,如果连每天都在使用的东西都不了解,我觉得多少都是有些问题的。 关于这一点实际上就跟Vue本身没多大关系的,这涉及到的实际上就是模块化方法的知识。 js的ES6模块化的一些概念 关于模块化的作用在这里不做过多的叙述,直接说最终使用上的一个规则,网上可能有各种各样的说法,这里我得到叫法可能跟网上有所不同,但语法规则上是一样的,大家可以自行去网上了解。 导出

// 非默认导出,他可以有多个,不可匿名
export const a = 'a'
export const b = 'b'
// 默认导出,可以匿名
export default ‘c’

导入

// 导入非默认导出变量,导出的变量名必须跟导出相同
import { a } from '导出文件地址'
// 导入默认导出变量,默认导出变量名可以自定义,因为导出是匿名
import ccccc from '导出文件地址'
// 全量导入,会将默认导出与非默认导出一起合成一个大对象返回,如果是默认导出,那么key值就是default
import * as all from '导出文件地址'

console.log(a)
// 输出 'a'
console.log(ccccc)
// 输出 'c'
console.log(all)
// 输出对象 { a: 'a', b: 'b': default: 'c' }

Vue中import导入的组件变量componentA到底是什么

回到最开始的时候写的案例组件,如下

<script>
import { ref, onMounted } from 'vue'

export default {
    setup () {
        // 响应式状态
        const count = ref(0)

        // 用来修改状态、触发更新的函数
        function increment() {
            count.value++
        }

        // 生命周期钩子
        onMounted(() => {
            console.log(`The initial count is ${count.value}.`)
        })
        
        return {
            count
        }
    }
}
</script>

<template>
    <button @click="increment">Count is: {{ count }}</button>
</template>

很显然componentA就是<script>里面的export default所导出的整个对象,到此也解释了为何我不推荐写<script setup>,因为本应该能能基于我们更好理解性质的代码被直接忽略了,这是由于通常我们使用vue-cli开发,内部集成了webpack里面的其中一个loader,也就是vue-loader帮我们处理了这些事情。 老好人vue-loader 使用脚手架开发时候,我们不难发现在package.json里面需要依赖vue-loader。 什么?你说没有? 那是因为官方提供的脚手架实际上不是直接依赖vue-loader,而是依赖了@vue/cli-service然后再这个包内部又依赖了vue-loader,去node_modules内部找到这个包查看引用不难发现这点。 那么vue-loader帮我们做了什么? js模块化的局限性及解决办法 我们所熟悉的模块化实际上只支持两种文件js,json.vue文件实际不难理解,因为他并不是纯js代码。 那么import导入时候肯定是不知道导出的变量是啥,哪怕之前所说的componentA实际上export default这些代码也是在.vue文件内的一个<script>内部的代码,我们所熟悉的能直接这么写的文件恐怕只有.html文件,在浏览器的时候他认识这个标签。 但.vue凭什么理所应当就认识?里面还有<template>作为类html的模板以及<style>作为容纳css的标签,从我们最开始理解的前端三剑客html,css,js,这似乎是一件不被理解的事情。 因此vue-loader实际上就相当于是认识这个.vue的翻译官,它的作用就是将.vue文件转换成.js文件,这样就能解决了模块导入的局限性。 vue-loader针对.vue文件做了多少处理 关系这点还是挺多细节的,在这里不做过多解释,有机会可以单独写一篇讲一下,这里只做简单解释,就是将<template>转换成导出的对象中的render方法,将<style>转换成js语法,比如通过document.createElement创建<style>标签,再通过document.body.appendChild插入到dom中,这样一来不就是纯js代码了。 那么回归到最初的问题,很显然 <script setup>就是在这个过程中做了一些代码的节约,从而让我们可以少写了这几行代码。 可以简单的理解为,我们不用亲自写这些代码。但是vue-loader在编译之后还是给我们加上了这些代码,这其中也包括了return出去的变量,所以才可以直接在模板中使用。 总结使用<script setup>代价到底失去了什么

<script>
import { ref, onMounted } from 'vue'

export const defaultOptions = {
    count: '0'
}

export default {
    setup () {
        // 响应式状态
        const option = ref(defaultOptions)
        
        return {
            option
        }
    }
}
</script>

<template>
    <div>{{ option.count }}</div>
</template>

如上述这类代码除了export default以外还可以使用非默认导出export导出变量defaultOptions,当然这点几乎无关痛痒,也并非是我不推荐的原因。 最主要的原因是,经过上述的说法,如果对于js 模块化有足够的理解,那么我认为从代码阅读性质来说无疑是更好的,因为vue-loader将这一部分不该做的事情都做了,回想Vue2实际这些代码都是不可忽略的,但反而因为如此,他能更接近js本质上的一些东西,我认为是不可忽略的。 其中return返回的变量,我认为其实从某种角度上,更能直观让你看到<template>上到底使用了那些变量,方法,计算属性等。 总结 使用<script setup>弊大于利 而对于相对于少这一点点代码来说实际上,我认为实际上并不占用项目太多的代码量,但会换来更好的代码阅读性。

Tags:

最近发表
标签列表