* `toRef`函数为源响应式对象上的某个属性创建一个 ref 对象,二者内部操作的是同一个数据值,更新时二者是同步的。
* `toRef`与`ref`不同的是:ref 是拷贝了一份新的数据值单独操作,更新时相互不影响。
* 应用:当要将某个`prop`的 ref 传递给复合函数时,toRef 很有用。
**1. 演示`toRef`与`ref`的不同**
```html
<template>
<!-- 4. 分别更新age和money并查看效果 -->
<h3>state: {{ state }}</h3>
<h3>age: {{ age }}</h3>
<h3>money: {{ money }}</h3>
<hr />
<button @click="updateAge">更新age</button>
<button @click="updateMoney">更新money</button>
</template>
<script lang="ts">
import { defineComponent, reactive, ref, toRef } from "vue"
export default defineComponent({
setup() {
//1. 创建一个响应式对象
const state = reactive({
age: 5,
money: 100,
})
//2. 分别用toRef和ref将state.age属性和state.money转换为ref对象
const age = toRef(state, "age")
const money = ref(state.money)
//3. 更新age和money
const updateAge = () => {
age.value += 5
console.log(age.value)
console.log(state.age)
//age与state.age同步更新
}
const updateMoney = () => {
money.value += 10;
console.log(money.value)
console.log(state.money)
//只有money更新,state.money不会被更新
}
return {
state,
age,
money,
updateAge,
updateMoney,
}
}
})
</script>
```
效果如下,可见当更新 age 时,age 与 state.age 同步更新;当更新 money 时,只有 money 被更新,state.money 不会被更新。更新 state.age 则 age 也会同步更新的。
![](https://img.kancloud.cn/2c/b3/2cb3aca7b82980a458a160492dedb7d3_1714x283.gif)
<br/>
**2. `toRef`的一个应用示例**
(1)父组件 *`src/components/LearnToRefParent.vue`*
```html
<template>
<h2>父组件</h2>
<!-- 4. 更新price并查看效果 -->
<h3>state: {{ state }}</h3>
<h3>price: {{ price }}</h3>
<button @click="update">更新</button>
<hr />
<!-- 5. 向子组件传递属性price -->
<LearnToRefChild :price="price"></LearnToRefChild>
</template>
<script lang="ts">
import { defineComponent, reactive, ref, toRef } from "vue";
import LearnToRefChild from "./LearnToRefChild.vue";
export default defineComponent({
setup() {
//1. 创建一个响应式对象
const state = reactive({
price: 90
})
//2. 用toRef将state.price转换为ref对象
const price = toRef(state, 'price')
//3. 更新price
const update = () => {
price.value += 10
}
return {
state,
price,
update
}
},
components: {
LearnToRefChild,
}
})
</script>
```
(2)子组件 *`src/components/LearnToRefChild.vue`*
```html
<template>
<h2>子组件</h2>
<!-- 4. 观看效果 -->
<h3>price: {{ price }}</h3>
<h3>length: {{ length }}</h3>
</template>
<script lang="ts">
import { computed, defineComponent, Ref, toRef } from "vue";
//2. 获取字符串长度的函数,参数类型为Ref
function useGetLength(price: Ref) {
return computed(() => {
return price.value.toString().length
})
}
export default defineComponent({
setup(props) {
//3. 当函数要求的参数是一个Ref对象时,toRef的作用就体现出来了
const length = useGetLength(toRef(props, 'price'))
return {
length,
}
},
props: {
price: { //1. 从父组件传递过来的price属性
type: Number,
required: true,
},
},
})
</script>
```
(3)效果。
![](https://img.kancloud.cn/af/61/af615ad49e3e2de1e76b38a668354fc1_1714x493.gif)
- nodejs
- 同时安装多个node版本
- Vue3
- 创建Vue3项目
- 使用 vue-cli 创建
- 使用 vite 创建
- 常用的Composition API
- setup
- ref
- reactive
- 响应数据原理
- setup细节
- reactive与ref细节
- 计算属性与监视
- 生命周期函数
- toRefs
- 其它的Composition API
- shallowReactive与shallowRef
- readonly与shallowReadonly
- toRaw与markRaw
- toRef
- customRef
- provide与inject
- 响应式数据的判断
- 组件
- Fragment片断
- Teleport瞬移
- Suspense
- ES6
- Promise对象
- Promise作用
- 状态与过程
- 基本使用
- 常用API
- async与await
- Axios