您现在的位置是:首页 >技术交流 >【Vue3重点概念总结和实践一】(ref / isRef / unref / toRef /toRefs / computed)网站首页技术交流

【Vue3重点概念总结和实践一】(ref / isRef / unref / toRef /toRefs / computed)

小草莓蹦蹦跳 2024-09-17 12:01:06
简介【Vue3重点概念总结和实践一】(ref / isRef / unref / toRef /toRefs / computed)

目录

1、如何检查`count`是否为一个 ref 对象?

2、如果参数是一个 ref,则返回内部值,否则返回参数本身

3、为源响应式对象上的某个 `property` 新创建一个 `ref`,然后`ref` 可以被传递,它会保持对其源`property`的响应式连接

4、如何保证解构 / 扩展不丢失响应性 ? 

5、创建一个可写的计算属性

6、Vue3 + Vue-cli (1) 基础篇

7、Vue3+ Vue-cli (2) 组件篇


1、如何检查 count 是否为一个 ref 对象?

原题:

vuejs-challenges/README.zh-CN.md at main · webfansplz/vuejs-challenges · GitHub

答案: 

检查某个值是否为 ref:isRef(count) 

文档: 

响应式 API:工具函数 | Vue.js

2、如果参数是一个 ref,则返回内部值,否则返回参数本身

原题:

vuejs-challenges/README.zh-CN.md at main · webfansplz/vuejs-challenges · GitHub

答案: 

如果参数是 ref,则返回内部值,否则返回参数本身:unref(value)

这是 val = isRef(val) ? val.value : val 计算的一个语法糖。

文档: 

响应式 API:工具函数 | Vue.js

3、为源响应式对象上的某个 `property` 新创建一个 `ref`,然后`ref` 可以被传递,它会保持对其源`property`的响应式连接

原题: 

vuejs-challenges/README.zh-CN.md at main · webfansplz/vuejs-challenges · GitHub

答案:

基于响应式对象上的一个属性,创建一个对应的 ref。

这样创建的 ref 与其源属性保持同步:改变源属性的值将更新 ref 的值,反之亦然。

toRef(对象, property)

const state = reactive({
  foo: 1,
  bar: 2
})
// 双向ref,会与源属性同步
const fooRef = toRef(state, 'foo') // 重点!!!!

// 修改引用将更新原引用
fooRef.value++
console.log(state.foo, fooRef.value, '修改引用将更新原引用', state.foo === 2) // true

// 修改原引用也会更新`ref`
state.foo++
console.log(state.foo, fooRef.value, '修改原引用也会更新`ref`', fooRef.value === 3) // true

文档:

响应式 API:工具函数 | Vue.js

4、如何保证解构 / 扩展不丢失响应性 ?

原题:

在 JavaScript 中,我们经常解构/扩展对象。在 Vue.js中,我们同样解构/扩展“响应式”对象,但它会失去响应性。

答案:

当从组合式函数中返回响应式对象时,toRefs 相当有用。使用它,消费者组件可以解构/展开返回的对象而不会失去响应性:toRefs(对象)

toRefs 在调用时只会为源对象上可以枚举的属性创建 ref。如果要为可能还不存在的属性创建 ref,请改用 toRef 

例子1: 

function useCount() {
  const state = reactive({
    count: 0
  })

  function update(value) {
    state.count = value
  }

  return {
    state: toRefs(state),
    update
  }
}

// 引入的时候
// 确保解构不丢失响应性
const {
  state: { count },
  update
} = useCount()
    <p>
      <span @click="update(count - 1)">-</span>
      {{ count }}
      <span @click="update(count + 1)">+</span>
    </p>

例子2:

将一个响应式对象转换为一个普通对象,这个普通对象的每个属性都是指向源对象相应属性的 ref。每个单独的 ref 都是使用 toRef() 创建的。

const state = reactive({
  foo: 1,
  bar: 2
})

const stateAsRefs = toRefs(state)
/*
stateAsRefs 的类型:{
  foo: Ref<number>,
  bar: Ref<number>
}
*/

// 这个 ref 和源属性已经“链接上了”
state.foo++
console.log(stateAsRefs.foo.value) // 2

stateAsRefs.foo.value++
console.log(state.foo) // 3

例子3:

function useFeatureX() {
  const state = reactive({
    foo: 1,
    bar: 2
  })

  // ...基于状态的操作逻辑

  // 在返回时都转为 ref
  return toRefs(state)
}

// 可以解构而不会失去响应性
const { foo, bar } = useFeatureX()

文档:

 响应式 API:工具函数 | Vue.js

5、创建一个可写的计算属性

原题: 

vuejs-challenges/README.zh-CN.md at main · webfansplz/vuejs-challenges · GitHub

答案:

computed()

接受一个 getter 函数,返回一个只读的响应式 ref 对象。

该 ref 通过 .value 暴露 getter 函数的返回值。

它也可以接受一个带有 get 和 set 函数的对象来创建一个可写的 ref 对象。

创建一个只读的计算属性 ref:

const count = ref(1)
const plusOne = computed(() => count.value + 1)
console.log(plusOne.value) // 2

plusOne.value++ // 错误

 创建一个可写的计算属性 ref:

const count = ref(1)
const plusOne = computed({
  get: () => count.value + 1,
  set: val => {
    count.value = val - 1
  }
})

/**
 * 确保 `plusOne` 可以被写入。
 * 最终我们得到的结果应该是 `plusOne` 等于 3 和 `count` 等于 2。
 */
plusOne.value++
const count = ref(1)
const plusOne = computed({
  get: () => count.value + 1,
  set: (val) => {
    count.value = val - 1
  }
})

plusOne.value = 1
console.log(count.value) // 0

 文档:

 Vue3 + Vue-cli (1) 基础篇_vue3 vue-cli_小草莓蹦蹦跳的博客-CSDN博客

 响应式 API:核心 | Vue.js

6、Vue3 + Vue-cli (1) 基础篇

Vue3 + Vue-cli (1) 基础篇_vue3 vue-cli_小草莓蹦蹦跳的博客-CSDN博客

7、Vue3+ Vue-cli (2) 组件篇

Vue3+ Vue-cli (2) 组件篇_vue3一个根组件写法_小草莓蹦蹦跳的博客-CSDN博客

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。