目錄
v-moel
v-model的原理
v-model用在組件標簽上
方式
?defineModel()簡寫
ref屬性
獲取原生DOM
獲取組件實例
nextTick()?
v-moel
v-model:雙向數據綁定指令
- 數據變了,視圖跟著變(數據驅動視圖)
- 視圖變了,數據也會跟著變
v-model的原理
作用在原生輸入框時,本質就是:value="數據"+@input="數據=輸入框的值"的組合
如下:
第1行代碼和第2行代碼所實現的效果是一樣的.
- :value="msg",實現了v-model的數據驅動視圖
- @input="msg = $event.target.value",實現了v-model的視圖驅動數據,$event.target獲得觸發input監聽事件的dom對象。
<template>
<input type="text" v-model="msg"/>? //1
<input type="text" :value="msg" @input="msg = $event.target.value"/> //2
</template>
<script setup>
? ? import { ref } from 'vue'
? ? const msg = ref("aaaa")
</script>
v-model用在組件標簽上
<XXX v-model="數據"/>,XXX是一個組件
等價于
<XXX :modelValue="數據" @update:modelValue="數據=新值" />
- 這種方式使用到了父傳子的方式, modelValue屬于自定義類型,子組件需要接收。
<XXX :modelValue="數據" @update:modelValue="數據=新值" />方式
父組件
<script setup>import { ref } from 'vue'import MyOption from './components/MyOption.vue';const activetedId=ref('333')
</script>
<template><MyOption :modelValue="activetedId" @update:modelValue="activetedId=$event"/>
</template><style scoped></style>
子組件
<template>
<select :value="modelValue" @change="emit('update:modelValue', $event.target.value)" v-if="modelValue.length>0"><option value="111">北京</option><option value="222">上海</option><option value="333">廣州</option> <option value="444">深圳</option><option value="555">杭州</option><option value="666">南京</option>
</select>
</template><script setup>defineProps({modelValue: String,Required: true})const emit=defineEmits()
</script><style scoped></style>
?defineModel()簡寫
- 父:<xxx v-model="父的響應式數據" />
- 子:const model=defineModel(),子組件可以對這個model響應式數據做讀、寫操作
父組件
<script setup>import { ref } from 'vue'import MyOption from './components/MyOption.vue';const activetedId=ref('333')
</script>
<template><MyOption v-model="activetedId"/>
</template><style scoped></style>
子組件
<template>
<select v-model="model"><option value="111">北京</option><option value="222">上海</option><option value="333">廣州</option> <option value="444">深圳</option><option value="555">杭州</option><option value="666">南京</option>
</select>
</template><script setup>//defineModel()的返回值是一個ref數據,并且可以在子組件直接操作這個ref數據,子組件修改這個數據會引起父組件的數據的同步更新const model=defineModel()
</script><style scoped></style>
ref屬性
這里要與ref函數做區別,這里ref屬性是作用在標簽上的屬性,是vue新增的,原生不具備這個屬性的。
作用
用來獲取原生DOM或組件實例(進而調用組件提供的方法)
獲取原生DOM
- 先創建一個ref響應式數據
- 將標簽的ref屬性綁定創建好的ref響應式數據
- 通過divRef.value獲取到<div></div>
<template>
<div ref="divRef">Some text...
</div>
</template><script setup>import { onMounted, ref } from 'vue'const divRef=ref(null)onMounted(() => {divRef.value.style.color="blue" })
</script>
獲取組件實例
如下使用示例:
MyFrom提供的校驗方法和賬號、密碼輸入框,根組件依靠ref屬性調用子組件提供的方法
MyFrom.vue
組件需要讓外部使用的函數,需要對外暴露,類似于導出,defineExpose({ })
<template><div class="from-container">賬號:<input type="text" v-model="username"><br /><br />密碼:<input type="password" v-model="password"><br /><br /></div>
</template><script setup>import { ref} from 'vue'const username = ref('')const password = ref('') const validate=()=>{return username.value=="admin" && password.value=="123456"}defineExpose({validate})
</script><style scoped></style>
App.vue
<template>
<div><MyForm ref="fromRef"/><button @click="onLogin">登錄</button>
</div>
</template><script setup>import {ref} from 'vue'import MyForm from './components/MyForm.vue'const fromRef=ref(null)const onLogin=()=>{if(fromRef.value.validate()){console.log('success')}else{console.log('fail')}}
</script><style scoped></style>
nextTick()?
nextTick() 是vue3提供的一個方法
作用
當數據變了,想獲取更新后的DOM,需要把代碼寫在這個方法的回調中。
什么時候使用這個方法
當數據變了,想DOM操作,如果直接拿不到,在這個方法的回調中去獲取。
如下,當v-if的判斷值為true后,DOM還未更新,此時就需要在nextTick() 中操作更新后的DOM
<script setup>import {ref,nextTick} from 'vue'const onEdit=()=>{isShowEdit.value=true//此時顯示文本框,但是在vue3中,DOM的更新是異步的,此時直接獲取更新后的DOM是拿不到的,因為還沒有更新nextTick(()=>{inputRef.value.focus()})}
</script>