### setup 概述 `setup`是`Vue3`中一个新的配置项,值是一个函数,组件中所用到的:数据、方法、计算属性、监视......等等,均配置在`setup`中。 特点如下: - `setup`函数返回的对象中的内容,可直接在模板中使用。 - `setup`中访问`this`是`undefined`。 - `setup`函数会在`beforeCreate`之前调用,它是“领先”所有钩子执行的。 ```vue ``` ### setup 的返回值 - 若返回一个**对象**:则对象中的:属性、方法等,在模板中均可以直接使用**(重点关注)。** - 若返回一个**函数**:则可以自定义渲染内容,代码如下: ```jsx setup(){ return ()=> '你好啊!' } ``` ### setup 与 Options API 的关系 - `Vue2` 的配置(`data`、`methos`......)中**可以访问到** `setup`中的属性、方法。 - 但在`setup`中**不能访问到**`Vue2`的配置(`data`、`methos`......)。 - 如果与`Vue2`冲突,则`setup`优先。 ### setup 语法糖 `setup`函数有一个语法糖,这个语法糖,可以让我们把`setup`独立出去,代码如下: ```vue ``` 扩展:上述代码,还需要编写一个不写`setup`的`script`标签,去指定组件名字,比较麻烦,我们可以借助`vite`中的插件简化 1. 第一步:`npm i vite-plugin-vue-setup-extend -D` 2. 第二步:`vite.config.ts` ```jsx import { defineConfig } from 'vite' import VueSetupExtend from 'vite-plugin-vue-setup-extend' export default defineConfig({ plugins: [ VueSetupExtend() ] }) ``` 3. 第三步:` ``` ## 【reactive 创建:对象类型的响应式数据】 - **作用:**定义一个**响应式对象**(基本类型不要用它,要用`ref`,否则报错) - **语法:**`let 响应式对象= reactive(源对象)`。 - **返回值:**一个`Proxy`的实例对象,简称:响应式对象。 - **注意点:**`reactive`定义的响应式数据是“深层次”的。 ```vue ``` ## 【ref 创建:对象类型的响应式数据】 - 其实`ref`接收的数据可以是:**基本类型**、**对象类型**。 - 若`ref`接收的是对象类型,内部其实也是调用了`reactive`函数。 ```vue ``` ## 【ref 对比 reactive】 宏观角度看: > 1. `ref`用来定义:**基本类型数据**、**对象类型数据**; > > 2. `reactive`用来定义:**对象类型数据**。 - 区别: > 1. `ref`创建的变量必须使用`.value`(可以使用`volar`插件自动添加`.value`)。 > > 自动补充value > > 2. `reactive`重新分配一个新对象,会**失去**响应式(可以使用`Object.assign`去整体替换)。 - 使用原则: > 1. 若需要一个基本类型的响应式数据,必须使用`ref`。 > 2. 若需要一个响应式对象,层级不深,`ref`、`reactive`都可以。 > 3. 若需要一个响应式对象,且层级较深,推荐使用`reactive`。 ## 【toRefs 与 toRef】 - 作用:将一个响应式对象中的每一个属性,转换为`ref`对象。 - 备注:`toRefs`与`toRef`功能一致,但`toRefs`可以批量转换。 - 语法如下: ```vue ``` ## 【computed】 作用:根据已有数据计算出新数据(和`Vue2`中的`computed`作用一致)。 ```vue ``` ## 【watch】 - 作用:监视数据的变化(和`Vue2`中的`watch`作用一致) - 特点:`Vue3`中的`watch`只能监视以下**四种数据**: > 1. `ref`定义的数据。 > 2. `reactive`定义的数据。 > 3. 函数返回一个值(`getter`函数)。 > 4. 一个包含上述内容的数组。 我们在`Vue3`中使用`watch`的时候,通常会遇到以下几种情况: ### * 情况一 监视`ref`定义的【基本类型】数据:直接写数据名即可,监视的是其`value`值的改变。 ```vue ``` ### * 情况二 监视`ref`定义的【对象类型】数据:直接写数据名,监视的是对象的【地址值】,若想监视对象内部的数据,要手动开启深度监视。 > 注意: > > * 若修改的是`ref`定义的对象中的属性,`newValue` 和 `oldValue` 都是新值,因为它们是同一个对象。 > > * 若修改整个`ref`定义的对象,`newValue` 是新值, `oldValue` 是旧值,因为不是同一个对象了。 ```vue ``` ### * 情况三 监视`reactive`定义的【对象类型】数据,且默认开启了深度监视。 ```vue ``` ### * 情况四 监视`ref`或`reactive`定义的【对象类型】数据中的**某个属性**,注意点如下: 1. 若该属性值**不是**【对象类型】,需要写成函数形式。 2. 若该属性值是**依然**是【对象类型】,可直接编,也可写成函数,建议写成函数。 结论:监视的要是对象里的属性,那么最好写函数式,注意点:若是对象监视的是地址值,需要关注对象内部,需要手动开启深度监视。 ```vue ``` ### * 情况五 监视上述的多个数据 ```vue ```