- 1:1.1 什么是 vue
- 2:1.2 vue 的特性
- 2.1:1.2.1 数据驱动视图
- 2.2:1.2.2 双向数据绑定
- 2.3:1.2.3 MVVM
- 2.4:1.2.4 MVVM 的工作原理
- 3:3.1 内容渲染指令
- 4:3.2 属性绑定指令
- 5:3.3 事件绑定指令
- 6:3.4 双向绑定指令
- 7:3.5 条件渲染指令
- 8:3.6 列表渲染指令
- 9:4.1 定义过滤器
- 10:4.2 私有过滤器和全局过滤器
- 11:4.3 连续调用多个过滤器
- 12:4.4 过滤器传参
- 13:4.5 过滤器的兼容性
- 14:5.1 什么是 watch 侦听器
- 15:5.2 使用 watch 检测用户名是否可用
- 16:5.3 immediate 选项
- 17:5.4 deep 选项
- 18:5.5 监听对象单个属性的变化
- 19:6.1 什么是计算属性
- 20:6.2 计算属性的特点
- 21:7.1 什么是 vue-cli
- 22:7.2 安装和使用
- 23:7.3 vue 项目的运行流程
- 24:8.1 什么是组件化开发
- 25:8.2 vue 中的组件化开发
- 26:8.3 vue 组件的三个组成部分
- 26.1:8.3.1 template
- 26.2:8.3.2 script
- 26.3:8.3.3 style
- 27:8.4组件之间的父子关系
- 27.1:8.4.1 使用组件的三个步骤
- 27.2:8.4.2 注册全局组件
- 28:8.5组件的 props
- 28.1:8.5.1 props 是只读的
- 28.2:8.5.2 props 的 default 默认值
- 28.3:8.5.3 props 的 type 值类型
- 28.4:8.5.4 props 的 required 必填项
- 29:8.6 组件之间的样式冲突问题
- 29.1:8.6.1 自定义属性
- 29.2:8.6.2 style 节点的 scoped 属性
- 29.3:8.6.3 /deep/ 样式穿透
- 30:9.1 生命周期 & 生命周期函数
- 31:9.2 组件生命周期函数的分类
- 32:10.1 Vue 3 的 Template 支持多个根标签,Vue 2 不支持
- 33:10.2 Composition API
- 34:10.3 建立数据 data
- 35:10.4 父子传参不同,setup() 函数特性
1. Vue简介
1.1 什么是 vue
官方给出的概念:Vue是一套用于构建用户界面的前端框架。
1.2 vue 的特性
vue 框架的特性,主要体现在如下两方面: ① 数据驱动视图 ② 双向数据绑定
1.2.1 数据驱动视图
在使用了 vue 的页面中,vue 会监听数据的变化,从而自动重新渲染页面的结构。

好处:当页面数据发生变化时,页面会自动重新渲染!
注意:数据驱动视图是单向的数据绑定。
1.2.2 双向数据绑定
在填写表单时,双向数据绑定可以辅助开发者在不操作 DOM 的前提下,自动把用户填写的内容同步到数据源 中。示意图如下

好处:开发者不再需要手动操作 DOM 元素,来获取表单元素最新的值!
1.2.3 MVVM
MVVM 是 vue 实现数据驱动视图和双向数据绑定的核心原理。MVVM 指的是 Model、View 和 ViewModel, 它把每个 HTML 页面都拆分成了这三个部分,如图所示

在 MVVM 概念中:
- Model 表示当前页面渲染时所依赖的数据源。
- View 表示当前页面所渲染的 DOM 结构。
- ViewModel 表示 vue 的实例,它是 MVVM 的核心。
1.2.4 MVVM 的工作原理
ViewModel 作为 MVVM 的核心,是它把当前页面的数据源(Model)和页面的结构(View)连接在了一起。

