原博客地址:深入 Vue.js 的心脏:全面剖析 $el 属性_vue $el-CSDN博客
目录
1 $el是什么
1.1 $el本质
1.2 访问$el时机
1.3 $el与模板的关系
2 $el使用场景
2.1 集成第三方库
2.2 操作DOM元素样式
2.3 处理焦点和事件
2.4 实现自定义指令
3 $el的注意事项
3.1 不要过度依赖$el
3.2 注意生命周期
3.3 避免直接操作子组件的$el
4 与其他API协作
4.1 与$refs配合
4.2 与$nextTick配合
5 总结
1 $el是什么
$el:代表Vue实例所管理的根DOM元素。
每个Vue实例创建时,都会绑定一部分DOM元素,$el属性是这部分DOM元素的入口。
1.1 $el本质
$el属性的值是一个DOM元素对象。
- 获取元素属性:this.$el.id
- 修改元素样式:this.$el.style.color='red'
- 添加事件监听:this.$el.addEventListener('click', this.handleClick)
1.2 访问$el时机
$el属性在Vue实例完成挂载,将模板编译成真实DOM元素并插入到页面中后,才能访问$el。
Vue实例创建完成时也不能访问$el属性。
const vm = new Vue({
template: '<div>Hello World</div>'
});
// 错误示范:此时 vm.$el 还未定义
console.log(vm.$el); // undefined
// 正确姿势:在 mounted 生命周期钩子中访问
vm.$mount('#app');
vm.$nextTick(() => {
console.log(vm.$el); // <div>Hello World</div>
});
这里可以看出,vm就是Vue实例。
1.3 $el与模板的关系
Vue实例的模板最终会被编译成一个DOM树,$el指向这棵树的根节点。
如果模板里没有定义根节点,Vue会自动创建一个<div>元素作为根节点。
<!-- 模板 -->
<template>
<p>这是一段文本</p>
<button>点击</button>
</template>
<!-- 渲染后的 DOM 结构 -->
<div>
<p>这是一段文本</p>
<button>点击</button>
</div>
2 $el使用场景
2.1 集成第三方库
第三方JS库都需要操作DOM元素,使用$el可以将Vue组件与这些库结合起来。
例如在Vue组件里使用Chart.js绘制图表,将图表渲染到组件的$el上。
import Chart from 'chart.js';
export default {
mounted() {
this.chart = new Chart(this.$el, {
// 图表配置
});
}
};
2.2 操作DOM元素样式
动态调整元素样式。
export default {
mounted() {
// 获取元素宽度
const width = this.$el.offsetWidth;
// 设置元素高度
this.$el.style.height = `${width}px`;
}
};
2.3 处理焦点和事件
手动控制DOM元素的焦点,如表单验证、自定义输入框等。
export default {
mounted() {
// 聚焦到输入框
this.$el.querySelector('input').focus();
},
methods: {
handleClickOutside(event) {
// 判断点击事件是否发生在组件外部
if (!this.$el.contains(event.target)) {
// 执行相应操作
}
}
}
};
2.4 实现自定义指令
Vue.js自定义指令可以用于扩展HTML元素功能,其中用到了$el属性。
Vue.directive('focus', {
inserted: function (el) {
el.focus();
}
});
3 $el的注意事项
3.1 不要过度依赖$el
过度依赖$el会破坏Vue.js数据驱动的优势。
多数情况下,尽量使用Vue.js提供的数据绑定、计算属性、事件处理等机制操作DOM元素,将$el作为最后手段。
3.2 注意生命周期
$el只有在Vue实例完成挂载后才能访问,因此要在mounted及之后的生命周期函数里使用$el.
3.3 避免直接操作子组件的$el
Vue.js中,每个组件都有自己的$el属性,代表组件的根DOM元素。
尽量避免直接操作子组件的$el,而是通过props、事件等机制与子组件进行通信。
4 与其他API协作
$el可与Vue.js其他API协作。
4.1 与$refs配合
$refs属性可以获取到组件中使用ref属性标记的DOM元素或子组件实例,而$el可以获取到组件的根DOM元素。两者可以结合使用。
<template>
<div ref="container">
<p>这是一段文本</p>
</div>
</template>
<script>
export default {
mounted() {
// 获取容器元素的高度
const height = this.$refs.container.offsetHeight;
// 设置容器元素的背景颜色
this.$el.style.backgroundColor = 'lightblue';
}
};
</script>
4.2 与$nextTick配合
某些情况需要在DOM更新后执行一些操作,例如获取元素尺寸、位置等。
$nextTick方法可以将回调函数延迟到下次DOM更新循环后执行,确保操作的是最新DOM元素。
export default {
mounted() {
this.$nextTick(() => {
// 获取元素高度
const height = this.$el.offsetHeight;
// 执行其他操作
});
}
};
补充:API-Vue.nextTick的解释API — Vue.js
5 总结
$el提供了一种在Vue中直接操作DOM元素的途径。
但实际开发中,要谨慎使用$el属性,避免过度依赖$el破坏Vue.js数据驱动的优势。
充分利用$el属性的强大功能,结合Vue.js其他API,构建更加灵活高效的Vue.js应用程序。