Vue3中的ref為何要用.value進行值的調用呢
Vue3中ref為何要用.value進行值的調用
在Vue2中,所有的數據都通過一個Data進行統一的返回,並且在data中對某個組件要用的數據進行統一的管理,常見的使用形式是這樣的:
<template> <div class="div"> <todos :Obj="tos" :removeObj="removeObj"></todos> </div> </template> <script> import search from '@/components/search' import todos from '@/components/todos' import all from '@/components/all' export default { name: 'App', data () { return { tos: [ { id: '001', value: '第一個', done: true }, { id: '002', value: '第二個', done: true }, { id: '003', value: '第三個', done: false }, { id: '004', value: '第四個', done: true }, ], } }, computed: { }, components: { search, todos, all, }, methods: { removeObj (obj) { console.log(obj.id) this.tos = this.tos.filter(item => item.id !== obj.id) console.log(this.tos) }, }, } </script> <style scoped> // 樣式 </style>
可以看出來這裡定義的內容都在一個數組中進行,或者是一個函數,將要使用的數據返回出來,這裡無論怎麼進行操作處理,最終進行數據代理的時候得到的都是一個對象,Vue2中直接通過defineProperty進行處理,並綁定對應的監聽事件進行響應式的處理。
而Vue3中,數據的定義可以是單獨的,Vue可以讓我們隨時需要隨時定義,這也就帶來瞭另一個問題,我需要的一個數據可能不是對象
<script lang="ts" setup> let str = ref('響應式字符串') let obj = reactive({ name: '張三', age: 10, }) </script>
如果要定義的數據不是對象,還需要代理會怎麼樣?
在Vue2中數據的定義都在對象中統一進行,也就不會出現這種情況,如果一定要代理一個單獨的數據呢?
Vue2中的數據代理通過defineProperty進行實現,也就是說我們要讓defineProperty代理一個普通的數據,而不是一個對象,在defineProperty的MDN的文檔中是這樣定義的:
Object.defineProperty()
方法會直接在一個對象上定義一個新屬性,或者修改一個對象的現有屬性,並返回此對象。
通過這個可以明確看出,隻能進行對象的代理,不能進行普通數據的代理,如果使用普通數據類型會直接報以下錯誤[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-p1Lm0OSJ-1661407967498)(Vue3中的ref為何要用.value進行值的調用?.assets/image-20220825094409254.png)]
在Vue3中數據代理可以使用單一數據瞭,並且也改進瞭數據代理的方式,使用的是Peoxy完成瞭數據代理,而MDN中對Proxy也進行瞭定義:
Proxy
對象用於創建一個對象的代理,從而實現基本操作的攔截和自定義(如屬性查找、賦值、枚舉、函數調用等)。
可以看出,Proxy依然是為對象服務,而不是普通的內容,這樣問題似乎就解決瞭
本操作的攔截和自定義(如屬性查找、賦值、枚舉、函數調用等)。
可以看出,Proxy依然是為對象服務,而不是普通的內容,這樣問題似乎就解決瞭
即使是Vue3中使用的Proxy的代理方式也不能進行普通數據的代理,所以當調用Ref的時候其實仍然創建瞭一個Proxy對象,並且Vue幫你給這個對象瞭一個value屬性,屬性值就是你定義的內容,改變的時候監視的改變依然是通過Proxy的數據劫持來進行響應式的處理,而模板中使用的時候Vue會默認調用對應的value屬性,從而完成模板中的內容的直接調用
Vue3 ref告別.value
眾所周知,ref要求我們訪問變量時需要加上.value,這讓很多開發者覺得難受.
let count = ref(1) const add = () => { count.value += 1 }
後來vue3 提瞭一個 Ref Sugar 的 RFC,即 ref 語法糖,在ref前加上$,目前還處理實驗階段。
Ref 語法糖在項目中的使用
1. 該功能默認關閉,需要手動開啟。
// vite.config.ts import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' export default defineConfig({ plugins: [ vue({ refTransform: true // 開啟ref轉換 }) ] })
2. 在.vue文件中使用
<template> <div>{{count}}</div> <button @click="add">click me</button> </template> <script setup> let count = $ref(1) const add = () => { count++ } </script>
以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。