Chapter 14 scoped样式以及data函数
欢迎大家订阅【Vue2+Vue3】入门到实践 专栏,开启你的 Vue 学习之旅!
文章目录
- 1 scoped样式
- 1.1 全局样式
- 1.2 局部样式
- 1.3 工作原理
- 2 data函数
1 scoped样式
1.1 全局样式
全局样式是指作用于整个应用程序的样式,不论在哪个组件中定义,都能影响到所有具有相同元素的组件。
在 Vue 中,若在组件的 <style>
标签中没有使用 scoped
,则该样式会自动成为全局样式,影响到所有同样的 HTML 元素。
【示例】
BaseOne.vue
<template><div>BaseOne</div>
</template><script>
export default {}
</script><style>
/*
默认的style样式会作用于全局 -> 全局样式
*/
div{border:3px solid blue;margin:30px;
}
</style>>
BaseTwo.vue
<template><div>BaseTwo</div>
</template><script>
export default {}
</script><style></style>
App.vue
<template><div><BaseOne></BaseOne><BaseTwo></BaseTwo></div>
</template><script>
// 在 <script> 标签内
import BaseOne from './components/BaseOne.vue';
import BaseTwo from './components/BaseTwo.vue';export default {components: {BaseOne,BaseTwo}
}
</script><style></style>
运行结果:
从上图可知,BaseOne.vue 中定义的全局样式不仅影响了 BaseOne 组件中的 div
元素,还影响了 BaseTwo 组件中的 div
元素
1.2 局部样式
局部样式仅适用于当前组件,避免了全局样式的污染。
在 Vue 中,通过在 <style>
标签上添加 scoped
属性,可以限制样式的作用范围,仅影响当前组件内的元素,而不会影响其他组件中的相同元素。
【示例】
修改 BaseOne.vue 的代码,为其添加 scoped
属性来限制样式的作用范围:
运行结果:
添加 scoped
后,样式将只作用于 BaseOne.vue 中的 div
元素,而不再影响 BaseTwo.vue 中的 div
元素。
1.3 工作原理
Vue 实现 scoped
样式的方式是通过给每个元素添加一个唯一的 data-v-xxxx
属性,并且在样式选择器中增加这个属性作为条件,以确保样式只作用于当前组件的元素。
【示例】
BaseOne.vue
<template><div>BaseOne<span>111</span><a href="">链接</a></div>
</template><script>
export default {}
</script><style>
/*
默认的style样式会作用于全局 -> 全局样式
*/
div{border:3px solid blue;margin:30px;
}
</style>>
BaseTwo.vue
<template><div>BaseTwo</div>
</template><script>
export default {}
</script><style scoped>
div{border:3px solid red;margin:30px;
}
</style>
运行结果:
【Scoped 样式的工作机制】
1. 添加 data-v-hash
属性
Vue 会为每个组件的元素添加一个唯一的 data-v-hash
属性(例如 data-v-5f6a9d56
),该属性仅在当前组件中存在。
2. 修改样式选择器
Vue 会自动将样式选择器修改为 div[data-v-5f6a9d56]
,样式只会作用于带有 data-v-hash 属性的元素。
3. 同一组件的 hash 值相同
Vue 会确保同一组件中的所有元素的 data-v-hash
属性相同,从而保证它们共享相同的样式。
2 data函数
在 Vue 中,组件的 data
选项必须是一个返回对象的函数,确保每个组件实例都有独立的数据对象。
为什么 data
是一个函数?
Vue 会创建一个新的组件实例时,每个组件实例都需要一份独立的 data
对象。如果 data
是一个对象而不是函数,所有组件实例将共享同一个数据对象,从而导致数据污染和不可预期的行为。
【示例】
BaseCount.vue
<template><div class="base-count"><button @click="count--">-</button><span>{{ count }}</span><button @click="count++">+</button></div>
</template><script>
export default {data: function () {return {count: 100,}},
}
</script><style>
.base-count {margin: 20px;
}
</style>
App.vue
<template><div class="app"><BaseCount></BaseCount><BaseCount></BaseCount><BaseCount></BaseCount></div>
</template><script>
import BaseCount from './components/BaseCount'
export default {components: {BaseCount,},
}
</script><style>
</style>
运行结果:
在 App.vue 中,创建了三个 <BaseCount>
组件实例。每次 Vue 创建新的 BaseCount 实例时,都会执行 data
函数,返回一个新的对象。
每个 BaseCount 组件都有独立的 count
数据,初始值为 100。点击某个组件的加减按钮时,只有该组件的 count
值会发生变化,而其他组件的 count
数据不受影响。