vue - ref 说明
ref
是英文单词 reference
,代表引用.
在 vue
中, ref
的使用分四种情况.
-
ref
作用于普通的HTML
元素. -
ref
作用于component
-
v-for
配合:ref
绑定表达式作用于普通的HTML
元素. -
v-for
配合:ref
绑定表达式作用于component
1. ref
作用于普通的 HTML
元素.
当 ref
作用于普通的 HTML
元素是, this.$refs.ref
拿到的就是普通的 DOM
元素.
<!-- 作用于普通的html -->
<input type="text" ref='input'><br>
<button @click='handlerRefOnNormalHTML'>ref作用于普通的HTML</button><br>
handlerRefOnNormalHTML() {
// 当 ref 总用于普通的HTML元素上时,拿到的就是普通的dom对象.
this.$refs.input.value = '普通的HTML元素'
}
结果:
2. ref
作用于component
当 ref
作用于 component
的时候, this.$refs.ref
拿到的就是对应的 component
实例对象.
<div id='app'>
<!-- 当ref作用于组件上时,ref拿到的就是组件 -->
<helloworld ref='comHello'></helloworld><br>
<button @click='handlerRefOnComponent'>ref作用于组件上</button><br>
</div>
<template id='helloworld'>
<div>
<h1 ref='hello'>{{msg}}</h1>
</div>
</template>
Vue.component('helloworld', {
template: '#helloworld',
data() {
return {
// 组件内部的数据
msg: '我是组件的msg'
}
},
methods: {
// 组件内部的方法
changeBGColor() {
this.$refs.hello.style.backgroundColor = 'red';
}
}
})
handlerRefOnComponent() {
// 当ref作用于组件上时,ref拿到的就是组件
// 修改组件实例的数据
this.$refs.comHello.msg = '父组件把我的msg改改成这样了.'
// 调用最佳实例的方法.
this.$refs.comHello.changeBGColor()
}
我们在 app.vue
的 handlerRefOnComponent
通过 this.$refs.comHello
.
拿到当前组件的实例.
修改此组件身上的 data-msg
属性.
以及调用此组件的 changeBGColor()
方法.
结果:
3. v-for
配合 :ref
绑定表达式作用于普通的 HTML
元素.
当我们使用 v-for
遍历一些普通的 HTML
元素,并使用 :ref
绑定表达式绑定这些元素时.
可以使用 this.$refs[bindValue][0]
来访问到在循环里绑定到的这些HTML元素.
<h3>ref在for循环中,作用于普同的HTML元素,$refs[index][0] 拿到的就是普通的DOM元素</h3>
<ul>
<!-- 当 ref 在循环中,绑定的是一个普通的HTML元素时 -->
<li v-for="(item,index) of list" :key="index" :ref="index" @click="hanlderRefOnHTMLLoop(index)">
{{item}}
</li>
</ul>
hanlderRefOnHTMLLoop(index) {
// 当ref 作用在循环上时,通过熟悉绑定的ref dom 对象是被放在了一个数组当中了.
this.$refs[index][0].style.backgroundColor = 'orange'
}
结果:
4. v-for
配合 :ref
绑定表达式作用于 component
当我们使用 v-for
搭配 :refs
属性绑定表达式作用于 component
上.
我们可以使用 this.$refs[bindValue][0]
拿到对应的组件.
<h3>ref在for循环中,作用于普同的HTML元素,$refs[index][1] 拿到的就是组件实例</h3>
<ul>
<li v-for="(item,index) in 5" :key="index" @click="hanlderRefOnComponentLoop(index)">
<hello-world :ref='index'></hello-world>
</li>
</ul>
</div>
<template id='HelloWorld'>
<div>
<h1 ref='h1'>{{msg}}</h1>
</div>
</template>
Vue.component('HelloWorld', {
template: '#HelloWorld',
data() {
return {
msg: 'Hello World 组件的 msg'
}
},
methods: {
changeBGColor() {
this.$refs.h1.style.backgroundColor = 'orange'
}
}
})
hanlderRefOnComponentLoop(index) {
// ref在for循环中,作用于普同的HTML元素,$refs[index][0] 拿到的就是组件实例
this.$refs[index][0].msg = '修改了组件内部的值'
this.$refs[index][0].changeBGColor()
}
我们通过 this.$refs[index][0]
拿到对应的组件后.
接可以拿到当前组件的实例.
修改此组件身上的 data-msg
属性.
以及调用此组件的 changeBGColor()
方法.
结果:
为什么在 v-for 里,那引用的HTML或者组件非要是 this.refs[bindValue][0] ?
为什么在 v-for
& :ref
的时候,this.$refs[bindValue]
返回的是一个数组呢?
当我们在组件内部,同时有一个以上的这样的搭配时,就能说明问题了.
<div id='app'>
<h3>ref在for循环中,作用于普同的HTML元素,$refs[index][0] 拿到的就是普通的DOM元素</h3>
<ul>
<!-- 当 ref 在循环中,绑定的是一个普通的HTML元素时 -->
<li v-for="(item,index) of list" :key="index" :ref="index" @click="hanlderRefOnHTMLLoop(index)">
{{item}}
</li>
</ul>
<hr>
<h3>ref在for循环中,作用于普同的HTML元素,$refs[index][1] 拿到的就是组件实例</h3>
<ul>
<li v-for="(item,index) in 5" :key="index" @click="hanlderRefOnComponentLoop(index)">
<hello-world :ref='index'></hello-world>
</li>
</ul>
<button @click="lookrefs">查看 this.$refs[bindValue] 数组</button>
<button @click="lookLength">查看 this.refs[bindValue].length</button>
<button @click="lookRefsArry0">查看 this.refs[bindValue][0]</button>
<button @click="lookRefsArry1">查看 this.refs[bindValue][1]</button>
</div>
lookrefs() {
console.log(this.$refs[0])
},
lookLength() {
console.log(this.$refs[0].length)
},
lookRefsArry0() {
console.log(this.$refs[0][0])
},
lookRefsArry1() {
console.log(this.$refs[0][1])
}
结果:
-
this.$refs[0]
返回的是一个数组, 里面包含了两个元素:liDOM元素 & HelloWorld组件实例 -
this.$refs[0].length
所以.length = 2
-
this.$refs[0][0]
拿到的是第一个li
DOM 元素 -
this.$refs[0][1])
拿到的是第一个HelloWorld
组件实例.
总结
-
ref
单纯的使用时,是绑定单个DOM
元素 或者是 单个组件实例
.那么拿到的就是单个DOM
元素或者是单个组件实例
. -
:ref
属性绑定表达式一般搭配v-for
一起来使用,用于循环绑定DOM
元素或者是组件实例
.-
this.$refs[bindValue]
返回的是一个数组. - 通过
this.$refs[bindValue][index]
可以拿到对应的DOM
ORComponent
. - 如果在一个组件内有一个以上的
v-for
&:ref
搭配使用,就需要用 this.$refs[bindValue][index]
去选择对应的是在哪一个v-for
里遍历的元素或者是组件.
-