likes
comments
collection
share

vue3个人心得---功能详解(六)模板引用ref

作者站长头像
站长
· 阅读数 39

ref的作用

原始对 DOM 的操作,使用的是通过ID与getElementById方法来操作,如下:

<script setup>
function uu(){
console.log( document.getElementById('itemR'))}//借助getElementById方法及ID操作DOM
</script>
<template>
 <button v-on:click="uu"></button>
    <li  id="itemR">
     我来试试
    </li> 
</template>

ref不需要用到 getElementById 直接使用ref名即可对 DOM 进行操作,如下:

import {ref} from 'vue'
const itemR=ref()
function uu(){
console.log(itemR.value)}//直接使用ref名操作DOM
</script>
<template>
 <button v-on:click="uu"></button>
    <li  ref="itemR">
     我来试试
    </li>
</template>

ref的写法

模板部通过标签的ref属性给DOM赋标识符 <li ref="标识符">选项式API通过$fefs对象来操作ref标识的DOM

this.$refs.标识符

组合式API不再使用$refs对象,而是直接使用标识符来操作,不过需要先用ref声名这个标识符。

const 标识符=ref()
      标识符.value

注意此处的ref声明的响应变量不是普通的响应变量,而是DOM响应变量,他的值是DOM对象。

ref生命周期问题

ref属性是在DOM 渲染阶段生成,因此在渲染生成前使用ref会得到空的DOM,只有在渲染完成后才能使用ref操作DOM,如下ref将操作不了DOM:

<script setup>
import {ref,reactive,onMounted,onBeforeMount} from 'vue'
const itemR=ref()
console.log(itemR.value)//打印不出<li>标签
</script>
<template>
     <li  ref="itemR">
     我来试试
    </li>
  </template>

放在onMounted里,才能成功操作DOM,如下:

<script setup>
import {ref,reactive,onMounted,onBeforeMount} from 'vue'
const itemR=ref()
onMounted(()=>{
console.log(itemR.value)})//成功打印出<li>标签
</script>
<template>
 <button v-on:click="uu"></button>
    <li  ref="itemR">
     我来试试
    </li>
</template>

ref的标识名

1、字符型标识模板部的ref赋值的标识为字符,逻辑部定义同名标识,用于存放此DOM对象,如上所有的例子都是字符型标识。当有重名标识时,逻辑部的同名标识只存放最后一个同名的DOM对象。如下:

<script setup>
import { ref, onMounted } from 'vue'
const item = ref()
function oi(){console.log(item.value.textContent)}//打印出来的是最后一个ref=item的<li>
</script>
<template>
  <ul>
    <button @click="oi">我来测试</button>
    <li  ref="item">
      我是一
    </li>
    <li  ref="item">
      我是二
    </li>
  </ul>
</template>

2、数组型标识只存在于v-for创建的ref,逻辑部定义同名标识,但这个标识是个数组,存放v-for创建的多个DOM对象,如下:

<script setup>
import { ref, onMounted } from 'vue'
const wo = ref(['我是一','我是二'])
const item = ref()
function oi(){console.log(item.value.map( (x) =>{ return x.textContent}))}//打印出了两个DOM
</script>
<template>
  <ul>
    <button @click="oi">我来测试</button>
    <li v-for="tt in wo" ref="item">
      {{tt}}
    </li>
  </ul>
</template>

3、变量型标识可以使用v-bind将ref属性绑定一个响应变量,逻辑部要对响应变量的值进行定义,这个值用于存放DOM对象。如下:

<script setup>
import {ref} from 'vue'
const wocao = ref('oneRef')
const oneRef=ref()
const twoRef=ref()
function oi(){if (wocao.value=='oneRef')
{console.log("打印ref='oneRef'的DOM:",oneRef.value,"打印ref='twoRef'的DOM:",twoRef.value)}
else{console.log("打印ref='oneRef'的DOM:",oneRef.value,"打印ref='twoRef'的DOM:",twoRef.value)}}
</script>
<template>
  <ul>
    <button @click="oi">测试ref值</button><br>
    <input type="radio" value="oneRef" v-model="wocao" id="1">
    <label for="1">ref='oneRef'</label><br>
    <input type="radio" value="twoRef" v-model="wocao" id="2" >
    <label for="1">ref='twoRef'</label>
    <li :ref="wocao" id="qa">
      我的ref值是??
    </li>
  </ul>
</template>

注意上例,要对wocao的值 oneRef与twoRef 进行定义,用于存放DOM<li>

此ref非彼ref

模板引用中的ref与响应变量的ref虽然定义的写法是一样的,但这两种ref性质完全不同。1、响应变量的ref定义时可以赋值"const wocao = ref('oneRef')",也可以重新赋值"wocao.value=twoRef",是真正义意上的值。2、模板引用的ref的值默认为DOM对象,如上"const wocao = ref()"定义后wocao的值为<li>,并且始终用于存放DOM对象<li>,对它再赋值无效。

通过ref操作DOM

在逻辑部, 标识符.value 代表着对这个标识符的DOM引用,因此所有的DOM操作都可以通过这个 标识符.value 来实现。1、通过 标识符.value 操作其它DOM获得这个DOM的父节点:"标识符.value.parentNode";获得第一个子节点:"标识符.value.firstChild";获得最后一个子节点:"标识符.value.lastChild"。还有很多操作其它DOM的属性与方法,在此不一一举例。2、通过 标识符.value 操作本DOM的属性添加属性:"标识符.value.setAttribute('a','b')",注意a与b要用引号;取属性值:"标识符.value.属性名",如取一个标签的ID属性,可以这样:标识符.value.id注:以上方式只能取系统默认的属性值,如是自定义的属性,需用getAttribute("自定义属性名")方法才能取出属性值。如下:

<li ref="wo" id="ni" zid="ta">
系统自有属性"id"的取出方法: wo.value.id
自定属性"zid"的取出方法: wo.value.getAttribute("zid")
ref的属性无法取出:如 wo.value.ref ,得不到ref的值 wo 不知有没有高人指点?请在此文下留言,感激不尽。

获取本DOM内容:"识符.value.innerHTML"(会把子的文本及html代码一起取出);"识符.value.textContent"(只取出本身及子的文本内容)还有很多操作本DOM的属性与方法,在此不一一举例。

ref子组件

转载自:https://segmentfault.com/a/1190000043206208
评论
请登录