如果阅读有疑问的话,欢迎评论或私信!!
本人会很热心的阐述自己的想法!谢谢!!!
文章目录
- 模板引用
- 前言
- 访问模板引用
- 模板引用与v-if、v-show的结合
- v-for中的模板引用
- 函数模板引用
模板引用
前言
在前面学过的 v-on
v-if
v-show
等指令都是对DOM操作的抽象指令
,而有时我们需要直接访问底层DOM元素。例如在我们刚挂载完组件实例时,想要将一个input输入框聚焦
。参照之前的知识好像无法完成,在该章节我们可以使用vue提供的ref属性。我们称为模板引用
。
语法:
<input ref="input">
访问模板引用
挂载结束后,ref属性
都会被暴露在this.$refs
之上,例如我们之前的场景:
<template><p>Ask a yes/no question:<input v-model="some.nested.question" :disabled="loading" ref="myInput"/><button @click="some.nested.question = 'b?'">点我</button></p><p>{{ answer }}</p>
</template>
<script>export default {mounted() {this.$refs.myInput.focus()}
}
</script>
注意,这里ref属性值
只有在挂载之后才可以被访问,在挂载之间一直是undefined
状态。因为我们的DOM在挂载前还没有被渲染,也就是ref
还没有通知给引擎。例如
<script>export default {created(){this.$refs.myInput.focus();}
}
//Uncaught TypeError: Cannot read properties of undefined (reading 'focus')
</script>
模板引用与v-if、v-show的结合
我们通过上面可以知道ref属性
只有在被渲染之后才可以访问到其中的值,那么我们可以联想到前面所讲的v-if
和v-show
的知识。如果我们ref所在的DOM元素包含v-if
或者v-show
会产生什么样的结果呢?结合我们学习到的知识,我觉得应该v-if
会抛出错误,v-show
不会抛出错误,因为两个的渲染机制不一样。例如:
<template><p><input v-model="some.nested.question" :disabled="loading" ref="myInput" v-if="flag"/> <!-- Uncaught TypeError: Cannot read properties of undefined (reading 'focus') --><input v-model="some.nested.question" :disabled="loading" ref="myInput2" v-show="flag"/><button @click="flag = !flag">更改input显示/隐藏</button></p>
</template>
<script>export default {data(){return{flag:false}},mounted() {this.$refs.myInput.focus();this.$refs.myInput2.focus();}
}
</script>
可以看出结果和我们预料的一样,只有v-if
才会报错。
v-for中的模板引用
官方文档中解释了在对v-for
中使用模板引用时,$refs
中该属性是一个数组,也就是我们可以对其使用数组的方法。例如:
<template><ul><li v-for="currentValue in myArr" ref="items">{{ currentValue.myNumber }}</li></ul></p>
</template><script>
export default {data() {var myArr = [{myNumber: 1},{myNumber: 2},{myNumber: 3},{myNumber: 4},];return {myArr};},mounted() {console.log(this.$refs.items); //(4) [li, li, li, li]},
};
</script>
在上方代码中我们可以看出
this.$refs.items
会输出一个数组,那么我们可以使用this.$refs.items[0]
访问得到第一个元素。
但是官方文档说不保证this.$refs.items
与源数组相同的顺序。也就是我们在使用这个方法时需要查看一下是不是该元素,也可以使用数组中的indexOf
来查找位置之后再使用该方法。
函数模板引用
对于ref中的值,我们可以是任意字符串,在mounted中使用this.$refs来引用。如果我们想要将这个DOM元素传入一个属性或者一个方法,我们可以使用函数模板引用。例如:
<button :ref="(el)=>{console.log(el)}">按钮</button> //<!-- <button>按钮</button> -->
在使用函数模板引用时,ref是一个动态属性
,需要使用v-bind
来绑定。当绑定的元素被卸载时,函数也会被调用一次,此时的 el
参数会是 null
。你当然也可以绑定一个组件方法而不是内联函数。