个人网站空间多大合适中国新闻
#元素 attribute 的顺序推荐
元素 (包括组件) 的 attribute 应该有统一的顺序。
这是我们为组件选项推荐的默认顺序。它们被划分为几大类,所以你也能知道新添加的自定义 attribute 和指令应该放到哪里。
- 定义 (提供组件的选项)
is
- 列表渲染 (创建多个变化的相同元素)
v-for
- 条件渲染 (元素是否渲染/显示)
v-ifv-else-ifv-elsev-showv-cloak
- 渲染修饰符 (改变元素的渲染方式)
v-prev-once
- 全局感知 (需要超越组件的知识)
id
- 唯一的 Attributes (需要唯一值的 attribute)
refkey
- 双向绑定 (把绑定和事件结合起来)
v-model
- 其他 Attributes (所有普通的绑定或未绑定的 attribute)
- 事件 (组件事件监听器)
v-on
- 内容 (覆写元素的内容)
v-htmlv-text
#组件/实例选项中的空行推荐
你可能想在多个 property 之间增加一个空行,特别是在这些选项一屏放不下,需要滚动才能都看到的时候。
当你的组件开始觉得密集或难以阅读时,在多个 property 之间添加空行可以让其变得容易。在一些诸如 Vim 的编辑器里,这样格式化后的选项还能通过键盘被快速导航。
好例子
props: {value: {type: String,required: true},focused: {type: Boolean,default: false},label: String,icon: String},computed: {formattedValue() {// ...},inputClasses() {// ...}}
// 没有空行在组件易于阅读和导航时也没问题。props: {value: {type: String,required: true},focused: {type: Boolean,default: false},label: String,icon: String},computed: {formattedValue() {// ...},inputClasses() {// ...}}
#单文件组件的顶级元素的顺序推荐
单文件组件应该总是让 <script>、<template> 和 <style> 标签的顺序保持一致。且 <style> 要放在最后,因为另外两个标签至少要有一个。
反例
<style>/* ... */</style><script>/* ... */</script><template>...</template>
<!-- ComponentA.vue --><script>/* ... */</script><template>...</template><style>/* ... */</style><!-- ComponentB.vue --><template>...</template><script>/* ... */</script><style>/* ... */</style>
好例子
<!-- ComponentA.vue --><script>/* ... */</script><template>...</template><style>/* ... */</style><!-- ComponentB.vue --><script>/* ... */</script><template>...</template><style>/* ... */</style>
<!-- ComponentA.vue --><template>...</template><script>/* ... */</script><style>/* ... */</style><!-- ComponentB.vue --><template>...</template><script>/* ... */</script><style>/* ... */</style>
#优先级 D 的规则:谨慎使用 (潜在风险)
#scoped 中的元素选择器谨慎使用
元素选择器应该避免在 scoped 中出现。
在 scoped 样式中,类选择器比元素选择器更好,因为大量使用元素选择器是很慢的。
详解
为了给样式设置作用域,Vue 会为元素添加一个独一无二的 attribute,例如 data-v-f3f3eg9。然后修改选择器,使得在匹配选择器的元素中,只有带这个 attribute 才会真正生效 (比如 button[data-v-f3f3eg9])。
问题在于大量的元素和 attribute 组合的选择器 (比如 button[data-v-f3f3eg9]) 会比类和 attribute 组合的选择器慢,所以应该尽可能选用类选择器。
反例
<template><button>×</button></template><style scoped>button {background-color: red;}</style>
好例子
<template><button class="btn btn-close">×</button></template><style scoped>.btn-close {background-color: red;}</style>
#隐性的父子组件通信谨慎使用
应该优先通过 prop 和事件进行父子组件之间的通信,而不是 this.$parent 或变更 prop。
一个理想的 Vue 应用是 prop 向下传递,事件向上传递的。遵循这一约定会让你的组件更易于理解。然而,在一些边界情况下 prop 的变更或 this.$parent 能够简化两个深度耦合的组件。
问题在于,这种做法在很多简单的场景下可能会更方便。但请当心,不要为了一时方便 (少写代码) 而牺牲数据流向的简洁性 (易于理解)。
反例
app.component('TodoItem', {props: {todo: {type: Object,required: true}},template: '<input v-model="todo.text">'})
app.component('TodoItem', {props: {todo: {type: Object,required: true}},methods: {removeTodo() {this.$parent.todos = this.$parent.todos.filter(todo => todo.id !== vm.todo.id)}},template: `<span>{{ todo.text }}<button @click="removeTodo">×</button></span>`})
好例子
app.component('TodoItem', {props: {todo: {type: Object,required: true}},template: `<input:value="todo.text"@input="$emit('input', $event.target.value)">`})
app.component('TodoItem', {props: {todo: {type: Object,required: true}},template: `<span>{{ todo.text }}<button @click="$emit('delete')">×</button></span>`})
#非 Flux 的全局状态管理谨慎使用
应该优先通过 Vuex 管理全局状态,而不是通过 this.$root 或一个全局事件总线。
通过 this.$root 和/或全局事件总线管理状态在很多简单的情况下都是很方便的,但是并不适用于绝大多数的应用。
Vuex 是 Vue 的官方类 flux 实现,其提供的不仅是一个管理状态的中心区域,还是组织、追踪和调试状态变更的好工具。它很好地集成在了 Vue 生态系统之中 (包括完整的 Vue DevTools 支持)。
反例
// main.jsimport { createApp } from 'vue'import mitt from 'mitt'const app = createApp({data() {return {todos: [],emitter: mitt()}},created() {this.emitter.on('remove-todo', this.removeTodo)},methods: {removeTodo(todo) {const todoIdToRemove = todo.idthis.todos = this.todos.filter(todo => todo.id !== todoIdToRemove)}}})
好例子
// store/modules/todos.jsexport default {state: {list: []},mutations: {REMOVE_TODO (state, todoId) {state.list = state.list.filter(todo => todo.id !== todoId)}},actions: {removeTodo ({ commit, state }, todo) {commit('REMOVE_TODO', todo.id)}}}
<!-- TodoItem.vue --><template><span>{{ todo.text }}<button @click="removeTodo(todo)">X</button></span></template><script>import { mapActions } from 'vuex'export default {props: {todo: {type: Object,required: true}},methods: mapActions(['removeTodo'])}</script>
