一、属性透传attribute
- 指的是传递给一个组件,但没有通过props或emits接收,常见的如class、style、id
- 透传的样式会自动被添加到子组件根元素上,如果子组件已经有一个样式,透传的样式会和已有样式合并。
- 如果透传的是一个点击事件,也会自动被添加到子组件根元素上,如果子组件自身也有点击事件,点击时透传过来的事件和其本身的事件都会触发。
- 透传的属性可以通过{{$attrs}}拿到
- 属性透传只会透传到根元素上,如果有多个根节点,vue不知道要透传到哪个节点,需要通过v-bind="$attrs"绑定到要透传到的那个节点上,否则会抛出警告。
- 属性透传是可以禁用的,通过inheritAttrs: false可以阻止透传
例:
目录

1.新建assets样式文件夹,样式文件style.css
css
.large{
color: red;
}
.small{
background-color: pink;
}
2.在index.html中引入样式文件
xml
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>首页</title>
<link rel="stylesheet" href="./assets/css/style.css">
</head>
<body>
<div id="app"></div>
<script type="module" src="./src/main.js"></script>
</body>
</html>
父组件App.js
arduino
import Child from "./Child.js";
export default {
components: {
Child,
},
data() {
return {
title: "attribute属性透传",
count:0
};
},
/*html*/
template: `<div style="width:400px;height:400px;background-color:skyblue;">
<h2>{{title}}</h2>
<p>{{count}}</p>
<Child class="large" @click="count++" ></Child>
</div>`,
};
子组件Child.js
dart
export default {
data() {
return {
num: 10,
};
},
inheritAttrs: true, // 阻止透传
/*html*/
template: `
<button @click="num++" class="small">子按钮{{num}}</button>
<main v-bind="$attrs">多个根节点</main>
`,
};
二、vue实例对象方法$nextTick()
可以通过this.$nextTick(()=>{})访问,回调函数会在dom节点渲染完成后执行
如:正常操作dom节点是在mounted生命周期中操作,nextTick()方法可以实现在created生命周期中操作dom节点
javascript
export default {
data() {
return {
title: "vue实例对象的 $nextTick()",
count:10
};
},
created() {
this.$nextTick(()=>{
//回调函数,模板界面异步更新完成后执行
const pEle = document.querySelector('#countP')
console.log('bindPlus >> ',pEle.innerHTML);
})
},
methods: {
bindPlus(){
this.count++
// 验证, count数据变化,通知依赖更新界面是一个异步过程
const pEle = document.querySelector('#countP')
console.log('bindPlus >> ',pEle.innerHTML);//是更新之前的值,说明是异步更新的
//模板界面异步更新完成后执行nextTick回调函数中代码
this.$nextTick(()=>{
const pEle = document.querySelector('#countP')
console.log('bindPlus >> ',pEle.innerHTML); //是更新之后的值
})
}
},
/*html*/
template: `<div>
<h2>{{title}}</h2>
<p id="countP">{{count}}</p>
<button @click="bindPlus">加一 </button>
</div>`,
};
三、虚拟dom、浏览器渲染机制
整个html文档是一个dom对象,整个html由dom节点对象构成。
浏览器渲染机制:
- 解析HTML生成dom树,同时解析CSS文档构建CSSOM树
- DOM树和CSSOM树关联起来生成渲染树(RenderTree)
- 浏览器按照渲染树进行重排重绘
重绘:CSS 样式改变(如:visibility,背景色的改变),使浏览器需要根据新的属性进行绘制
重排:对DOM的修改引发了DOM几何元素的变化(如:改变元素高度),渲染树需要重新计算,重新生成布局,重新排列元素。
重绘不一定导致重排,但重排一定会导致重绘
操作真实dom会引起重排重绘,vue框架操作的是虚拟dom(本质上就是一个普通的JS对象。是模拟真实dom得到的一个JS对象)
将真实dom多次操作在虚拟dom上完成,再将虚拟dom映射到真实dom,完成一次重排重绘,提高渲染效率。
我们在vue中写的template模板,vue编译过程中,会调用render()函数将其编译成虚拟dom树,后映射挂载成真实dom,然后重排重绘显示给用户
vue提供了一个h()方法,用于创建虚拟dom(vnode)
php
import { h } from 'vue'
render(){
return[
h('div')
h('div', { id: "foo" })
h('div', { id: "foo", class: "bar", style: { color: 'red' }, onClick: () => { } },'标 题', [/*child*/])
]
}