ref元素的用法

这篇文章来谈谈《Spring Framework 开发参考手册》的3.3.2小节中的ref的用法。
 
  ref元素是用在property中,来设置需要引用的容器管理的其它Bean。
 
  它的用法:,这里主要分析一下这三个参数的作用。
 
  这次先看实例,再进行讲解。
 
· 先建立一个包:javamxj.spring.basic.ref ,然后把以下5个文件放在这个包下。
HelloBean.java
package javamxj.spring.basic.ref;

public class HelloBean {
    private String hello;

    public String getHello() {
        return hello;
    }

    public void setHello(String hello) {
        this.hello = hello;
    }
}
 

 
HelloDate.java
package javamxj.spring.basic.ref;

import java.util.Date;

public class HelloDate {
    private Date date;

    private HelloBean hb;

    public void setDate(Date date) {
        this.date = date;
    }

    public void setHb(HelloBean hb) {
        this.hb = hb;
    }

    public void sayHello() {
        System.out.println(hb.getHello() + "  " + date.toLocaleString());
    }

}

 
beans.xml

xml version="1.0" encoding="GBK"?>
DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN""http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
   
    <bean id="helloBean"class="javamxj.spring.basic.ref.HelloBean">
        <property name="hello" value="Hello! Child Bean." />
    bean>
   
    <bean id="dateBean" name="#date"class="java.util.Date"/>
   
    <bean id="hd1"class="javamxj.spring.basic.ref.HelloDate">
        <property name="hb">
            <ref bean="helloBeanParent"/>
        property>
        <property name="date">
            <ref bean="#date"/>
           
        property>
    bean>
   
    <bean id="hd2"class="javamxj.spring.basic.ref.HelloDate">
        <property name="hb">
            <ref local="helloBean"/>
        property>
        <property name="date">
            <ref local="dateBean"/>
        property>
    bean>
   
    <bean id="hd3"class="javamxj.spring.basic.ref.HelloDate">
        <property name="hb">
            <ref parent="helloBean"/>
        property>
        <property name="date">
            <bean class="java.util.Date"/>
        property>
    bean>
   
beans>
 
parent.xml
xml version="1.0" encoding="GBK"?>
DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN""http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
   
    <bean id="helloBean"class="javamxj.spring.basic.ref.HelloBean">
        <property name="hello" value="Hello! Javamxj."/>
    bean>
   
    <bean id="helloBeanParent"class="javamxj.spring.basic.ref.HelloBean">
        <property name="hello" value="Hello! Parent Bean." />
    bean>
   
beans>

 
Main.java
package javamxj.spring.basic.ref;

import org.springframework.beans.factory.BeanFactory;
importorg.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;

public class Main {

    public static void main(String[] args) {
        BeanFactory parent = new XmlBeanFactory(newClassPathResource(
               "javamxj/spring/basic/ref/parent.xml"));
        BeanFactory child = new XmlBeanFactory(newClassPathResource(
                "javamxj/spring/basic/ref/beans.xml"), parent);

        HelloDate hd1 = (HelloDate) child.getBean("hd1");
        HelloDate hd2 = (HelloDate) child.getBean("hd2");
        HelloDate hd3 = (HelloDate) child.getBean("hd3");

        hd1.sayHello();
        hd2.sayHello();
        hd3.sayHello();
    }
}

 
 
·运行Main.java,输出结果如下:
 
Hello! Parent Bean.  2005-8-10 22:25:56
Hello! Child Bean.  2005-8-10 22:25:56
Hello! Javamxj.  2005-8-10 22:25:56
 
 
   OK!这里主要分析beans.xml、Main.java这两个文件。对于Main.java要注意的是如何加载“parent”的,重点看看beans.xml中ref元素的用法。
 
  首先定义两个bean:helloBean、dateBean,分别指向HelloBean类和Date类。然后定义了hd1、hd2、hd3等三个bean,都指向HelloDate类。
 
·hd1:
  property标签中的“helloBeanParent”并不存在于beans.xml中,而是在parent.xml中,使用可以从其它bean配置文件中寻找需要加载的目标bean。bean属性的值可以同目标bean的id属性相同,也可以同它的name属性中任意的一个值相同。
 
·hd2:
   property标签中的“helloBean”如果不存在于beans.xml中,则XML解析器会提示错误。只能这个bean配置文件中寻找需要加载的目标bean,而且local属性值必须同目标bean的id属性相同。
 
·hd3:
   property标签中的“helloBean”同时存在于beans.xml和parent.xml中,使用则会优先从beans.xml中寻找需要加载的目标bean,如果需要从parent.xml中加载目标bean,则需使用。在设置date时,使用的是内联bean,这时可以不要任何id或name定义。


本文来自优快云博客,转载请标明出处:http://blog.youkuaiyun.com/yuyulover/archive/2010/07/09/5722410.aspx

