本文最后更新于:2024年3月18日 晚上
在由选项式API转向组合式API时,发现响应式数据的定义往往通过ref来实现,但是直接定义变量的方式也能够在页面中实现显示,而后又有readonly来进行变量定义的方式,因此实验了一下其中的区别。
自定义变量
使用自定义变量时直接进行定义即可let customVal:number = 10
- 自定义变量的值可以直接在模板中显示(包括文本和输入框等)
- 点击按钮改变自定义变量的值时,后台数据会发生变化,但页面不会刷新,即显示的还是原来的值
- 通过输入框改变值时(v-model绑定)可以将数值传输到后台数据并更改其值。
ref定义变量
使用ref定义变量时需要使用ref()函数let refVal:Ref<number> = ref(10)
- ref变量的值可以直接在模板中显示(包括文本和输入框等)
- 点击按钮改变自定义变量的值时,后台和页面数据都发生变化,触发监听器
- 通过输入框改变值时(v-model绑定)可以将数值传输到后台数据并更改其值,触发监听器
vue中同样可以使用reactive来定义响应式变量,不过reactive只能定义对象、数组等类型,而ref既可以接受对象类型又可以接受原始数据类型(number,string,boolean等),所以reactive相当于是ref的子集,ref在接受对象类型的时候内部也是通过reactive来实现。
readonly定义对象
使用readonly定义变量时需要使用readonly()函数let readonlyVal:Readonly<{value:number}> = readonly({value:10})
- readonly变量的值可以直接在模板中显示,但只能作为文本显示,而不能投射到表单组件,即input等。
- readonly变量只读,无法进行修改,后台试图修改readonly变量的操作会直接报错(编译时异常)
- 无法在输入框中正常显示也无法修改
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
| <script setup lang="ts"> import { ref,readonly, Ref, watch } from 'vue'
let customVal = 10; function changeCustomValValue(){ customVal++; document.getElementById('info').innerText="现在customVal的值为"+customVal; } watch(()=>customVal,()=>{ document.getElementById('customTip').innerText="customVal的值发生变化"; })
let refVal:Ref<number> = ref(10); function changeRefValValue(){ refVal.value++; } watch(refVal,()=>{ document.getElementById('refTip').innerText="refVal的值发生变化"; })
let readonlyVal:Readonly<{value:number}> = readonly({value:10}); function changeReadOnlyValValue(){ try{ readonlyVal.value++; } catch(e){ document.getElementById('error').innerText=e; } } watch(readonlyVal,()=>{ document.getElementById('readonlyTip').innerText="readonlyVal的值发生变化"; }) </script>
<template> <div>自定义变量</div> <div class="container"> <button class="button" @click="changeCustomValValue"> 修改数据 </button> <div class="output"> <div>数据值为:<input class="input" v-model="customVal"/></div> <div id="info"></div> <div id="customTip"></div> </div> </div> <div>ref定义变量</div> <div class="container"> <button class="button" @click="changeRefValValue"> 修改数据 </button> <div class="output"> <div>数据值为:<input class="input" v-model="refVal"/></div> <div id="refTip"></div> </div> </div> <div>readOnly定义变量</div> <div class="container"> <button class="button" @click="changeReadOnlyValValue"> 修改数据 </button> <div class="output"> <div>数据值为:<input class="input" v-model="readonlyVal"/></div> <div id="error"></div> <div id="readonlyTip"></div> </div> </div> </template>
<style> .container{ background-color: #F1F1F1; width: 95%; height: 200px; display: flex; justify-content: space-between; align-items: center; padding: 20px 20px; margin-bottom: 20px; } .button{ margin-left: 20%; width: 20%; height: 20%; background-color: white; border: none; box-shadow: 0px 0px 15px lightgray; cursor: pointer; } .button:hover{ background-color: lightcyan; transition: background-color 0.3s ease-in-out; } .button:active { background-color: skyblue; transition: background-color 0.3s ease-in-out; } .output{ align-self:self-end; width: 40%; height: 100%; background-color: white; display: flex; flex-direction: column; justify-content: center; align-items: center; } </style>
|