1. vue中获取dom元素
- 正常情况
<template>
<div>
<span ref="domRef">我只是一段文字</span>
<div>
</template>
<script>
import echarts from 'echarts'
export default {
data() {
return {
}
},
mounted() {
//获取dom元素
console.log(this.$refs.domRef);
console.log(document.getElementById('domRef'));
},
methods: {
//获取dom元素
getDom(){
const that = this;
// 使用 nextTick 确保dom渲染后,才去获取dom元素
that.$nextTick(() => {
console.log(this.$refs.domRef);
console.log(document.getElementById('domRef'));
})
}
}
}
</script>
<style lang="scss">
</style>
- 获取dom为空的情况
ref本身作为渲染结果被创建,在初始渲染的时候不能访问他们,是不存在的。
$refs不是响应式的,只在组件渲染完成后才填充。
用于元素或子组件注册引用信息,注册完成,将会注册在父组件$refs对象上
如果你获取到的总是空的,你注意一下:
-
你在哪里调用,和你调用的对象,试试在mounted()里面调用有效果没有,调用的对象是本来就存在的,还是需要数据渲染之后才会出现的。同理,在mounted()里面调用看看
-
调用对象是不是数组列表,我一开始设置ref在v-for列表上,直接获取this.$refs.name.style,永远是空的,
后来才发现,this.$refs.name是一个数组,无法通过 .style 获取样式,只能遍历这个this.$refs.name数组,在this.$refs.name[index]上设置样式 -
调用对象是否和v-if结合使用,ref不是响应式的,所有的动态加载的模板更新它都无法相应的变化。
-
假设使用element-UI的dialog,如果div在dialog标签里面的话,必须先要把dialog展示出来才能获取dom,大概因为窗口未展示出来就未渲染dom,所以ref会获取空。
2. Js字符串渲染Dom后绑定onclick事件
有些时候,需要在js里面以字符串写html代码,然后调用第三方api进行渲染html(如:高德地图的jsAPI),然后又要在新渲染的dom里面添加绑定事件触发函数。网上找了一下资料,思路是使用window.function进行全局绑定onclick事件,然后在mounted里面声明全局的绑定事件,具体大概如下:
<template>
<div id="aaa">
<div id="container"></div>
</div>
</template>
<script>
export default {
data() {
return {
mapObj: null,
mapWin:null
}
},
mounted(){
this.mapObj= new AMap.Map("container", {
resizeEnable: true,
center: [116.481181, 39.989792],
zoom: 16
});
//声明绑定关闭标点展示窗口的事件【关键代码】
this.closeWin();
},
methods:{
//绑定关闭标点展示窗口的事件【关键函数】
closeWin() {
const that = this;
//窗口关闭事件
window.closeInfoWindow = function () {
that.mapWin.clearInfoWindow();
}
},
// 简单引用官方的demo,介绍一下怎么加dom
addWin(){
let title = '<span style="font-size:11px;color:#F00;">测试窗口</span>',
let content = [];
content.push("<a href='javascript:void(0);' onclick=‘closeWin()’>点击关闭</a>");
this.mapWin = new AMap.InfoWindow({
isCustom: true, //使用自定义窗体
// 调用下面的方法往信息窗口加dom
content: that.createInfoWindow(title, content.join("<br/>")),
offset: new AMap.Pixel(16, -45)
});
},
//构建窗口的dom【可以忽略】
createInfoWindow(title, content) {
let info = document.createElement("div");
info.className = "custom-info input-card content-window-card";
//可以通过下面的方式修改自定义窗体的宽高
//info.style.width = "400px";
// 定义顶部标题
var top = document.createElement("div");
var titleD = document.createElement("div");
var closeX = document.createElement("img");
top.className = "info-top";
titleD.innerHTML = title;
closeX.src = "https://webapi.amap.com/images/close2.gif";
closeX.onclick = closeInfoWindow;
top.appendChild(titleD);
top.appendChild(closeX);
info.appendChild(top);
// 定义中部内容
let middle = document.createElement("div");
middle.className = "info-middle";
middle.style.backgroundColor = 'white';
middle.innerHTML = content;
info.appendChild(middle);
// 定义底部内容
let bottom = document.createElement("div");
bottom.className = "info-bottom";
bottom.style.position = 'relative';
bottom.style.top = '0px';
bottom.style.margin = '0 auto';
let sharp = document.createElement("img");
sharp.src = "https://webapi.amap.com/images/sharp.png";
bottom.appendChild(sharp);
info.appendChild(bottom);
return info;
}
}
}
</script>
<style lang="scss">
</style>