<think>我们正在讨论Vue中使用ref获取DOM元素或组件实例的问题。根据引用内容,我们可以总结出以下关键点: 1. 在Vue模板中,可以通过`ref`属性标记DOM元素或子组件。 2. 在组合式API(Composition API)中,使用`ref`函数创建一个响应式引用,然后在模板中通过相同的名称绑定。 3. 在选项式API(Options API)中,可以直接在模板中设置`ref`属性,然后通过`this.$refs`访问。 4. 注意:在组件挂载完成后(如`mounted`生命周期钩子)才能访问到对应的DOM元素或组件实例。 下面我将分别展示组合式API和选项式API的用法。 ### 组合式API(Vue 3) 在Vue 3中,使用`setup`函数和Composition API: ```vue <template> <div ref="myRef">获取单个DOM元素</div> </template> <script> import { ref, onMounted } from 'vue'; export default { setup() { // 创建一个ref,初始值为null const myRef = ref(null); onMounted(() => { // 在挂载后,myRef.value指向DOM元素 console.dir(myRef.value); // 输出DOM元素 }); return { myRef // 必须返回,模板才能访问 }; } }; </script> ``` ### 选项式API(Vue 2 和 Vue 3 都支持) 在选项式API中,我们可以这样: ```vue <template> <div ref="myRef">获取单个DOM元素</div> </template> <script> export default { mounted() { // 通过this.$refs访问 console.log(this.$refs.myRef); // 输出DOM元素 } }; </script> ``` ### 获取组件实例 同样,`ref`也可以用于子组件,从而访问子组件的属性和方法。 ```vue <template> <ChildComponent ref="childRef" /> </template> <script> import ChildComponent from './ChildComponent.vue'; export default { components: { ChildComponent }, mounted() { // 访问子组件实例 console.log(this.$refs.childRef); // 调用子组件方法 this.$refs.childRef.someMethod(); } }; </script> ``` ### 注意事项 - 在组件挂载完成之前(如`created`生命周期),`$refs`还未被填充,访问会是`undefined`。 - `ref`是响应式的,但你不应该使用它来直接操作DOM(避免直接修改DOM,应该通过数据驱动),但在某些情况下(如集成第三方库)可能需要直接访问DOM。 - 在Vue 3的组合式API中,`ref`用于DOM引用和响应式数据使用的是同一个函数,但用途不同。用于DOM引用时,我们只是用它来保存一个引用,并不需要改变它(所以不会用`.value`去修改它)。 §§相关问题§§ 1. Vue 3中如何使用`ref`获取多个DOM元素? 2. 如何在Vue中通过`ref`调用子组件的方法? 3. Vue的`ref`和原生JavaScript的`getElementById`有什么区别? 4. 为什么在`setup`中访问`ref`的`value`有时是`null`?</think>### Vue 中使用 ref 获取 DOM 元素或组件实例 在 Vue 中,`ref` 是用于获取 DOM 元素或组件实例引用的特殊属性。以下是具体实现方法: #### 1. **获取 DOM 元素** ```vue <template> <!-- 标记 DOM 元素 --> <div ref="myDiv">点击查看控制台输出</div> </template> <script> import { ref, onMounted } from 'vue'; export default { setup() { const myDiv = ref(null); // 创建 ref 引用 onMounted(() => { console.log(myDiv.value); // 输出: <div>点击查看控制台输出</div> myDiv.value.style.color = "red"; // 操作 DOM }); return { myDiv }; // 必须返回才能在模板中使用 } }; </script> ``` #### 2. **获取组件实例** ```vue <template> <!-- 标记子组件 --> <ChildComponent ref="childComp" /> </template> <script> import ChildComponent from './ChildComponent.vue'; export default { components: { ChildComponent }, mounted() { // 访问子组件方法和数据 this.$refs.childComp.someMethod(); console.log(this.$refs.childComp.someData); } }; </script> ``` #### 3. **选项式 API 法** ```vue <template> <button ref="myButton">按钮</button> </template> <script> export default { mounted() { console.log(this.$refs.myButton); // 输出按钮 DOM 元素 this.$refs.myButton.addEventListener('click', this.handleClick); } } </script> ``` ### 关键注意事项 1. **访问时机** DOM 元素必须在组件挂载后访问(`onMounted` 或 `mounted` 生命周期钩子中),否则值为 `null`[^3][^4]。 2. **响应式更新** `ref` 是响应式的,但直接修改 DOM 不是推荐做法(应优先使用数据驱动)。 3. **动态 ref** 结合 `v-for` 使用时可获取元素数组: ```vue <li v-for="item in list" :ref="setItemRef"></li> ``` ```js setup() { const itemRefs = []; const setItemRef = el => { if (el) itemRefs.push(el); }; return { setItemRef }; } ``` ### 与原生 DOM 操作的区别 | 方式 | 优点 | 缺点 | |------|------|------| | `ref` | 自动清理内存,与 Vue 生命周期绑定 | 需等待组件挂载 | | `getElementById` | 即时可用 | 需手动清理,易导致内存泄漏 | > 最佳实践:优先使用数据驱动视图,仅在集成第三方库或触发焦点等场景使用 `ref`[^2][^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值