Directorio de artículos
Prefacio
Si necesitamos acceder directamente a los elementos DOM subyacentes en el componente, podemos usar vue para proporcionar atributos de referencia especiales para el acceso.
1.Referencia de plantilla de acceso
- Utilice el atributo ref en el elemento de vista para establecer el elemento DOM
a al que se debe acceder. El atributo ref se puede configurar usando un valor de carácter
. El atributo ref se puede vincular a una función en forma de v-bind: o: Ref. El primer parámetro de la función es el elemento. - Si el valor del atributo ref del elemento tiene la forma de una cadena
a. En API JS opcional, se puede acceder a la referencia de la plantilla a través de esto.$refs
b. En API JS combinado, necesitamos declarar una variable ref con el mismo nombre para Obtener una referencia a esta plantilla
Referencia de plantilla de acceso [opcional]
<script>
export default {
data: () => ({
accountEl: null,
passwordEl: null
}),
methods: {
changeAccountInputStyle() {
this.accountEl = this.$refs.account // 获取账号输入框的 DOM
console.log(this.accountEl)
this.accountEl.style = "padding: 15px"
this.accountEl.className = "rounded"
this.accountEl.focus()
},
passwordRef(el) {
this.passwordEl = el // el 元素是密码输入框
},
changePasswordInputStyle() {
console.log(this.passwordEl)
console.log(this.$refs) // 函数式声明的 ref,不会在this.$refs中获取
this.passwordEl.style = "padding: 15px"
this.passwordEl.className = "rounded"
this.passwordEl.focus()
},
}
}
</script>
<template>
<!-- ref 字符串值形式 -->
账号输入框:<input type="text" ref="account">
<button @click="changeAccountInputStyle">改变账号输入框的样式</button>
<hr>
<!-- ref 函数形式:元素渲染后,会立即执行该函数 -->
密码输入框:<input type="password" :ref="passwordRef">
<button @click="changePasswordInputStyle">改变密码输入框的样式</button>
</template>
<style>
.rounded {
border-radius: 15px;
}
</style>
Referencia de plantilla de acceso [combinada]
<script setup>
import {
ref } from 'vue';
// 账号输入框
let account = ref(null) // ref 变量名和账号输入框中的 ref 属性值一样
function changeAccountInputStyle() {
console.log(account.value)
account.value.style = 'padding: 10px'
account.value.className = 'rounded'
account.value.focus()
}
// ------------------------------------------------------------------------
// 密码输入框元素
let passwordEl = ref(null)
function passwordRef(el) {
passwordEl.value = el // el 元素是密码输入框
}
function changePasswordInputStyle() {
console.log(passwordEl.value)
passwordEl.value.style = 'padding: 10px'
passwordEl.value.className = 'rounded'
passwordEl.value.focus()
}
</script>
<template>
<!-- ref 字符串值形式 -->
账号输入框:<input type="text" ref="account">
<button @click="changeAccountInputStyle">改变账号输入框的样式</button>
<hr>
<!-- ref 函数形式:元素渲染后,会立即执行该函数-->
密码输入框:<input type="password" :ref="passwordRef">
<button @click="changePasswordInputStyle">改变密码输入框的样式</button>
</template>
<style>
.rounded {
border-radius: 15px;
}
</style>
2. Referencia de plantilla en v-for
Cuando se utilizan referencias de plantilla en v-for:
- Si el valor de referencia tiene la forma de una cadena, contiene todos los elementos correspondientes a la lista completa después de que se representa el elemento [matriz]
- Si el valor de referencia tiene la forma de una función, la función correspondiente se ejecutará cada vez que se represente un elemento de la lista [no recomendado]
Nota: Requiere v3.2.25 y superior
Referencia de plantilla en instrucciones de representación de lista [opcional]
<script>
export default {
data: () => ({
books: [
{
id: 1, name: '红楼梦' },
{
id: 2, name: '三国演义' },
{
id: 3, name: '水浒传' },
{
id: 4, name: '西游记' }
],
students: [
{
id: 1, name: 'Jack' },
{
id: 2, name: 'Annie' },
{
id: 3, name: 'Tom' }
]
}),
methods: {
changeBookListStyle() {
console.log(this.$refs.bookList)
this.$refs.bookList[2].style = 'color: red'
},
studentsRef(el) {
console.log(el)
}
}
}
</script>
<template>
<ul>
<!-- 如果 ref 值是字符串形式,在元素被渲染后包含对应整个列表的所有元素【数组】 -->
<li v-for="b in books" :key="b.id" ref="bookList">
{
{
b.name }}
</li>
</ul>
<button @click="changeBookListStyle">点我查看 bookList </button>
<hr>
<!-- 如果ref值是函数形式,则会每渲染一个列表元素则会执行对应的函数【不推荐使用】 -->
<ul>
<li v-for="s in students" :key="s.id" :ref="studentsRef">
{
{
s.name }}
</li>
</ul>
</template>
Referencia de plantilla en instrucciones de representación de lista [combinada]
<script setup>
import {
onMounted, ref } from 'vue';
// 书本
let books = ref([
{
id: 1, name: '海底两万里' },
{
id: 2, name: '骆驼祥子' },
{
id: 3, name: '老人与海' },
{
id: 4, name: '安徒生童话' },
])
let bookList = ref(null)
onMounted(() => {
console.log(bookList.value); // 获取引用的 DOM 对象,并打印,发现那么是数组,
bookList.value[2].className = 'error'
})
</script>
<template>
<ul>
<li v-for="b in books" :key="b.id" ref="bookList">
{
{
b.name }}
</li>
</ul>
</template>
<style>
.error {
border: 1px solid red;
}
</style>
3. referencia sobre el componente
Las referencias de plantilla también se pueden usar en un componente secundario; en este caso el valor obtenido en la referencia es la instancia del componente
- Si un componente secundario usa una API opcional, de manera predeterminada el componente principal puede acceder libremente a los datos y funciones del componente secundario, a menos que se use la opción de exposición en el componente secundario para exponer datos o funciones específicas. El valor de exposición es una matriz de cadenas .
- Si el componente secundario utiliza la API compuesta
App.vue【opción】
<script>
import LoginVue from './components/Login.vue';
export default {
components: {
LoginVue },
data: ()=> ({
login_vue: null
}),
methods: {
showSonData() {
console.log(this.login_vue.account) // 访问子组件中的账号数据
console.log(this.login_vue.password) // 访问子组件中的密码数据
this.login_vue.toLogin() // 访问子组件中的去登陆函数
}
},
mounted(){
this.login_vue = this.$refs.loginView
}
}
</script>
<template>
<h3>登陆界面</h3>
<hr>
<!-- 组件上的 ref 的值为该组件的实例 -->
<LoginVue ref="loginView" />
<hr>
<button @click="showSonData">查看子组件中的信息</button>
</template>
Iniciar sesión.vue【opción】
<script>
// 选项式 API ,默认情况下父组件可以随意访问该子组件的数据和函数等
export default {
data: ()=> ({
account: 'Abc31510',
password: '123321'
}),
methods: {
toLogin() {
console.log('登录中……');
}
},
// 只暴露指定数据、函数等
expose: ['account', 'toLogin']
}
</script>
<template>
账号:<input type="text" v-model="account">
<br>
密码:<input type="text" v-model="password">
</template>