setup 语法糖

当使用单文件组件(SFC)时,我们可以使用<script setup>来简化大量样板代码。

  1. <script setup>
  2. import { reactive } from 'vue'
  3. const state = reactive({ count: 0 })
  4. function increment() {
  5. state.count++
  6. }
  7. </script>
  8. <template>
  9. <button @click="increment">
  10. {{ state.count }}
  11. </button>
  12. </template>

reactive

[reactive()](https://staging-cn.vuejs.org/api/reactivity-core.html#reactive)函数创建一个响应式对象或数组

  1. import { reactive } from 'vue'
  2. const state = reactive({ count: 0 })

reactive() API 有两条限制:

  1. 仅对对象类型有效(对象、数组和 Map、Set 这样的集合类型),而对 string、number 和 boolean 这样的 原始类型 无效。
  2. 因为 Vue 的响应式系统是通过 property 访问进行追踪的, 当我们将响应式对象的 property 赋值或解构至本地变量时,或是将该 property 传入一个函数时,我们会失去响应性:
    ```javascript const state = reactive({ count: 0 })

// n 是一个局部变量,同 state.count // 失去响应性连接 let n = state.count // 不影响原始的 state n++

// count 也和 state.count 失去了响应性连接 let { count } = state // 不会影响原始的 state count++

// 该函数接收一个普通数字,并且 // 将无法跟踪 state.count 的变化 callSomeFunction(state.count)

  1. <a name="JJ5Jx"></a>
  2. # ref 定义响应式变量
  3. 为了解决 reactive() 带来的限制 ,Vue 提供了一个 `[ref()](https://staging-cn.vuejs.org/api/reactivity-core.html#ref) `方法来允许我们创建可以使用任何值类型的响应式 **ref**
  4. ```javascript
  5. // 使用时需要引入
  6. import { ref } from 'vue'
  7. const count = ref(0)
  8. console.log(count) // { value: 0 }
  9. console.log(count.value) // 0
  10. count.value++
  11. console.log(count.value) // 1

ref 被传递给函数或是从一般对象上被解构时,不会丢失响应性:

  1. const obj = {
  2. foo: ref(1),
  3. bar: ref(2)
  4. }
  5. // 该函数接收一个 ref
  6. // 需要通过 .value 取值
  7. // 但它会保持响应性
  8. callSomeFunction(obj.foo)
  9. // 仍然是响应式的
  10. const { foo, bar } = obj

ref 也会在模板中自动解包,因此在模板表达式中引用时无需添加 .value

使用ts为ref进行类型标注

为 ref 内的值指定一个更复杂的类型,可以通过使用 Ref 这个类型:

  1. import { ref, Ref } from 'vue'
  2. const year: Ref<string | number> = ref('2020')
  3. year.value = 2020 // 成功!

或者,在调用 ref() 时传入一个泛型参数,来覆盖默认的推导行为:

  1. // 得到的类型:Ref<string | number>
  2. const year = ref<string | number>('2020')
  3. year.value = 2020 // 成功!

获取dom元素 ref

为了通过组合式 API 获得该模板 ref,我们需要声明一个同名的 ref:

  1. <template>
  2. <input ref="input" />
  3. </template>
  4. <script setup>
  5. import { ref, onMounted } from 'vue'
  6. // 声明一个 ref 来存放该元素的引用
  7. // 必须和模板 ref 同名
  8. const input = ref<HTMLInputElement | null>(null)
  9. // 在这个地方打印input 可能为空,因为元素可能还没有挂载上
  10. // 解决方法: 在onMounted里打印
  11. console.log(input)//null
  12. onMounted(() => {
  13. input.value.focus()
  14. //此时可以获取 dom元素
  15. })
  16. </script>