Изоляция стилей и состояния является одной из ключевых практик при разработке современных интерфейсов на Vue.js. Она позволяет создавать компоненты, которые не зависят от глобальных стилей и состояния, обеспечивая предсказуемость и повторное использование.
Vue предоставляет встроенный механизм для локализации CSS через
атрибут scoped в <style>. При
использовании:
<template>
<div class="button">
Нажми меня
</div>
</template>
<script>
export default {
name: 'MyButton'
}
</script>
<style scoped>
.button {
background-color: #42b983;
color: white;
padding: 10px 20px;
border-radius: 4px;
}
</style>
Особенности scoped:
:root
напрямую. Для глобальных стилей используют <style>
без scoped или :deep() селектор.::v-deep(.global-class) {
color: red;
}
Каждый компонент Vue имеет собственный объект data,
который создаётся при инстанциировании:
export default {
data() {
return {
count: 0
};
},
methods: {
increment() {
this.count++;
}
}
};
Преимущества локального состояния:
Изоляция состояния компонентов также поддерживается через передачу
данных сверху вниз через props и событий снизу вверх через
$emit.
<template>
<ChildComponent :value="parentValue" @update="handleUpdate" />
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: { ChildComponent },
data() {
return { parentValue: 10 };
},
methods: {
handleUpdate(newValue) {
this.parentValue = newValue;
}
}
}
</script>
Основные принципы:
props обеспечивают передачу только нужных данных внутрь
компонента.$emit позволяет компоненту уведомлять родителя об
изменениях, не нарушая инкапсуляцию состояния.Когда приложение масштабируется, изоляция состояния на уровне компонентов может стать ограниченной. Vuex и Pinia позволяют создавать централизованное управление состоянием, сохраняя при этом локальные участки состояния:
// store.js
import { defineStore } from 'pinia';
export const useCounterStore = defineStore('counter', {
state: () => ({ count: 0 }),
actions: {
increment() {
this.count++;
}
}
});
Компоненты подключаются к хранилищу, не взаимодействуя напрямую с другими компонентами:
import { useCounterStore } from './store.js';
export default {
setup() {
const counter = useCounterStore();
const incrementCounter = () => counter.increment();
return { counter, incrementCounter };
}
};
Преимущества:
Vue также поддерживает CSS Modules, что позволяет полностью локализовать стили компонента с уникальными именами классов:
<template>
<div :class="$style.button">Кнопка</div>
</template>
<style module>
.button {
background: #42b983;
color: white;
padding: 10px;
}
</style>
Особенности:
scoped и
CSS-препроцессорами.scoped или CSS Modules.Изоляция стилей и состояния позволяет создавать компоненты, которые надёжны, повторно используемы и легко тестируемы, снижая зависимость от внешних факторов и повышая предсказуемость поведения приложения.