1 Ref与Reactive
Ref 用来创建基础类型的响应式数据,模板默认调用value显示数据。方法中修改需要修改value的值才能修改
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 
 | <!-- 模板语法> <template>
 <div>{{state}}</div>
 </template>
 //js 脚本
 setup(){
 let state = ref(10)
 state.value = 11
 return {state}
 }
 
 | 
Reactive 用来创建引用类型的响应式数据
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 
 | <!-- 模板语法> <template>
 <div>{{state.name}}</div>
 </template>
 //js 脚本
 setup(){
 let state = reactive({name:'小明'}})
 state.name = '小李'
 return {state}
 }
 
 | 
区别:
1 Ref的本质是通过Reactive创建的,Ref(10)=>Reactive({value:10});
Ref在模板调用可以直接省略value,在方法中改变变量的值需要修改value的值,才能修改成功。Reactive在模板必须写全不然显示整个数据。
2 Reactive的本质是将每一层的数都解析成proxy对象,Reactive 的响应式默认都是递归的,改变某一层的值都会递归的调用一遍,重新渲染dom。
2 shallowRef 与shallowReactive
Ref与Reactive创建的都是递归响应的,将每一层的json 数据解析成一个proxy对象,shallowRef 与shallowReactive创建的是非递归的响应对象,shallowReactive创建的数据第一层数据改变会重新渲染dom
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 
 |  var state = shallowReactive({a:'a',
 gf:{
 b:'b',
 f:{
 c:'c',
 s:{d:'d'}
 }
 }
 })
 state.a = '1'
 //改变第一层的数据会导致页面重新渲染
 //state => Proxy {a:"a",gf:{...}}
 //如果不改变第一层 只改变其他的数据 页面不会重新渲染 例如 state.gf.b = 2
 
 | 
通过shallowRef创建的响应式对象,需要修改整个value才能重新渲染dom
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 
 | var state = shallowRef({a:'a',
 gf:{
 b:'b',
 f:{
 c:'c',
 s:{d:'d'}
 }
 }
 })
 state.value.a = 1
 
 
 
 state.value = {
 a:'1',
 gf:{
 b:'2',
 f:{
 c:'3',
 s:{d:'d'}
 }
 }
 }
 
 
 | 
如果使用了shallowRef想要只更新某一层的数据可以使用triggerRef,页面就会重新渲染
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 
 | var state = shallowRef({a:'a',
 gf:{
 b:'b',
 f:{
 c:'c',
 s:{d:'d'}
 }
 }
 })
 state.value.gf.f.s.d = 4
 triggerRef(state)
 
 | 
3 toRaw —只修改数据不渲染页面
只修改响应式的数据不想引起页面渲染可以使用toRaw这个方法
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 
 | var obj = {name:'test'}var state = reactive(obj)
 var obj2 = toRaw(state)
 obj2.name = 'zs'//并不会引起页面的渲染
 
 ----
 //如果是用ref 创建的 就要获取value值
 var obj = {name:'test'}
 var state = ref(obj)
 var obj2 = toRaw(state.value)
 
 | 
4 markRaw — 不追踪数据
如果不想要数据被追踪,变成响应式数据可以调用这个方法,就无法 追踪修改数据重新渲染页面
| 12
 3
 4
 
 | var obj = {name:'test'}obj = markRaw(obj)
 var state = reactive(obj)
 state.name = 'zs'//无法修改数据 页面也不会修改
 
 | 
5 toRef — 跟数据源关联 不修改UI
如果使用ref 创建的响应式变量,不会与源数据关联,如果想要与源数据关联但数据更改不更新UI,就要使用toRef创建
| 12
 3
 4
 5
 6
 7
 8
 
 | var obj = {name:'test'}var state = ref(obj.name)
 state.name = 'zs' //此时obj的name 属性值并不会改变,UI会自动更新
 
 ///
 var obj = {name:'test'}
 var state = toRef(obj,'name') //只能设置一个属性值
 state.name = 'zs'//此时obj里面的name属性值会发生改变,但是UI 不会更新
 
 | 
6 toRefs —设置多个toRef属性值
| 12
 3
 4
 
 | var obj = {name:'test',age:16}var state = toRefs(obj)
 state.name.value = 'zs'//obj的name的属性值也会改变,但UI不会更新
 state.age.value = 18//obj的age的属性值也会改变,但UI不会更新
 
 | 
7 customRef —自定义一个ref
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 
 | function myRef(value){
 
 
 
 return customRef((track,trigger)=>{
 return {
 get(){
 track()
 return value
 },
 set(newVal){
 value = newVal
 trigger()
 }
 }
 })
 
 }
 setup(){
 var age = myRef(18)
 age.value = 20
 }
 
 | 
8 ref 捆绑页面的标签
vue2.0 可以通过this.refs拿到dom元素,vue3取消了,而直接用ref()方法生成响应式变量与dom 元素捆绑
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 
 | <template><div ref="box"></div>
 
 </template>
 import {ref,onMounted} from 'vue'
 
 
 
 <script>
 setup(){
 var box = ref(null)
 onMounted(()=>{
 console.log('onMounted',box.value)
 })
 console.log(box.value)
 return {box}
 
 }
 
 </script>
 
 
 | 
参考文章:
Vue3.0中Ref与Reactive的区别示例详析_vue.js_脚本之家 (jb51.net)