Vue3实例选项

Vue 3 实例选项完全指南

本文档从零开始讲解 Vue 3 的实例选项:在用选项式 API 定义组件时,export default { } 里可以写哪些选项(data、props、computed、methods、watch、生命周期、setup 等)、各自的作用和写法,配有大量示例,适合新手系统学习。


一、什么是“实例选项”?

1.1 概念

选项式 API 里,一个组件是通过 export default 导出一个配置对象来定义的。
这个对象里的每一个键(如 datamethodsmounted)就是一个实例选项
Vue 会根据这些选项创建组件实例:例如根据 data 生成响应式数据,根据 methods 生成方法,在对应时机执行 mounted 等。

1.2 和 的关系

组合式 API 的写法,没有“选项对象”,而是用 refonMounted 等函数。
本文讲的是选项式写法:export default { data(), methods: {}, mounted() {} } 这一套。
了解实例选项有助于阅读老项目、或选择用选项式写组件时使用。


二、data —— 组件的数据

2.1 作用

data 用来定义组件的响应式数据
必须是函数返回一个对象;对象里的属性会变成响应式的,并挂到组件实例 this 上。

2.2 写法

export default {
  data() {
    return {
      count: 0,
      name: '',
      list: []
    }
  }
}
  • 在模板里用 countnamelist
  • methodsmounted 等里用 this.countthis.name

2.3 为什么必须是函数?

每个组件可能有多个实例(同一组件被用多次)。
data 是普通对象,所有实例会共享同一份数据;写成函数后,每次创建实例都会执行一次 data(),得到各自的对象,互不干扰。

data() {
  return { count: 0 }
}

三、props —— 父组件传入的数据

3.1 作用

props 声明组件从父组件接收哪些属性;父组件通过 :xxx=”值” 传入,子组件通过 this.xxx 或模板里 xxx 使用。
props 是只读的,不要在本组件里修改。

3.2 写法

数组写法(只声明名字):

export default {
  props: ['title', 'count']
}

对象写法(带类型、默认值、必填):

export default {
  props: {
    title: {
      type: String,
      required: true
    },
    count: {
      type: Number,
      default: 0
    }
  }
}

在模板和 this 里用 this.titlethis.count


四、computed —— 计算属性

4.1 作用

computed 里定义依赖其它数据计算出来的值;会缓存,依赖不变就不会重新计算。
在模板里当属性用,不用加括号;在 this 上也是 this.xxx

4.2 写法

只读(函数写法):

export default {
  data() {
    return { count: 0 }
  },
  computed: {
    double() {
      return this.count * 2
    }
  }
}

可写(get/set):

computed: {
  fullName: {
    get() {
      return this.firstName + ' ' + this.lastName
    },
    set(val) {
      const [first, last] = val.split(' ')
      this.firstName = first
      this.lastName = last
    }
  }
}

模板里:{{ double }}{{ fullName }}


五、methods —— 方法

5.1 作用

methods 里定义方法,会挂到实例 this 上;可在模板里调用(如 @click=”add”)、在其它方法或生命周期里用 this.add()

5.2 写法

export default {
  data() {
    return { count: 0 }
  },
  methods: {
    add() {
      this.count++
    },
    addN(n) {
      this.count += n
    }
  }
}
<button @click="add">+1</button>
<button @click="addN(10)">+10</button>

注意: 在模板里需要传参时要写 addN(10);需要事件对象时写 add($event)add(无参时 Vue 会传事件对象)。


六、watch —— 侦听器

6.1 作用

watch 用来监听某个数据的变化,变化时执行你写的函数(如请求接口、存本地)。

6.2 写法

简单写法(函数):

export default {
  data() {
    return { keyword: '' }
  },
  watch: {
    keyword(newVal, oldVal) {
      console.log(newVal, oldVal)
    }
  }
}

带选项(deep、immediate):

watch: {
  form: {
    handler(newVal) {
      console.log('form 变了', newVal)
    },
    deep: true,
    immediate: true
  }
}

监听对象某个属性(字符串路径):

watch: {
  'form.name'(newVal) {
    console.log(newVal)
  }
}

七、emits —— 声明自定义事件

7.1 作用

emits 声明组件会向父组件触发哪些自定义事件(可选,但推荐写上,便于文档和校验)。
触发用 this.$emit(‘事件名’, 参数)

7.2 写法

数组:

export default {
  emits: ['update', 'close']
}

对象(带校验):

emits: {
  submit: null,
  update: (payload) => {
    if (payload.id) return true
    console.warn('缺少 id')
    return false
  }
}

methods 里:this.$emit(‘update’, 1)


八、components —— 局部注册组件

8.1 作用

components 用来局部注册只在当前组件里用的子组件;注册后可在模板里当标签用。

8.2 写法

import Child from './Child.vue'
export default {
  components: {
    Child
  }
}

模板里:


九、directives —— 局部注册指令

9.1 作用