当数据源发生变化时,会被 ViewModel 监听到,VM 会根据最新的数据源自动更新页面的结构
当表单元素的值发生变化时,也会被 VM 监听到,VM 会把变化过后最新的值自动同步到 Model 数据源中
2. Vue2的基本使用
- 1.导入vue.js文件,或通过链接导入
- 2.new Vue()构造函数,得到vm实例对象
- 3.声明el和data数据节点
- el:控制区域 data:数据源 methods:处理函数
- 4.MVVM的对应关系
- M:model(指data数据源) V:view(el所控制的区域) VM:view model核心(vue实例对象)
3. Vue2的常见指令
指令(Directives)是 vue 为开发者提供的模板语法,用于辅助开发者渲染页面的基本结构。
vue 中的指令按照不同的用途可以分为如下 6 大类:
- ① 内容渲染指令
- ② 属性绑定指令
- ③ 事件绑定指令
- ④ 双向绑定指令
- ⑤ 条件渲染指令
- ⑥ 列表渲染指令
3.1 内容渲染指令
内容渲染指令用来辅助开发者渲染 DOM 元素的文本内容。常用的内容渲染指令有如下 3 个:
- v-text:覆盖元素内默认的值。
- {{ }}:差值表达式,不会覆盖元素中默认的文本内容,只能用在内容节点
- v-html:v-text 指令和插值表达式只能渲染纯文本内容。如果要把包含 HTML 标签的字符串渲染为页面的 HTML 元素
3.2 属性绑定指令
- v-bind(缩写 : ):如果需要为元素的属性动态绑定属性值,则需要用到 v-bind 属性绑定指令,用在绑定属性节点
3.3 事件绑定指令
- v-on(缩写@) :用来辅助程序员为 DOM 元素绑定事件监听,通过 v-on 绑定的事件处理函数,需要在 methods 节点中进行声明
注意:原生 DOM 对象有 onclick、oninput、onkeyup 等原生事件,替换为 vue 的事件绑定形式后, 分别为:v-on:click、v-on:input、v-on:keyup
在事件处理函数中调用 event.preventDefault() 或 event.stopPropagation() 是非常常见的需求。因此, vue 提供了事件修饰符的概念,来辅助程序员更方便的对事件的触发进行控制。常用的 5 个事件修饰符如下:
事件修饰符 | 说明 |
.prevent | 阻止默认行为(例如:阻止 a 连接的跳转、阻止表单的提交等) |
.stop | 阻止事件冒泡 |
.capture | 以捕获模式触发当前的事件处理函数 |
.once | 绑定的事件只触发1次 |
.self | 只有在 event.target 是当前元素自身时触发事件处理函数 |
语法格式如下:
<a href="https://www.baidu.com" @click.prevent="onLinkClcik">百度首页</a>
//触发click点击事件,阻止a链接的默认跳转行为
3.4 双向绑定指令
- v-model:双向绑定,对于v-bind,他是单向的,是从model到view即数据到视图。
修饰符 | 作用 | 示例 |
.number | 自动将用户的输入值转为数值类型 | <input v-model.number="age" /> |
.trim | 自动过滤用户输入的首尾空白字符 | <input v-model.trim="msg" /> |
.lazy | 在“change”时而非“input”时更新 | <input v-model.lazy="msg" /> |
3.5 条件渲染指令
- v-if、v-show:按条件渲染
- v-if:会动态地创建或移除 DOM 元素,频繁使用会损耗性能
- v-show:相当于在其样式上添加行内样式:display:none
- 一般性能不用考虑可直接使用v-if
3.6 列表渲染指令
- v-for :需要循环创建相似的UI结构
v-for 指令需要使 用 item in items 形式的特殊语法,其中:
- items 是待循环的数组
- item 是被循环的每一项
data:{
list:[
{ id:1,name'zs' },
{ id:2,name'ls' }
]
}
<ul>
<li v-for="item in list" :key="item.id">姓名是:{{ item.name }}</li>
</ul>
v-for 指令还支持一个可选的第二个参数,即当前项的索引。语法格式为 (item, index) in items
注意:v-for 指令中的 item 项和 index 索引都是形参,可以根据需要进行重命名。例如 (user, i) in userlist
- :key:可以使用序号,但是没有意义,但是一般用id来绑定,因为如果序号出现删除后再增加,会出现key相同的情况。
4. 过滤器
过滤器(Filters)是 vue 为开发者提供的功能,常用于文本的格式化。过滤器可以用在两个地方:插值表达式 和 v-bind 属性绑定。
过滤器应该被添加在 JavaScript 表达式的尾部,由“管道符”进行调用,示例代码如下:
//双大括号中通过“管道符”调用capitalize过滤器,对message的值进行格式化
<p>{{ message| capitalize }}</p>
//在v-bind中通过“管道符”调用formatID过滤器,对rawID的值进行格式化
<div v-bind:id="rawID | formatID"></div>
4.1 定义过滤器
在创建 vue 实例期间,可以在 filters 节点中定义过滤器,示例代码如下:
const vm = new Vue ({
el:'#app',
data: {
message:hellow
info:'title info'
},
filters: { //在filters 节点下定义"过滤器
capitalize(str) { // 把首字母转为大写的过滤器
return str . charAt(0). toUpperCase() + str .slice(1)
}
})
4.2 私有过滤器和全局过滤器
在 filters 节点下定义的过滤器,称为“私有过滤器”,因为它只能在当前 vm 实例所控制的 el 区域内使用。 如果希望在多个 vue 实例之间共享过滤器,则可以按照如下的格式定义全局过滤器:
//全局过滤器-独立于每个Vm实例之外
// Vue. filter()方法接收两个参数:
//第1个参数,是全局过滤器的"名字”
//第2个参数,是全局过滤器的"处理函数”
Vue. filter('capitalize', (str) => {
return str . charAt(0). toUpperCase() + str .slice(1) + '--'
})
4.3 连续调用多个过滤器
过滤器可以串联地进行调用,例如
//把message的值交给filterA进行处理
//把filterA处理的结果再交给filterB进行处理
//最终把filterB处理的结果作为最终的值渲染到页面上
{{ message | filterA | filterB }}
4.4 过滤器传参
过滤器的本质是 JavaScript 函数,因此可以接收参数,格式如下:
<!-- arg1 和arg2是传递给filterA的参数-->
<p>{{ message | filterA(arg1 ,arg2) }}</p>
//过滤器处理函数的形参列表中:
//第一个参数:永远都是”管道符”前面待处理的值
//从第二个参数开始,才是调用过滤器时传递过来的arg1和arg2 参数
Vue. filter('filterA', (msg, arg1, arg2) => {
//过滤器的代码逻辑...
})
4.5 过滤器的兼容性
过滤器仅在 vue 2.x 和 1.x 中受支持,在 vue 3.x 的版本中剔除了过滤器相关的功能。
5. watch 侦听器
5.1 什么是 watch 侦听器
watch 侦听器允许开发者监视数据的变化,从而针对数据的变化做特定的操作,语法格式:
const Vm = new Vue({
el: ' #app',
data: { username: ' },
watch: {
//监听username值的变化
// newVal 是"变化后的新值”,oldVal 是"变化之前的旧值”
username(newVal, oldVal) {
console. log(newVal, oldVal)
}
}
})
5.2 使用 watch 检测用户名是否可用
监听 username 值的变化,并使用 axios 发起 Ajax 请求,检测当前输入的用户名是否可用:
watch: {
// 监听 username 值的变化
async username(newVal) {
if (newVal === '') return
// 使用 axios 发起请求,判断用户名是否可用
const { data: res } = await axios.get('https://www.escook.cn/api/finduser/' + newVal)
console.log(res)
}
}
5.3 immediate 选项
默认情况下,组件在初次加载完毕后不会调用 watch 侦听器。如果想让 watch 侦听器立即被调用,则需要使用 immediate 选项。
immediate: true
5.4 deep 选项
如果 watch 侦听的是一个对象,如果对象中的属性值发生了变化,则无法被监听到。此时需要使用 deep 选项
deep: true
5.5 监听对象单个属性的变化
如果只想监听对象中单个属性的变化,则可以按照如下的方式定义 watch 侦听器:
const Vm = new Vue({
el:' #app',
data: {
info: { username: 'admin' }
},
watch: {
'info.username ': {
handler(newVal) {
console. log(newVal)
}
}
}
})
6. 计算属性
6.1 什么是计算属性
计算属性指的是通过一系列运算之后,最终得到一个属性值。
这个动态计算出来的属性值可以被模板结构或 methods 方法使用。示例代码如下:
var Vm = new Vue({
el: ' #app '
data: {
r:0,g:0,b:0
},
computed: {
rgb() { return rgb(${this.r}, ${this.g}, ${this.b}) }
},
methods: {
show() { console. log(this.rgb) }
},
})
6.2 计算属性的特点
- ① 虽然计算属性在声明的时候被定义为方法,但是计算属性的本质是一个属性
- ② 计算属性会缓存计算的结果,只有计算属性依赖的数据变化时,才会重新进行运算
7. vue-cli
7.1 什么是 vue-cli
vue-cli 是 Vue.js 开发的标准工具。它简化了程序员基于 webpack 创建工程化的 Vue 项目的过程。程序员可以专注在撰写应用上,而不必花好几天去纠结 webpack 配置的问题。
7.2 安装和使用
vue-cli 是 npm 上的一个全局包,使用 npm install 命令,即可方便的把它安装到自己的电脑上:
npm install -g @vue/cli
基于 vue-cli 快速生成工程化的 Vue 项目:
vue create 项目的名称
7.3 vue 项目的运行流程
在工程化的项目中,vue 要做的事情很单纯:通过 main.js 把 App.vue 渲染到 index.html 的指定区域中。
其中:
- ① App.vue 用来编写待渲染的模板结构
- ② index.html 中需要预留一个 el 区域
- ③ main.js 把 App.vue 渲染到了 index.html 所预留的区域中
8. vue 组件
8.1 什么是组件化开发
组件化开发指的是:根据封装的思想,把页面上可重用的 UI 结构封装为组件,从而方便项目的开发和维护。
8.2 vue 中的组件化开发
vue 是一个支持组件化开发的前端框架。
vue 中规定:组件的后缀名是 .vue。之前接触到的 App.vue 文件本质上就是一个 vue 的组件。
8.3 vue 组件的三个组成部分
每个 .vue 组件都由 3 部分构成,分别是:
- template -> 组件的模板结构
- script -> 组件的 JavaScript 行为
- style -> 组件的样式
其中,每个组件中必须包含 template 模板结构,而 script 行为和 style 样式是可选的组成部分。
8.3.1 template
vue 规定:每个组件对应的模板结构,需要定义到 <template> 节点中。
<template>
<!--当前组件的DOM结构,需要定义到template 标签的内部-->
</ template>
注意:
- template 是 vue 提供的容器标签,只起到包裹性质的作用,它不会被渲染为真正的 DOM 元素
- template 中只能包含唯一的根节点
8.3.2 script
vue 规定:开发者可以在 <script> 节点中封装组件的 JavaScript 业务逻辑。
<script > 节点的基本结构如下:
<script>
//今后,组件相关的data数据、methods 方法等,
//都需要定义到export default 所导出的对象中。
export default {}
</script>
.vue 组件中的 data 必须是函数
vue 规定:.vue 组件中的 data 必须是一个函数,不能直接指向一个数据对象。
因此在组件中定义 data 数据节点时,下面的方式是错误的:
data: { //组件中,不能直接让data 指向一个数据对象(会报错)
count: 0
}
data(){//正确
return {
count:0
}
}
8.3.3 style
vue 规定:组件内的 <style> 节点是可选的,开发者可以在 <style> 节点中编写样式美化当前组件的 UI 结构。
<script > 节点的基本结构如下:
<style>
h1 {
font -weight:normal;
}
</style>
让 style 中支持 less 语法
在 <style> 标签上添加 lang="less" 属性,即可使用 less 语法编写组件的样式:
<style lang="less">
h1 {
font -weight:
span {
color: red;
}
}
</style>
8.4组件之间的父子关系


8.4.1 使用组件的三个步骤

以上components节点注册的组件,均为私有节点
8.4.2 注册全局组件
在 vue 项目的 main.js 入口文件中,通过 Vue.component() 方法,可以注册全局组件。示例代码如下:
//导入需要全局注册的组件
import Count from " @/ components/ Count .vue
//参数1:字符串格式,表示组件的“注册名称"
//参数2:需要被全局注册的那个组件
Vue.component('MyCount',Count)
8.5组件的 props
props 是组件的自定义属性,在封装通用组件的时候,合理地使用 props 可以极大的提高组件的复用性!
它的语法格式如下:
export default {
//组件的自定义属性
props: ['自定义属性A', '自定义属性B','其它自定义属性...'],
//组件的私有数据
data() {
return { }
}
}
8.5.1 props 是只读的
vue 规定:组件中封装的自定义属性是只读的,程序员不能直接修改 props 的值。否则会直接报错
要想修改 props 的值,可以把 props 的值转存到 data 中,因为 data 中的数据都是可读可写的!
8.5.2 props 的 default 默认值
在声明自定义属性时,可以通过 default 来定义属性的默认值。示例代码如下
export default {
props: {
init: {
//用default 属性定义属性的默认值
default: 0
}
}
}
8.5.3 props 的 type 值类型
在声明自定义属性时,可以通过 type 来定义属性的值类型。示例代码如下:
export default {
props: {
init: {
//用default 属性定义属性的默认值
default: 0,
//用type属性定义属性的值类型
//如果传递过来的值不符合此类型,会终端报错
type:Number
}
}
}
8.5.4 props 的 required 必填项
在声明自定义属性时,可以通过 required 选项,将属性设置为必填项,强制用户必须传递属性的值。
示例代码:
export default {
props: {
init: {
type:Number
//必填项
required: true
}
}
}
8.6 组件之间的样式冲突问题
默认情况下,写在 .vue 组件中的样式会全局生效,因此很容易造成多个组件之间的样式冲突问题。
导致组件之间样式冲突的根本原因是:
- ① 单页面应用程序中,所有组件的 DOM 结构,都是基于唯一的 index.html 页面进行呈现的
- ② 每个组件中的样式,都会影响整个 index.html 页面中的 DOM 元素
8.6.1 自定义属性
为每个组件分配唯一的自定义属性,在编写组件样式时,通过属性选择器来控制样式的作用域,示例代码如下:
<template>
<div class=" container" data-v-001>
<h3 data-v-001>轮播 图组件</h3>
</div>
</template>
<style>
/*通过中括号"属性选择器",来防止组件之间的"样式冲突问题",因为每个组件分配的自定义属性是"唯一-的" */
.container [data-v-0001] {
border: 1px solid red;
}
</style>
8.6.2 style 节点的 scoped 属性
为了提高开发效率和开发体验,vue 为 style 节点提供了 scoped 属性,从而防止组件之间的样式冲突问题:
<template>
<div class=" container">
<h3>轮播 图组件</h3>
</div>
</template>
<style scoped>
/* style节点的scoped 属性,用来自动为每个组件分配唯一的“自定 义属性”,并自动为当前组件的DOM标签和style样式应用这个自定义属性,防止组件的样式冲突问题*/
.container {
border: 1px solid red;
}
</style>
8.6.3 /deep/ 样式穿透
如果给当前组件的 style 节点添加了 scoped 属性,则当前组件的样式对其子组件是不生效的。如果想让某些样 式对子组件生效,可以使用 /deep/ 深度选择器。
<style lang="less" scoped>
.title {
color: blue; /*不加/deep/ 时,生成的选择器格式为. title[ data-v-052242de ]
}
/deep/ .title {
color: blue; /*加上/deep/ 时,生成的选择器格式为[data-v-052242de] .title */
}
</style>
9. 组件的生命周期
9.1 生命周期 & 生命周期函数
生命周期(Life Cycle)是指一个组件从 创建 -> 运行 -> 销毁的整个阶段,强调的是一个时间段。
生命周期函数:是由 vue 框架提供的内置函数,会伴随着组件的生命周期,自动按次序执行。
注意:生命周期强调的是时间段,生命周期函数强调的是时间点。
9.2 组件生命周期函数的分类

10.Vue2与Vue3的区别
10.1 Vue 3 的 Template 支持多个根标签,Vue 2 不支持
Vue2只能在 Template 节点下只能放一个根标签、Vue3可以放多个根标签
vue2:
<template>
<div class='form-element'>
<h2> {{ title }} </h2>
</div>
</template>
vue3:
<template>
<div class='form-element'>
</div>
<h2> {{ title }} </h2>
</template>
10.2 Composition API
Vue2与Vue3 最大的
区别 — Vue2使用选项类型API(Options API)对比Vue3合成型API(Composition API)
旧的选项型API在代码里分割了不同的属性: data,computed属性,methods,等等。新的合成型API能让我们用方法(function)来分割,相比于旧的API使用属性来分组,这样代码会更加简便和整洁。
vue2:
export default {
props: {
title: String
},
data () {
return {
username: '',
password: ''
}
},
methods: {
login () {
// 登陆方法
}
},
components:{
"buttonComponent":btnComponent
},
computed:{
fullName(){
return this.firstName+" "+this.lastName;
}
}
}
vue3:
export default {
props: {
title: String
},
setup () {
const state = reactive({ //数据
username: '',
password: '',
lowerCaseUsername: computed(() => state.username.toLowerCase()) //计算属性
})
//方法
const login = () => {
// 登陆方法
}
return {
login,
state
}
}
}
10.3 建立数据 data
Vue2 - 这里把数据放入data属性中
export default {
props: {
title: String
},
data () {
return {
username: '',
password: ''
}
}
}
在Vue3.0,我们就需要使用一个新的setup()方法,此方法在组件初始化构造的时候触发。
使用以下三步来建立反应性数据:
- 从vue引入reactive
- 使用reactive()方法来声名我们的数据为响应性数据
- 使用setup()方法来返回我们的响应性数据,从而我们的template可以获取这些响应性数据
import { reactive } from 'vue'
export default {
props: {
title: String
},
setup () {
const state = reactive({
username: '',
password: ''
})
return { state }
}
}
template使用,可以通过state.username和state.password获得数据的值。
<template>
<div>
<h2> {{ state.username }} </h2>
</div>
</template>
vue2:

vue3:
setup() :开始创建组件之前,在beforeCreate和created之前执行。创建的是data和method
onBeforeMount() : 组件挂载到节点上之前执行的函数。
onMounted() : 组件挂载完成后执行的函数。
onBeforeUpdate(): 组件更新之前执行的函数。
onUpdated(): 组件更新完成之后执行的函数。
onBeforeUnmount(): 组件卸载之前执行的函数。
onUnmounted(): 组件卸载完成后执行的函数
onActivated(): 被包含在中的组件,会多出两个生命周期钩子函数。被激活时执行。
onDeactivated(): 比如从 A 组件,切换到 B 组件,A 组件消失时执行。
onErrorCaptured(): 当捕获一个来自子孙组件的异常时激活钩子函数。
生命周期函数 | Vue2 | Vue3 |
开始创建组件之前 | beforeCreate() | use setup() |
创建组件完成 | created() | use setup() |
组件挂载到节点上之前执行 | beforeMount() | onBeforeMount |
组件挂载完成后执行 | mounted() | onMounted |
组件更新之前执行 | beforeUpdate() | onBeforeUpdate |
组件更新完成之后执行 | updated() | onUpdated |
组件销毁之前执行 | beforeDestory() | onBeforeUnmount |
组件销毁完成后执行 | destoryed() | onUnmounted |
被包含在中的组件,会多出两个生命周期钩子函数。被激活时执行 | activated() | onActivated |
比如从 A 组件,切换到 B 组件,A 组件消失时执行 | deactivated() | onDeactivated |
当捕获一个来自子孙组件的异常时激活钩子函数 | errorCaptured() | onErrorCaptured |
onRenderTracked(新增) — DebuggerEvent 调试用 | ||
onRenderTriggered(新增) — DebuggerEvent 调试用 |
10.4 父子传参不同,setup() 函数特性
总结:
1、setup 函数时,它将接受两个参数:(props、context(包含attrs、slots、emit))
2、setup函数是处于 生命周期函数 beforeCreate 和 Created 两个钩子函数之前的函数
3、执行 setup 时,组件实例尚未被创建(在 setup() 内部,this 不会是该活跃实例的引用,即不指向vue实例,Vue 为了避免我们错误的使用,直接将 setup函数中的this修改成了 undefined)
4、与模板一起使用:需要返回一个对象 (在setup函数中定义的变量和方法最后都是需要 return 出去的 不然无法再模板中使用)
5、使用渲染函数:可以返回一个渲染函数,该函数可以直接使用在同一作用域中声明的响应式状态1
注意事项:
1、setup函数中不能使用this。Vue 为了避免我们错误的使用,直接将 setup函数中的this修改成了 undefined)
2、setup 函数中的 props 是响应式的,当传入新的 prop 时,它将被更新。但是,因为 props 是响应式的,你不能使用 ES6 解构,因为它会消除 prop 的响应性。
如果需要解构 prop,可以通过使用 setup 函数中的toRefs 来完成此操作:
父传子,props
import { toRefs } from 'vue'
setup(props) {
const { title } = toRefs(props)
console.log(title.value)
onMounted(() => {
console.log('title: ' + props.title)
})
}
子传父,事件 - Emitting Events
举例,现在我们想在点击提交按钮时触发一个login的事件。
1、在 Vue2 中我们会调用到this.$emit然后传入事件名和参数对象。
login () {
this.$emit('login', {
username: this.username,
password: this.password
})
}
2、在setup()中的第二个参数content对象中就有emit,这个是和this.$emit是一样的。那么我们只要在setup()接收第二个参数中使用分解对象法取出emit就可以在setup方法中随意使用了。
然后我们在login方法中编写登陆事件
另外:context 是一个普通的 JavaScript 对象,也就是说,它不是响应式的,这意味着你可以安全地对 context 使用 ES6 解构
setup (props, { attrs, slots, emit }) {
// ...
const login = () => {
emit('login', {
username: state.username,
password: state.password
})
}
// ...
}
3、 setup()内使用响应式数据时,需要通过.value获取
import { ref } from 'vue'
const count = ref(0)
console.log(count.value) // 0
4、从 setup() 中返回的对象上的 property 返回并可以在模板中被访问时,它将自动展开为内部值。不需要在模板中追加 .value
5、setup函数只能是同步的不能是异步的