目录
Vue3核心语法1
OptionsAPI 与 CompositionAPI
setup函数
setup 概述
setup 语法糖
ref 创建:基本类型的响应式数据
reactive 创建:对象类型的响应式数据
ref 创建:对象类型的响应式数据
ref 对比 reactive
toRefs 与 toRef
computed
watch
情况一:监视 ref 定义的基本类型数据
情况二:监视 ref 定义的对象类型数据
情况三:监视 reactive 定义的对象类型数据
情况四:监视 ref 或 reactive 定义的对象类型数据中的某个属性
情况五:监视多个数据
Vue3核心语法1
OptionsAPI 与 CompositionAPI
Vue.js 是一个流行的前端 JavaScript 框架,它提供了两种不同的 API 风格来编写组件:Options (选项式)API 和 Composition(组合式) API。
1、Options API:
Options API 是 Vue.js 最初提供的 API 风格。在 Options API 中,你通过创建一个包含不同属性的对象来定义组件。这些属性可以包括 data、methods、computed、watch、props 等。每个属性都有其特定的作用,比如 data 用于定义组件的数据,methods 用于定义组件的方法,computed 用于定义计算属性等。
// Options API 示例
export default {data() {return {message: 'Hello, Vue!'};},methods: {greet() {alert(this.message);}}
};
2、Composition API:
Composition API 是 Vue.js 3.0 引入的新的 API 风格。与 Options API 不同,Composition API 允许你使用函数来组织你的代码,而不是将所有相关逻辑分散在不同的选项中。使用 Composition API,你可以将相关代码放在一起,并且可以更灵活地重用逻辑。
// Composition API 示例
import { ref, computed } from 'vue';export default {setup() {const message = ref('Hello, Vue!');function greet() {alert(message.value);}return {message,greet};}
};
主要区别:
- Options API 更适合小型应用程序或者对 Vue.js 不太熟悉的开发者,因为它的语法更直观,易于理解。
- Composition API 更适合复杂的组件或者大型应用程序,因为它更灵活,更容易组织和重用代码。
setup函数
setup 概述
setup 函数是 Vue 3 中的一个新的配置项,它是 Composition API 的入口点,用于配置组件内部所需的数据、方法、计算属性、监视等逻辑。
以下是关于 setup 函数的概述:
- 新配置项:setup 是 Vue 3 中新增加的配置项,与 Options API 中的 data、methods 等相对应,用于组织组件内部的逻辑。
- 函数返回值:setup 函数返回一个对象,对象中包含了组件内部所需的数据、方法、计算属性等,这些内容可以直接在模板中使用。
- 访问 this:在 setup 函数内部,无法直接访问 this,因为在 setup 执行时,组件实例尚未创建,this 是 undefined。取而代之的是通过参数来获取组件的属性和上下文信息。
- 执行时机:setup 函数会在组件实例创建之前调用,在 beforeCreate 生命周期钩子之前执行。因此,它是组件内部逻辑配置的第一个入口点。
- 功能扩展:setup 函数为 Vue 3 提供了更灵活的组件逻辑配置方式,使得代码更易于组织、重用,特别适用于复杂组件或大型应用程序的开发。
总的来说,setup 函数作为 Composition API 的入口点,为 Vue 3 的组件开发提供了更强大的能力和更清晰的代码结构,使得开发者可以更好地管理组件内部的状态和行为。
setup 语法糖
在 Vue 3 中,有一种称为“语法糖”的特性,可以简化使用 setup 函数的过程,这就是 <script setup> 语法糖。
使用 <script setup> 语法糖可以更简洁地定义组件,并且无需显式地编写 setup 函数。Vue 会自动将你的代码转换为等效的 setup 函数形式。
代码如下:
<template><div class="person"><h2>姓名:{{name}}</h2><h2>年龄:{{age}}</h2><button @click="changeName">修改名字</button><button @click="changeAge">年龄+1</button><button @click="showTel">点我查看联系方式</button></div>
</template>
<script lang="ts">
export default {name: "Preson",
};
</script>
<script setup lang="ts">
import { ref } from 'vue';
const name = ref('张三');
const age = ref(18);
const tel = '1234567890';
function changeName() {name.value = '李四';
}
function changeAge() {age.value +=1;
}
function showTel() {alert(tel)
}
</script>
<style scoped>.person {background-color: skyblue;box-shadow: 0 0 10px;border-radius: 10px;padding: 20px;}button {margin: 0 5px;}
</style>
扩展:上述代码,还需要编写一个不写`setup`的`script`标签,去指定组件名字,比较麻烦,我们可以借助`vite`中的插件简化
第一步:npm i vite-plugin-vue-setup-extend -D
第二步:打开vite.config.ts
import { defineConfig } from 'vite'
import VueSetupExtend from 'vite-plugin-vue-setup-extend'export default defineConfig({plugins: [ VueSetupExtend() ]
})
第三步:<script setup lang="ts" name="Person">
ref 创建:基本类型的响应式数据
1、作用: 定义响应式变量,这意味着当变量的值发生变化时,相关的视图会自动更新。
2、语法: 使用 let xxx = ref(初始值) 来创建一个响应式变量,其中 xxx 是变量名,初始值 是变量的初始值。
3、返回值: ref 函数返回一个 RefImpl 实例对象,简称为 ref对象 或 ref。该对象具有一个 value 属性,该属性是响应式的,即当 value 发生变化时,相关的视图会进行更新。
4、注意点:
- 在 JavaScript 中,操作响应式数据时需要使用 xxx.value,但在模板中不需要加 .value,直接使用变量名即可。
- 举例来说,如果有 let name = ref('张三') 这样的语句,name 不是响应式的,而 name.value 是响应式的。
扩展一下:推荐一个vscode的一个设置,设置后vscode会自动帮你.value
第一步:打开vscode的设置
第二步:点击扩展,找到volar
第三步:将下图的选项勾选上
例子:
<template><div class="person"><h2>姓名:{{name}}</h2><h2>年龄:{{age}}</h2><h2>性别: {{ sex }}</h2><button @click="changeName">修改名字</button><button @click="changeAge">年龄+1</button><button @click="sex = '女'">修改性别</button></div>
</template>
<script setup lang="ts" name ="Preson">
import { ref } from 'vue';
const name = ref('张三');
const age = ref(18);
const sex = ref('男');
function changeName() {name.value = '李四';
}
function changeAge() {age.value +=1;
}
</script>
<style scoped>.person {background-color: skyblue;box-shadow: 0 0 10px;border-radius: 10px;padding: 20px;}button {margin: 0 5px;}
</style>
reactive 创建:对象类型的响应式数据
1、作用: reactive 函数用于定义一个响应式对象,即当对象的属性发生变化时,相关的视图会自动更新。需要注意的是,应该将 reactive 用于对象类型的数据,而不是基本类型的数据,对于基本类型的数据应该使用 ref。
2、语法: 使用 let 响应式对象 = reactive(源对象) 来创建一个响应式对象,其中 响应式对象 是你想要创建的响应式对象的变量名,源对象 是你想要转换为响应式对象的普通 JavaScript 对象。
3、返回值: reactive 函数返回一个 Proxy 的实例对象,这个实例对象就是我们所说的响应式对象,它会拦截对对象的操作,使得这些操作变得响应式。
4、注意点: 使用 reactive 定义的响应式数据是“深层次”的,这意味着如果对象的嵌套属性发生变化,相关的视图也会更新。
例子:
<template><div class="person"><h2>学生信息</h2><p>姓名:{{ student.name }}</p><p>年龄:{{ student.age }}</p><p>性别:{{ student.gender }}</p><button @click="changeInfo">修改信息</button></div>
</template>
<script setup lang="ts" name ="Preson">
import { reactive } from 'vue';// 定义一个普通的 JavaScript 对象
const normalStudent = {name: '张三',age: 20,gender: '男'
};// 使用 reactive 函数将普通对象转换为响应式对象
const student = reactive(normalStudent);// 修改学生信息的方法
function changeInfo() {// 修改响应式对象的属性student.name = '李四';student.age += 1;student.gender = '女';
}
</script>
<style scoped>
.person {background-color: skyblue;box-shadow: 0 0 10px;border-radius: 10px;padding: 20px;
}button {margin: 0 5px;
}
</style>
ref 创建:对象类型的响应式数据
在 Vue 中,ref 函数不仅可以用于创建基本类型的响应式数据,还可以用于创建对象类型的响应式数据。实际上,如果将对象传递给 ref 函数,内部会自动调用 reactive 函数来将对象转换为响应式对象。
这种用法的好处是,无需手动调用 reactive 函数,而是直接使用 ref 函数来统一管理基本类型和对象类型的响应式数据。
例子:
<template><div class="person"><h2>学生信息</h2><p>姓名:{{ student.name }}</p><p>年龄:{{ student.age }}</p><p>性别:{{ student.gender }}</p><button @click="changeInfo">修改信息</button></div>
</template>
<script setup lang="ts" name ="Preson">
import { ref } from 'vue';// 使用 ref 函数创建对象类型的响应式数据
const student = ref({name: '张三',age: 20,gender: '男'
});// 修改学生信息的方法
function changeInfo() {// 通过 ref 的 .value 属性修改对象的属性student.value.name = '李四';student.value.age += 1;student.value.gender = '女';
}
</script>
<style scoped>
.person {background-color: skyblue;box-shadow: 0 0 10px;border-radius: 10px;padding: 20px;
}button {margin: 0 5px;
}
</style>
ref 对比 reactive
用途:
- ref 用于定义基本类型数据和对象类型数据。
- reactive 用于定义对象类型数据。
区别:
- 使用 ref 创建的变量,在访问其值时必须使用 .value,而 reactive 创建的变量不需要。
- 当重新分配一个新对象给 reactive 创建的变量时,会失去响应式,但可以使用 Object.assign 进行整体替换。
使用原则:
- 如果需要一个基本类型的响应式数据,必须使用 ref。
- 如果需要一个响应式对象,且层级不深,ref 和 reactive 都可以使用。
- 如果需要一个响应式对象,且层级较深,推荐使用 reactive。
总的来说,ref 更适合用于管理基本类型的响应式数据以及浅层次的对象类型数据,而 reactive 则更适合用于管理深层次的对象类型数据。
toRefs 与 toRef
toRefs 和 toRef 是 Vue 3 提供的两个工具函数,用于处理响应式对象和 ref 对象之间的转换。
toRefs
- 作用: 将一个响应式对象中的每一个属性,转换为 ref 对象。
- 备注: toRefs 可以批量转换多个属性。
toRef
- 作用: 将一个响应式对象的指定属性,转换为单独的 ref 对象。
- 备注: toRef 用于单个属性的转换。
比较
- toRefs 能够将整个响应式对象的所有属性都转换为 ref 对象,返回一个包含了所有属性的对象。
- toRef 则是将一个响应式对象的指定属性转换为 ref 对象。
使用时,如果需要批量转换多个属性,可以使用 toRefs;如果只需要转换一个属性,可以使用 toRef。
例子:
<template><div class="person"><p>计算: {{ state.count }}</p><p>名字: {{ state.name }}</p><button @click="increment">增加</button><button @click="changeName">修改名字</button><button @click="resetCount">重置</button></div>
</template>
<script setup lang="ts" name ="Preson">
import { reactive, toRefs, toRef } from 'vue';// 定义一个响应式对象
const state = reactive({count: 0,name: '张三'
});// 使用 toRefs 将响应式对象的所有属性转换为 ref 对象
const stateRefs = toRefs(state);// 使用 toRef 将响应式对象的 count 属性转换为单独的 ref 对象
const countRef = toRef(state, 'count');// 修改 count 的方法
function increment() {stateRefs.count.value++;
}// 修改 name 的方法
function changeName() {stateRefs.name.value = '李四';
}// 重置 count 的方法
function resetCount() {countRef.value = 0;
}
</script>
<style scoped>
.person {background-color: skyblue;box-shadow: 0 0 10px;border-radius: 10px;padding: 20px;
}button {margin: 0 5px;
}
</style>
computed
computed 是 Vue.js 中的一个计算属性(和`Vue2`中的`computed`作用一致),它可以根据响应式数据动态计算出一个新的值,并且在依赖的响应式数据发生变化时自动更新。
例子:
<template><div class="person">姓:<input type="text" v-model="firstName"> <br>名:<input type="text" v-model="lastName"> <br>全名:<span>{{ fullName }}</span> <br><button @click="changeFullName">全名改为:li-si</button></div>
</template><script setup lang="ts">
import { ref, computed } from 'vue';// 使用 ref 创建响应式数据
const firstName = ref('张');
const lastName = ref('三');// 使用 computed 创建计算属性
const fullName = computed({// 读取get(){return firstName.value + '-' + lastName.value},// 修改set(val){firstName.value = val.split('-')[0]lastName.value = val.split('-')[1]}})// 修改全名的方法
function changeFullName() {// 计算属性 fullName 是只读的,无法直接修改// 如果需要修改全名,可以直接操作 firstName 和 lastNamefirstName.value = '李';lastName.value = '四';
}
</script><style scoped>
.person {background-color: skyblue;box-shadow: 0 0 10px;border-radius: 10px;padding: 20px;
}button {margin: 0 5px;
}
</style>
watch
watch 在 Vue 3 中用于监视数据的变化,其功能与 Vue 2 中的 watch 类似。在 Vue 3 中,watch 只能监视四种类型的数据:ref 定义的数据、reactive 定义的数据、函数返回的值、以及一个包含上述内容的数组。下面是几种常见的使用情况:
情况一:监视 ref 定义的基本类型数据
监视 ref 定义的【基本类型】数据:直接写数据名即可,监视的是其`value`值的改变。
import { ref, watch } from 'vue';const count = ref(0);watch(count, (newValue, oldValue) => {console.log('count 值发生变化:', newValue, oldValue);
});
情况二:监视 ref 定义的对象类型数据
监视 ref 定义的【对象类型】数据:直接写数据名,监视的是对象的【地址值】,若想监视对象内部的数据,要手动开启深度监视(deep: true)。
注意:
- 若修改的是`ref`定义的对象中的属性,`newValue` 和 `oldValue` 都是新值,因为它们是同一个对象。
- 若修改整个`ref`定义的对象,`newValue` 是新值, `oldValue` 是旧值,因为不是同一个对象了。
import { ref, watch } from 'vue';const person = ref({ name: 'John', age: 30 });// 监视对象的地址值
watch(person, (newValue, oldValue) => {console.log('person 对象的地址值发生变化:', newValue, oldValue);
});// 监视对象内部属性的变化,手动开启深度监视
watch(person, (newValue, oldValue) => {console.log('person 对象内部属性发生变化:', newValue, oldValue);
}, { deep: true });
情况三:监视 reactive 定义的对象类型数据
监视 reactive 定义的【对象类型】数据,且默认开启了深度监视。
import { reactive, watch } from 'vue';const person = reactive({ name: 'John', age: 30 });// 默认开启了深度监视
watch(person, (newValue, oldValue) => {console.log('person 对象的地址值发生变化:', newValue, oldValue);
});
情况四:监视 ref 或 reactive 定义的对象类型数据中的某个属性
监视 ref 或 reactive 定义的【对象类型】数据中的 某个属性,注意点如下:
1. 若该属性值不是【对象类型】,需要写成函数形式。
2. 若该属性值是依然是【对象类型】,可直接编,也可写成函数,建议写成函数。
结论:监视的要是对象里的属性,那么最好写函数式,注意点:若是对象监视的是地址值,需要关注对象内部,需要手动开启深度监视(deep: true)。
import { ref, reactive, watch } from 'vue';const person = ref({ name: 'John', age: 30 });// 监视属性值不是对象类型,写成函数形式
watch(() => person.value.age, (newValue, oldValue) => {console.log('person 对象的 age 属性发生变化:', newValue, oldValue);
});// 监视属性值仍然是对象类型,可直接编,也可写成函数,建议写成函数
watch(person.value, (newValue, oldValue) => {console.log('person 对象内部属性发生变化:', newValue, oldValue);
});// 或者使用深度监视
watch(person, (newValue, oldValue) => {console.log('person 对象内部属性发生变化:', newValue, oldValue);
}, { deep: true });
情况五:监视多个数据
import { ref, watch } from 'vue';const count = ref(0);
const name = ref('John');watch([count, name], ([countValue, nameValue], [oldCountValue, oldNameValue]) => {console.log('count 和 name 值发生变化:', countValue, nameValue, oldCountValue, oldNameValue);
});