directives 用来局部注册自定义指令,只在当前组件里可用。

9.2 写法

export default {
  directives: {
    focus: {
      mounted(el) {
        el.focus()
      }
    }
  }
}

模板里:


十、mixins —— 混入

10.1 作用

mixins多个组件共用的选项(data、methods、生命周期等)抽成混入对象,按一定规则合并进当前组件。
Vue 3 更推荐用组合式函数替代混入,详见《Vue3混入.md》。

10.2 写法

import { timeMixin } from './mixins/timeMixin'
export default {
  mixins: [timeMixin],
  data() {
    return {}
  }
}

十一、provide / inject —— 依赖注入

11.1 provide

provide 用来向子孙组件提供数据或方法,不需要层层 props。

export default {
  data() {
    return { theme: 'dark' }
  },
  provide() {
    return {
      theme: this.theme
    }
  }
}

若希望 theme 是响应式的,可 provide 一个 computedthis 上的 getter。

11.2 inject

inject子孙组件注入祖先 provide 的值。

export default {
  inject: ['theme']
}

模板和 this 里用 this.theme
可写默认值:inject: { theme: { from: ‘theme’, default: ‘light’ } }


十二、生命周期钩子选项

在选项对象里直接写生命周期钩子函数,Vue 会在对应阶段调用。

选项 执行时机
beforeCreate 实例创建后、data 等初始化前
created data、methods 等已初始化,DOM 未挂载
beforeMount 即将挂载到 DOM 前
mounted 已挂载到 DOM,可操作 $el、$refs
beforeUpdate 数据变化,虚拟 DOM 即将更新前
updated DOM 更新完成后
beforeUnmount 即将销毁、从 DOM 移除前
unmounted 已销毁,做清理(解绑、清定时器)
export default {
  data() {
    return { count: 0 }
  },
  created() {
    console.log('created', this.count)
  },
  mounted() {
    console.log('mounted', this.$el)
  },
  unmounted() {
    console.log('unmounted,做清理')
  }
}

详见《Vue3中生命周期钩子.md》。


十三、name —— 组件名

13.1 作用

name 指定组件的名字,用于开发工具显示、keep-alive 的 include/exclude、递归组件等。

13.2 写法

export default {
  name: 'MyComponent'
}

十四、inheritAttrs —— 是否继承根节点属性

14.1 作用

父组件在子组件上写的、未在 props 里声明的属性,默认会自动应用到子组件根元素上。
inheritAttrs: false 可关闭这种自动应用,改由自己在模板里用 v-bind=”$attrs” 决定绑到哪。

14.2 写法

export default {
  inheritAttrs: false
}

十五、setup —— 组合式 API 入口(选项式里)

15.1 作用

选项式组件里也可以写 setup 函数,作为组合式 API 的入口;setup返回值会与 datamethods合并到实例上。
若同时有 setupdata,同名时以 setup 返回的为准。

15.2 写法

import { ref } from 'vue'
export default {
  data() {
    return { count: 0 }
  },
  setup(props, context) {
    const name = ref('')
    return { name }
  }
}

模板和 this 上既有 count(来自 data),也有 name(来自 setup)。
更多见《Vue3中setup函数.md》。


十六、完整示例:组合多个选项

export default {
  name: 'UserCard',
  components: {
    UserAvatar: () => import('./UserAvatar.vue')
  },
  props: {
    user: {
      type: Object,
      required: true
    }
  },
  data() {
    return {
      loading: false
    }
  },
  computed: {
    displayName() {
      return this.user?.name ?? '匿名'
    }
  },
  watch: {
    'user.id'() {
      this.loadDetail()
    }
  },
  emits: ['edit'],
  created() {
    this.loadDetail()
  },
  methods: {
    loadDetail() {
      this.loading = true
      // ...
      this.loading = false
    },
    onEdit() {
      this.$emit('edit', this.user)
    }
  }
}

十七、实例选项速查表

选项 类型 作用
data 函数,返回对象 响应式数据
props 数组或对象 声明接收的 props
computed 对象 计算属性
methods 对象 方法
watch 对象 侦听器
emits 数组或对象 声明自定义事件
components 对象 局部注册组件
directives 对象 局部注册指令
mixins 数组 混入
provide 对象或函数 向子孙提供数据
inject 数组或对象 注入祖先数据
beforeCreateunmounted 函数 生命周期钩子
name 字符串 组件名
inheritAttrs 布尔 是否继承根节点未声明属性
setup 函数 组合式 API 入口

十八、学习建议

  1. 先掌握 datamethodscomputedpropsmounted,能写一个完整的选项式组件。
  2. 再按需用 watchemitscomponentsprovide/inject
  3. 了解 nameinheritAttrs;需要组合式时再写 setup
  4. 新项目更推荐 + 组合式 API;实例选项主要用于阅读或维护选项式代码。

把本文档里的“完整示例”在项目里改一改、跑一遍,会掌握得更牢。祝你学习顺利。

发表评论