目录
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>