vue中的v-for和ref

一、使用vue中的ref获取DOM元素

  1. 在html标签内使用ref和id

<div ref="verify" id="verify">
这是要被修改的DOM元素,把字体改成18px
</div>
  1. 在vue中获取DOM元素
export default {
    
    
	name:'',
	mounted(){
    
    
		//打印id=verify的元素
		console.log(this.$refs.verify)
		//将id=verify的字体改为18px
		this.$refs.verify.style.fontSize = "18px";
	}
}

二、v-for+ref动态获取DOM元素

  1. html元素中写ref
<li v-for="item in number" :key="index" ref="lis">1</li>
  1. vue中利用this.$nextTick(() => {})获取动态生成的DOM元素
export default {
    
    
	name:'',
	mounted(){
    
    
		this.$nextTick(() => {
    
    
        console.log(this.$refs.lis);
      });
	}
}

此时如果出现返回结果为undefined字样,则原因为:
在mounted阶段,DOM结构准备就绪,DOM结构已经出来了,但是如果在DOM结构中的某个DOM节点使用了v-if、v-show或者v-for(即根据获得的后台数据来动态操作DOM,即响应式),那么这些DOM是在mounted阶段是找不到的。所以如果在mounted钩子中使用$refs,如果ref是定位在有v-if、v-for、v-show中的DOM节点,返回来的只能是undefined,因为在mounted阶段他们根本不存在。

解决方式有以下三种:

  1. 将mounted改成updated,updated阶段完成了数据更新到DOM的阶段(对加载回来的数据进行处理),此时,ref、数据等等全部都挂载到DOM结构上去,在update阶段使用this.$refs.xxx,就100%能找到该DOM节点。但是updated与mounted不同的是,在每一次的DOM结构更新,vue都会调用一次updated(){}钩子函数,而mounted仅仅只执行一次而已;
  2. 使用 this.$nextTick(() => {}) 等页面渲染好再调用;
  3. 搭配第二种方式,加个定时器延时加载this.$refs;(本文的解决方法)
//采用第三种解决方式的代码
export default {
    
    
	name:'',
	mounted(){
    
    
		setTimeout(() => {
    
    
			this.$nextTick(() => {
    
    
        	console.log(this.$refs.lis);
      		});
      	},1000);
	}
}

注意

  1. 在获取相应元素之前,必须在mounted生命周期进行挂载,否则获取到的值为空;
  2. 如果是给子组件加id并修改自定义属性,则直接会加载该子组件对应的外层div上,并不会改变该子组件原本的自定义属性的值;
  3. 如果给子组件加ref,然后获取到该DOM元素之后改变相应的自定义属性的值,vue会报错:

Avoid mutating a prop directly since the value will be overwritten,whenever the parent component re-renders. Instead, use a data or computed property based on the prop’s value. Prop being mutated: “title”

三、参考

  1. 注意点参考:
    https://blog.csdn.net/m0_37686205/article/details/96130534
  2. 解决方式:
    https://blog.csdn.net/changzhen11/article/details/84067816
  3. 返回undefined原因详解:
    https://www.cnblogs.com/pengshengguang/p/7929367.html

猜你喜欢

转载自blog.csdn.net/weixin_46353030/article/details/119302727