【Vue】v-model、ref获取DOM

发布于:2024-12-09 ⋅ 阅读:(126) ⋅ 点赞:(0)

目录

v-moel

v-model的原理

v-model用在组件标签上

方式

 defineModel()简写

ref属性

获取原生DOM

获取组件实例

nextTick() 


v-moel

v-model:双向数据绑定指令

  1. 数据变了,视图跟着变(数据驱动视图)
  2. 视图变了,数据也会跟着变

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()简写

  1. 父:<xxx v-model="父的响应式数据" />
  2. 子: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

  1. 先创建一个ref响应式数据
  2. 将标签的ref属性绑定创建好的ref响应式数据
  3. 通过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>


网站公告

今日签到

点亮在社区的每一天
去签到