Priority D 规则:谨慎使用
注意
此 Vue.js 风格指南已过时,需要重新审查。如果你有任何问题或建议,请 提交 issue。
Vue 的一些特性是为了适应罕见的边缘情况,或者让从旧代码库迁移时更顺畅而存在的。然而,当这些特性被过度使用时,它们会让代码更难维护,甚至成为 bug 的来源。这些规则会指出一些潜在有风险的特性,说明何时以及为什么应该避免它们。
带有 scoped 的元素选择器
应避免在 scoped 中使用元素选择器。
在 scoped 样式中,应优先使用类选择器而不是元素选择器,因为大量元素选择器的性能较差。
详细说明
为了实现样式作用域,Vue 会给组件元素添加一个唯一属性,例如 data-v-f3f3eg9。然后会修改选择器,使其只选择带有该属性的匹配元素(例如 button[data-v-f3f3eg9])。
问题在于,大量元素-属性选择器(例如 button[data-v-f3f3eg9])的速度会明显慢于类-属性选择器(例如 .btn-close[data-v-f3f3eg9]),因此在可能的情况下应优先使用类选择器。
差
template
<template>
<button>×</button>
</template>
<style scoped>
button {
background-color: red;
}
</style>好
template
<template>
<button class="btn btn-close">×</button>
</template>
<style scoped>
.btn-close {
background-color: red;
}
</style>隐式的父子通信
父子组件通信应优先使用 props 和 events,而不是 this.$parent 或直接修改 props。
理想的 Vue 应用是 props 向下传递,events 向上传递。遵循这一约定会让你的组件更容易理解。不过,也存在一些边缘情况,在这些情况下,修改 prop 或使用 this.$parent 可以简化两个已经高度耦合的组件。
问题在于,在很多 简单 的场景中,这些模式也可能带来便利。请注意:不要被“简化”(更容易理解状态流向)所替代的短期便利(更少的代码)所诱惑。
差
vue
<script setup>
defineProps({
todo: {
type: Object,
required: true
}
})
</script>
<template>
<input v-model="todo.text" />
</template>vue
<script setup>
import { getCurrentInstance } from 'vue'
const props = defineProps({
todo: {
type: Object,
required: true
}
})
const instance = getCurrentInstance()
function removeTodo() {
const parent = instance.parent
if (!parent) return
parent.props.todos = parent.props.todos.filter((todo) => {
return todo.id !== props.todo.id
})
}
</script>
<template>
<span>
{{ todo.text }}
<button @click="removeTodo">×</button>
</span>
</template>好
vue
<script setup>
defineProps({
todo: {
type: Object,
required: true
}
})
const emit = defineEmits(['input'])
</script>
<template>
<input :value="todo.text" @input="emit('input', $event.target.value)" />
</template>vue
<script setup>
defineProps({
todo: {
type: Object,
required: true
}
})
const emit = defineEmits(['delete'])
</script>
<template>
<span>
{{ todo.text }}
<button @click="emit('delete')">×</button>
</span>
</template>