>[success] # ref
1. 接受一個內部值并返回一個響應式且可變的 `ref `對象,`ref()` 返回的是**value reference (包裝對象)** 并且這個對象`value`屬性指**向包裝的值讓其具備了響應**
* 數據操作的是使用是`xxx.value`
* 在模板中引入`ref`的值時,Vue會自動幫助我們進行**解包操作**,所以我們并不需要在模板中通過 `ref.value` 的方式來使用
3. 一般定義基本類型的響應事數據使用`ref `常見的基本類型,如果你綁定的是對象他將會調用`reactive `,此時`.value`返回的是一個`proxy`對象,
4. 為什么具有`value `因為`proxy `不能將基本類型進行劫持和代理,因此將其轉換為對象,進行劫持代理,如果包裹是對象類型做了一層`reactive`包裹
>[danger] ##### 案例
~~~html
<template>
<div >
<button @click="print">觸發事件</button>
{{str}}
<input v-model="str" />
</div>
</template>
<script>
import {ref} from 'vue'
export default {
name: 'testlison',
setup(prop, ctx) {
const str = ref('z')
const num = ref(1)
const boolean = ref(false)
const ull = ref(null)
const un = ref(undefined)
const print = ()=>{
str.value = "q"
num.value = 100
boolean.value = true
ull.value = {name:'zz'}
un.value = 1000
}
return { str,print}
},
}
</script>
~~~
>[danger] ##### 解構
[案例](https://sfc.vuejs.org/#eNp9U21rE0EQ/ivDfmkCyR1VQQ2Xov9jv1wum/Zq7oW9vUQ4DvyQFsRqhJYarRbaChVE4xvFaOuv6Z3xk3/B2d3kkrMiB3uzs888M8/sbELuhqHRixlpEEswL+zagq1RH8Bquz1lgNWKhQh8uON0XedekxJnw/bXGSVr+d4kG44sUwMQTYUKgySxDd/2WJpaZsGjKfGsZThB7AujZ3fjEmRuWeZSKbiNHO6GQkFcLwy4gAQ469Q4sx3h9hik0OGBBysoZEWi2H2FarOOHXcRrfNHTMRhpTrfAjiBHwmwoSnZKpDIkhuU9Pt9SlKolmEthCVoY+XQUAGrVUilZvl1Yh9LwS7p5lSqRRIA04TsYhcjINvZmp5M8tE4G0+mH4/yZ2fZg+fZ1ln2/nDmGY2nx2/nujT89/nO5ddHv14dT09P8sOB63eCMreKx0gsSsdVykoKIXMpCajWNyQV9q4J9gIhferu0E3J6rXrNyhZnJYS5+9eowJdVfb0yc8XA90dqW/3cfZtLzsfolMJV+qkkovt6el2dvAj/3SUv3yYH3zJ9z+UWT+/yQdDTVB06vL7vhR4VYjOKDW0lg/1eMVdreLmrdv/EpEW1vzPcUK4vxgQALu2sFtLtr7mwoFzsESkV+XDxTKL+SU1oge47tmhsRkFPr47lY3ODiJKGvP8lOA8yz0lG0KEUcM0o44jX+tmZAR83UTL4CjV9ZjBIq/e4kE/YhyJKZmVpjhMdPYYr3Pmtxln/H+cf0Gv8M5EpST9A7P1k04=),如果將一個對象賦值給 ref,那么這個對象將通過[reactive()](https://cn.vuejs.org/api/reactivity-core.html#reactive)轉為具有深層次響應式的對象
~~~html
<template>
<div>
<button @click="change">改變</button>
<div> {{a.name}}</div>
<div> {{b.count.value}}</div>
</div>
</template>
<script>
import { ref,reactive } from 'vue'
export default {
setup() {
const a = ref( {name:"www"} )
const b = { count : ref(1) }
function change(){
// 當ref 包裹是對象時候其實對象是被reactive包裹,下面解構info
// 其實是 reactive({name:"www"}),視圖會更新
const { value:info } = a
info.name = "1234"
// 此時解構后的count 是響應式的ref 對象,但視圖沒有更新
// 注意響應是對象他是
const { count } = b
count.vaule = "789"
}
return {
a,
b,
change,
}
}
}
</script>
~~~
* 官方一個例子,`ref `被傳遞給函數或是從一般對象上被解構時,不會丟失響應性,解構后他 依舊是一個`ref `的響應式的對象,需要通過`value `賦值
~~~
const obj = {
foo: ref(1),
bar: ref(2)
}
// 該函數接收一個 ref
// 需要通過 .value 取值
// 但它會保持響應性
callSomeFunction(obj.foo)
// 仍然是響應式的
const { foo, bar } = obj
~~~
>[danger] ##### 是所有情況下ref 在模板渲染時候都不用.value么
1. 只有當`ref`包裹的對象是直接從`setup`返回的可以省略`value`,但是如果是嵌套的**依然需要你在模板中使用value屬性**

[案例](https://sfc.vuejs.org/#eNqNU01v00AQ/SvLXpqosc05ciM4cuHA2RfXmYBLbK9216Yo8oEDiEMLBxKpqEUQoopIUCoEhyQS6p/xR34G6107cROCuHh3Zp7fe7OzO8D3CdGjEHAbmxw80rc5dCwfIbPrRnIjtnc0DWXTcfbhZvllkp68TGan+XAa2f0QkKZVKEZsvzMYICcIfY7i2DRkpqwehpwHPrrn9F3n6YGFFWp/38KdB75DwQMRyqRpKGxdPT3/lMwW6h8KvfR6vvwxXn7+mixOsm9jYWk5macXUx8Yh24yuxL4/OJFPrpUJtN3p+limA3n6duz7Oxa+v+YjV7X3BcqWyYVn17z+lBm0C7LG4TZ1SQff09fvc9+jtalHSdSF9OV7/+R3MFGaHD8/FHdOgXb4W4ESA2xRiDnbaiBm0btGoiQOdQlXKq4HgkoR4NiAq0VW4x6NPDQnrhEewUKjiWqCz077Au08seAh6TRrEIkmvBZ2Qo6KBgbd5tVrVoNA+Xnv7I3l8nvG3Hh1NRvE6hDEwwr4qIiSKsw/gupolt1oK7PbV51fNKZQjV2CjRX1GuJakdF29TfMtdax6qBWkIpb9iXi/iIN1XNA7ewGojm2UQ/YoEv3rAUssoCs3C7krawmE8RW/gJ54S1DYP1nOLlHzE9oI8NsdOpsOZ6oAPztEMaPGNABbGFS3eSwxDJCKhGwe8CBfovzg3oFm/ZVIzjP94Ko3Y=)
~~~html
<template>
<div>
<!-- 模板解包不用value -->
<span>{{ count }}</span>
<button @click="count ++">Increment count</button>
<!-- 因為count ref對象被二次包裹在nested中因省略value 響應改變是不生效 -->
<!-- <button @click="nested.count ++">Nested Increment count</button> -->
<!-- 正確寫法 -->
<button @click="nested.count.value ++">Nested Increment count</button>
<button @click="proxyR.count ++">reactive 解包</button>
</div>
</template>
<script>
import { ref,reactive } from 'vue'
export default {
setup() {
const count = ref(0)
// 直接使用對象
const nested = {
count
}
// 使用reactive 包裹
const proxyR = reactive({
count
})
//
return {
count,
nested,
proxyR
}
}
}
</script>
~~~
>[danger] ##### 注意點作為對象參數
1. **當一個包裝對象被作為另一個響應式對象的(屬性)引用的時候也會被自動展開** 但是當從數組或本地集合類型(如Map)訪問ref時,不會執行展開操作
~~~
const books = reactive([ref('Vue 3 Guide')])
// need .value here 這里依舊需要value
console.log(books[0].value)
const map = reactive(new Map([['count', ref(0)]]))
// need .value here 這里依舊需要value
console.log(map.get('count').value)
// 反復包裹
let obj = ref({ name: 'w' })
console.log(obj.value.name)
console.log(reactive(obj).value.name)
~~~
>[danger] ##### 解包的api
~~~
1.reactive 和 readonly 具有相同解包特性
~~~
>[info] ## 官網
[## ref()](https://cn.vuejs.org/api/reactivity-core.html#ref)
[## 用`ref()`定義響應式變量](https://cn.vuejs.org/guide/essentials/reactivity-fundamentals.html#reactive-variables-with-ref)
- 官網給的工具
- 聲明vue2 和 vue3
- 指令速覽
- Mustache -- 語法
- v-once -- 只渲染一次
- v-text -- 插入文本
- v-html -- 渲染html
- v-pre -- 顯示原始的Mustache標簽
- v-cloak -- 遮蓋
- v-memo(新)-- 緩存指定值
- v-if/v-show -- 條件渲染
- v-for -- 循環
- v-bind -- 知識
- v-bind -- 修飾符
- v-on -- 點擊事件
- v-model -- 雙向綁定
- 其他基礎知識速覽
- 快速使用
- 常識知識點
- key -- 作用 (后續要更新)
- computed -- 計算屬性
- watch -- 偵聽
- 防抖和節流
- vue3 -- 生命周期
- vue-cli 和 vite 項目搭建方法
- vite -- 導入動態圖片
- 組件
- 單文件組件 -- SFC
- 組件通信 -- porp
- 組件通信 -- $emit
- 組件通信 -- Provide / Inject
- 組件通信 -- 全局事件總線mitt庫
- 插槽 -- slot
- 整體使用案例
- 動態組件 -- is
- keep-alive
- 分包 -- 異步組價
- mixin -- 混入
- v-model-- 組件
- 使用計算屬性
- v-model -- 自定義修飾符
- Suspense -- 實驗屬性
- Teleport -- 指定掛載
- 組件實例 -- $ 屬性
- Option API VS Composition API
- Setup -- 組合API 入口
- api -- reactive
- api -- ref
- 使用ref 和 reactive 場景
- api -- toRefs 和 toRef
- api -- readonly
- 判斷性 -- API
- 功能性 -- API
- api -- computed
- api -- $ref 使用
- api -- 生命周期
- Provide 和 Inject
- watch
- watchEffect
- watch vs. watchEffect
- 簡單使用composition Api
- 響應性語法糖
- css -- 功能
- 修改css -- :deep() 和 var
- Vue3.2 -- 語法
- ts -- vscode 配置
- attrs/emit/props/expose/slots -- 使用
- props -- defineProps
- props -- defineProps Ts
- emit -- defineEmits
- emit -- defineEmits Ts
- $ref -- defineExpose
- slots/attrs -- useSlots() 和 useAttrs()
- 自定義指令
- Vue -- 插件
- Vue2.x 和 Vue3.x 不同點
- $children -- 移除
- v-for 和 ref
- attribute 強制行為
- 按鍵修飾符
- v-if 和 v-for 優先級
- 組件使用 v-model -- 非兼容
- 組件
- h -- 函數
- jsx -- 編寫
- Vue -- Router
- 了解路由和vue搭配
- vueRouter -- 簡單實現
- 安裝即使用
- 路由懶加載
- router-view
- router-link
- 路由匹配規則
- 404 頁面配置
- 路由嵌套
- 路由組件傳參
- 路由重定向和別名
- 路由跳轉方法
- 命名路由
- 命名視圖
- Composition API
- 路由守衛
- 路由元信息
- 路由其他方法 -- 添加/刪除/獲取
- 服務器配置映射
- 其他
- Vuex -- 狀態管理
- Option Api -- VUEX
- composition API -- VUEX
- module -- VUEX
- 刷新后vuex 數據同步
- 小技巧
- Pinia -- 狀態管理
- 開始使用
- pinia -- state
- pinia -- getter
- pinia -- action
- pinia -- 插件 ??
- Vue 源碼解讀
- 開發感悟
- 練手項目