这2种方式都是组合式API吗?方式1也是写在一个.vue文件中的吗?

在阅读此文档时候:

方式1:不使用<script setup>

// js
import { reactive } from 'vue'

export default {
  // `setup` 是一个专门用于组合式 API 的特殊钩子函数
  setup() {
    const state = reactive({ count: 0 })

    // 暴露 state 到模板
    return {
      state
    }
  }
}

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

方式2:使用<script setup>

<script setup>
import { reactive } from 'vue'

const state = reactive({ count: 0 })

function increment() {
  state.count++
}
</script>

<template>
  <button @click="increment">
    {{ state.count }}
  </button>
</template>

请问下:
1.这2种方式都是组合式API吗?我只见过第二种写法,

2.方式1写在一个.vue文件中是这样的吗?

<script>
import { reactive } from 'vue'

export default {
  setup() {
    const state = reactive({ count: 0 })

    function increment() {
      state.count++
    }

    // 不要忘记同时暴露 increment 函数
    return {
      state,
      increment
    }
  }
}
</script>

<template>
  <button @click="increment">
    {{ state.count }}
  </button>
</template>
阅读 1.8k
2 个回答
✓ 已被采纳

省流:

setup并不代表组合式 API,只是组合式 API的限制是必须要在setup中使用;

详解

这两种都是组合式 API的应用场景,也就是 composition api 的中文解释,在我们使用 Vue2 的时候,用的都是 选项式 API,英文对应的是 options api

方式1 就是在选项式 API 中新增了一个选项配置,叫做 setup 的一个可选配置,在这个里面写的所有的代码全都是普通的 JS 对象,这个时候我们就需要使用 组合式 API 来使这个 普通的 JS 对象变成响应式对象;

就拿你文中的示例来说:

  • import { reactive } from 'vue'这个叫做组合式 API
  • const state = reactive({ count: 0 })这个叫做组合式 API 的应用

最后还需要通过return将这些JS对象返回出去,需要注意的是,这个返回的不管是不是响应式的对象,返回只是为了可以在其他模块中使用,例如你需要在模板中使用,就是下面的代码片段:

<button @click="increment">
    {{ state.count }}
</button>

这个state在定义的时候,使用了组合式 APIreactive函数来使其成为一个响应式对象,如果说不使用的话,其一是这个对象无法保持响应式,其二是你只使用了 setup 并没有使用 组合式 API

再说一下方式2:

方式2就是方式1的变形,也就是我们常说的语法糖,上面讲方式1讲了那么多,其实在方式2中也是相同的,不是同的是什么呢?

  1. 不需要return就可以在其他的地方使用定义好的变量。
  2. 无法使用选项式 API

这就是最大的,也是最明显的两个区别,例如我们是从Vue2过渡到Vue3的用户,对Vue2选项式 API滚瓜乱熟了,但是还不太了解Vue3组合式 API,现在有下面这样的一段代码:

  • Vue2
<template>
    <Bar/>
</template>
<script>
import Bar from './bar.vue';

export default {
    component: {
        Bar,
    }
}
<script>

这是Vue2中的组件应用的写法,那么在Vue3中应该怎么使用呢?

方式一:

<template>
    <Bar/>
</template>
<script>
import Bar from './bar.vue';

export default {
    setup() {
        // setup 实名傻眼,这活接不了
    },
    component: {
        Bar,
    }
}
<script>

方式2:

<template>
    <Bar/>
</template>
<script setup>
// 语法糖嘛,甜到你心里

import Bar from './bar.vue';

<script>

说了这么多,只是讲了方式1方式2之间的区别,好像并没有讲什么是组合式 API

组合式 API

组合式 APIVue提供的一种可以逻辑复用,并且有状态函数,例如有一个计数器的功能:

  • 不使用组合式 API
<template>
<div>
    {{count}}
    <button @click="increment">count++</button>
</div>
</template>
<script>
export default {
    data() {
        return {
            count: 0
        }
    },
    methods: {
        increment() {
            this.count++;
        }
    }
}
</script>
  • 使用组合式API(这里直接使用语法糖的写法了)
<template>
<div>
    {{count}}
    <button @click="increment">count++</button>
</div>
</template>
<script setup>
import {ref} from "vue";

const count = ref(0);
const increment = () => {
    count++;
}

先不说简洁程度,现在思考一个问题,就是如果这个计数器需要复用,如果不使用组合式 API应该怎么做?

第一个想到的可能是minxis,但是如果我自己的页面上也有一个同名的countincrement怎么办?而且你引用了minxis别人怎么知道里面有什么呢?这里就不演示代码了,Vue3已经表示minxis该被弃用了。

而使用组合式API可以怎么做呢?

  1. 新建一个 js 文件,然后写一个 useXxx开头的函数,将上面写的js代码复制进去,最后将这个函数导出,如下:
import {ref} from "vue";

function useCounter() {
  const count = ref(0);
  const increment = () => {
      count++;
  }

  return {
    count,
    increment
  }
}

export useCounter;
  1. 使用,直接引用这个 js ,然后调用对应的useXxx函数
<template>
<div>
    {{count}}
    <button @click="increment">count++</button>
</div>
</template>
<script setup>
import {useCounter} from './counter.js'

const {count, increment} = useCounter();

为什么要使用useXxx的这个use开头来命名这个函数呢?

这个只是业内大家默认的一个规范,大家看到是use开头的就心里明白这个函数的返回结果是响应式的,你也可以不使用use开头,当然这种是不建议的。

这个问题到这里了,希望对你有所帮助。

两种都是 组合式api 的使用方式,但用法上有些差别

  • 方式2 只能在 SFC(单文件组件,即 .vue 文件) 中使用,属于 vue 提供的一种简洁一点的方式
  • 方式1 则可以写在任何 js/ts 文件中,比如这样

    // demo.js - 使用 h 函数
    import { defineComponent, ref } from 'vue';
    export default defineComponent({
      name: 'Demo',
      setup(props) {
          const count = ref(1);
          return (h) => h('div', null, `demo: ${count}`);
      }
    });

    也可以使用 jsx

    // demo.jsx - 使用 jsx
    import { defineComponent, ref } from 'vue';
    export default defineComponent({
      name: 'Demo',
      setup(props) {
          const count = ref(1);
          return <div>demo: { count }<div>;
      }
    });
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题