马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
目次
前言
一、vue工程的创建
二、Vue3的核心语法
2.1 【OptionsAPI 与 CompositionAPI】
2.1.1Options API 的弊端
2.1.2 组合式API(Composition API)
2.2 拉开序幕的setup
2.2.1setup 概述
2.3【ref 创建:基本类型的响应式数据】
2.4. 【reactive 创建:对象类型的响应式数据】
2.5. 【ref 创建:对象类型的响应式数据】
2.6. 【ref 对比 reactive】
2.7. 【toRefs 与 toRef】
2.8. 【computed】
说明
与 watch 的区别
2.9.【watch】
* 环境一
* 环境二
* 环境三
* 环境四
环境五 监视上述多个数据信息
2.10. 【watchEffect】
watchEffect 与 watch 的区别
特点
2.11. 【标签的 ref 属性】
示例 1:访问普通 DOM 节点
示例 2:访问子组件实例
子组件 ChildComponent.vue
参考文献
前言
本教程通过搭建一个简单项目,资助读者快速入门Vue3项目实战,把握Vue3、TS、Element Plus、axios等技术栈。
Vue 3是Vue.js的最新主要版本,它带来了许多改进和新特性,包罗但不限于:
性能提升:Vue 3提供了更快的渲染速度和更低的内存利用率。
Composition API:引入了一个新的API,答应更灵活的代码组织和复用,特别得当构建大型应用。
更好的TypeScript支持:Vue 3从头开始就思量了TypeScript的支持,使得利用TypeScript开辟Vue应用更加顺畅。
更小的体积:通过优化和树摇(tree-shaking),Vue 3的体积更小,使得加载时间更短。
一、vue工程的创建
Vue 3项目可以通过Vue CLI或Vite这两种方式创建。Vue CLI是Vue的官方命令行工具,而Vite是一个当代化的前端构建工具,提供了更快的开辟服务器启动和热重载
利用Vue CLI创建项目:
起首,确保你安装了最新版的Vue CLI。如果尚未安装,可以通过npm安装:
然后,创建一个新的Vue 3项目:
在创建过程中,CLI会让你选择预设设置。为了利用Vue 3,你可以选择“Manually select features”来自界说功能,确保选择了“Vue 3”选项。
利用Vite创建项目:
Vite是一个建立在当代Web标准之上的新一代前端构建工具。利用Vite创建Vue 3项目,可以得到极速的服务启动和模块热更新。安装Vite并创建一个新项目:
- ## 1.创建命令
- npm create vue@latest
- ## 2.具体配置
- ## 配置项目名称
- √ Project name: vue3_test
- ## 是否添加TypeScript支持
- √ Add TypeScript? Yes
- ## 是否添加JSX支持
- √ Add JSX Support? No
- ## 是否添加路由环境
- √ Add Vue Router for Single Page Application development? No
- ## 是否添加pinia环境
- √ Add Pinia for state management? No
- ## 是否添加单元测试
- √ Add Vitest for Unit Testing? No
- ## 是否添加端到端测试方案
- √ Add an End-to-End Testing Solution? » No
- ## 是否添加ESLint语法检查
- √ Add ESLint for code quality? Yes
- ## 是否添加Prettiert代码格式化
- √ Add Prettier for code formatting? No
复制代码 手动编写一个App组件
- <template>
- <div class="app">
- <h1>你好啊!</h1>
- </div>
- </template>
- <script lang="ts">
- export default {
- name:'App' //组件名
- }
- </script>
- <style>
- .app {
- background-color: #ddd;
- box-shadow: 0 0 10px;
- border-radius: 10px;
- padding: 20px;
- }
- </style>
复制代码 总结:
- Vite 项目中,index.html 是项目标入口文件,在项目最外层。
- 加载index.html后,Vite 剖析 <script type="module" src="xxx"> 指向的JavaScript。
- Vue3中是通过 createApp 函数创建一个应用实例。
二、Vue3的核心语法
2.1 【OptionsAPI 与 CompositionAPI】
- Vue2的API计划是Options(设置)风格的。
- Vue3的API计划是Composition(组合)风格的。
2.1.1Options API 的弊端
Options类型的 API,数据、方法、计算属性等,是分散在:data、methods、computed中的,若想新增或者修改一个需求,就必要分别修改:data、methods、computed,不便于维护和复用。
- <template>
- <div>{{ fullName }}</div>
- </template>
- <script>
- export default {
- data() {
- return {
- firstName: 'Jane',
- lastName: 'Doe'
- }
- },
- computed: {
- fullName() {
- return this.firstName + ' ' + this.lastName;
- }
- }
- }
- </script>
复制代码
2.1.2 组合式API(Composition API)
Vue 3的组合式API提供了一种更灵活的组织组件逻辑的方式。它通过setup()函数答应你将相干功能组织在一起,而不是基于选项类型分开。这使得代码重用和逻辑提取变得更加简单,尤其是在构建复杂组件时。
- <template>
- <div>{{ fullName }}</div>
- </template>
- <script>
- import { ref, computed } from 'vue';
- export default {
- setup() {
- const firstName = ref('Jane');
- const lastName = ref('Doe');
- const fullName = computed(() => firstName.value + ' ' + lastName.value);
- return { fullName };
- }
- }
- </script>
复制代码 API比较
代码组织:组合式API使得按逻辑组织代码变得更加轻易,特别是在处置惩罚复杂组件时,可以将相干的逻辑放在一起,而不是分散在不同的选项中。
类型推断:组合式API提供了更好的TypeScript集成,因为它能够利用TypeScript的类型推断,使得在利用TypeScript开辟Vue应用时更加顺畅。
代码复用:通过组合式API,可以更轻易地将组件逻辑抽取到可复用的函数中,这对于保持代码的干净和维护性黑白常有资助的。
2.2 拉开序幕的setup
2.2.1setup 概述
setup是Vue3中一个新的设置项,值是一个函数,它是 Composition API “表演的舞台”,组件中所用到的:数据、方法、计算属性、监视......等等,均设置在setup中。
特点如下:
- setup函数返回的对象中的内容,可直接在模板中利用。
- setup中访问this是undefined。
- setup函数会在beforeCreate之前调用,它是“领先”所有钩子实行的。
- <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:'Person',
- setup(){
- // 数据,原来写在data中(注意:此时的name、age、tel数据都不是响应式数据)
- let name = '张三'
- let age = 18
- let tel = '13888888888'
- // 方法,原来写在methods中
- function changeName(){
- name = 'zhang-san' //注意:此时这么修改name页面是不变化的
- console.log(name)
- }
- function changeAge(){
- age += 1 //注意:此时这么修改age页面是不变化的
- console.log(age)
- }
- function showTel(){
- alert(tel)
- }
- // 返回一个对象,对象中的内容,模板中可以直接使用
- return {name,age,tel,changeName,changeAge,showTel}
- }
- }
- </script>
复制代码 2.3【ref 创建:基本类型的响应式数据】
- 作用:界说响应式变量。
- 语法:let xxx = ref(初始值)。
- 返回值:一个RefImpl的实例对象,简称ref对象或ref,ref对象的value属性是响应式的。
- 注意点:
- JS中操纵数据必要:xxx.value,但模板中不必要.value,直接利用即可。
- 对于let name = ref('张三')来说,name不是响应式的,name.value是响应式的。
Person.vue代码如下
- <template>
- <div class="person">
- <h2>姓名:{{name}}</h2>
- <h2>年龄:{{age}}</h2>
- <h2>电话:{{tel}}</h2>
- <h2>地址:{{address}}</h2>
- <button @click="changeName">修改姓名</button>
- <button @click="changeAge">修改年龄</button>
- <button @click="AddAge">增加年龄</button>
- <input type="text" v-model="newusername" placeholder="请输入新的姓名"></input>
- <!--绑定属性-->
- </div>
- </template>
- <script lang="ts" setup name="Person">
- import {ref} from "vue";
- let name = ref('张三')
- let age = ref(18)
- let tel = '13888888888'
- let address = '北京昌平区宏福苑·宏福科技园'
- let newusername = ref('')
- //方法
- //修改姓名
- function changeName(){
- name.value = newusername.value
- }
- //修改年龄
- function changeAge(){
- age.value = 19
- }
- //增加年龄
- function AddAge(){
- age.value = age.value+1
- }
- </script>
- <style>
- .person{
- background-color: aqua;
- box-shadow: 0 0 10px;
- border-radius: 10px;
- padding: 20px;
- }
- button{
- margin: 0 5px;
- }
- </style>
复制代码 App.vue代码
- <template>
- <Person />
- </template>
- <script lang="ts">
- import Person from "@/pagesvue3Code/007_ref创建_基本类型的响应式数据/components/Person.vue"
- export default {
- name:'Vue3CodeIndexDemo1',
- components:{
- Person
- }
- }
- </script>
- <style scoped>
- </style>
复制代码
2.4. 【reactive 创建:对象类型的响应式数据】
- 作用:界说一个响应式对象(基本类型不要用它,要用ref,否则报错)
- 语法:let 响应式对象= reactive(源对象)。
- 返回值:一个Proxy的实例对象,简称:响应式对象。
- 注意点:reactive界说的响应式数据是“深层次”的。
- <template>
- <div class="person">
- <h2>汽车信息:一台{{ car.brand }}汽车,价值{{ car.price }}万</h2>
- <h2>游戏列表:</h2>
- <ul>
- <li v-for="g in games" :key="g.id">{{ g.name }}</li>
- </ul>
- <h2>测试:{{obj.a.b.c.d}}</h2>
- <button @click="changeCarPrice">修改汽车价格</button>
- <button @click="changeFirstGame">修改第一游戏</button>
- <button @click="test">测试</button>
- </div>
- </template>
- <script lang="ts" setup name="Person">
- import { reactive } from 'vue'
- // 数据
- let car = reactive({ brand: '奔驰', price: 100 })
- let games = reactive([
- { id: 'ahsgdyfa01', name: '英雄联盟' },
- { id: 'ahsgdyfa02', name: '王者荣耀' },
- { id: 'ahsgdyfa03', name: '原神' }
- ])
- let obj = reactive({
- a:{
- b:{
- c:{
- d:666
- }
- }
- }
- })
- function changeCarPrice() {
- car.price += 10
- }
- function changeFirstGame() {
- games[0].name = '流星蝴蝶剑'
- }
- function test(){
- obj.a.b.c.d = 999
- }
- </script>
复制代码 2.5. 【ref 创建:对象类型的响应式数据】
- 实在ref吸收的数据可以是:基本类型、对象类型。
- 若ref吸收的是对象类型,内部实在也是调用了reactive函数。
- <template>
- <div class="person">
- <h2>汽车信息:一台{{ car.brand }}汽车,价值{{ car.price }}万</h2>
- <h2>游戏列表:</h2>
- <ul>
- <li v-for="g in games" :key="g.id">{{ g.name }}</li>
- </ul>
- <h2>测试:{{obj.a.b.c.d}}</h2>
- <button @click="changeCarPrice">修改汽车价格</button>
- <button @click="changeFirstGame">修改第一游戏</button>
- <button @click="test">测试</button>
- </div>
- </template>
- <script lang="ts" setup name="Person">
- import { ref } from 'vue'
- // 数据
- let car = ref({ brand: '奔驰', price: 100 })
- let games = ref([
- { id: 'ahsgdyfa01', name: '英雄联盟' },
- { id: 'ahsgdyfa02', name: '王者荣耀' },
- { id: 'ahsgdyfa03', name: '原神' }
- ])
- let obj = ref({
- a:{
- b:{
- c:{
- d:666
- }
- }
- }
- })
- console.log(car)
- function changeCarPrice() {
- car.value.price += 10
- }
- function changeFirstGame() {
- games.value[0].name = '流星蝴蝶剑'
- }
- function test(){
- obj.value.a.b.c.d = 999
- }
- </script>
复制代码 2.6. 【ref 对比 reactive】
宏观角度看:
- ref用来界说:基本类型数据、对象类型数据;
- reactive用来界说:对象类型数据。
- ref创建的变量必须利用.value(可以利用volar插件自动添加.value)。
- reactive重新分配一个新对象,会失去响应式(可以利用Object.assign去整体更换)。
- 若必要一个基本类型的响应式数据,必须利用ref。
- 若必要一个响应式对象,层级不深,ref、reactive都可以。
- 若必要一个响应式对象,且层级较深,推荐利用reactive。
2.7. 【toRefs 与 toRef】
- 作用:将一个响应式对象中的每一个属性,转换为ref对象。
- 备注:toRefs与toRef功能一致,但toRefs可以批量转换。
- 语法如下:
- <template>
- <div class="person">
- <h2>姓名:{{person.name}}</h2>
- <h2>年龄:{{person.age}}</h2>
- <h2>性别:{{person.gender}}</h2>
- <button @click="changeName">修改名字</button>
- <button @click="changeAge">修改年龄</button>
- <button @click="changeGender">修改性别</button>
- </div>
- </template>
- <script lang="ts" setup name="Person">
- import {ref,reactive,toRefs,toRef} from 'vue'
- // 数据
- let person = reactive({name:'张三', age:18, gender:'男'})
-
- // 通过toRefs将person对象中的n个属性批量取出,且依然保持响应式的能力
- let {name,gender} = toRefs(person)
-
- // 通过toRef将person对象中的gender属性取出,且依然保持响应式的能力
- let age = toRef(person,'age')
- // 方法
- function changeName(){
- name.value += '~'
- }
- function changeAge(){
- age.value += 1
- }
- function changeGender(){
- gender.value = '女'
- }
- </script>
复制代码 2.8. 【computed】
作用:根据已有数据计算出新数据(和Vue2中的computed作用一致)
在 Vue 3 中,computed 是一个用于声明计算属性的 API。它可以在组合式 API(Composition API)中利用,资助你界说基于其他响应式数据派生出的属性,并自动缓存和更新这些属性的值。与 Vue 2 中的计算属性相似,computed 在 Vue 3 中也起到减少重复计算、进步性能的作用。
- import { ref, computed } from 'vue';
- export default {
- setup() {
- const count = ref(0);
- // 定义一个计算属性,基于 count 值的变化
- const doubleCount = computed(() => count.value * 2);
- const increment = () => {
- count.value++;
- };
- return {
- count,
- doubleCount,
- increment,
- };
- },
- };
复制代码 说明
- computed 的参数是一个函数,用于返回计算属性的值。
- 当 count 值发生变革时,doubleCount 会自动重新计算。
- computed 是懒计算的,只有在被读取时才会重新计算值,并会缓存上一次的计算结果,直到依靠的响应式数据发生变革。
与 watch 的区别
computed 是用于派生新的状态,适用于基于其他响应式数据的计算,而 watch 则用于观察数据变革并触发副作用。
2.9.【watch】
- 作用:监视数据的变革(和Vue2中的watch作用一致)
- 特点:Vue3中的watch只能监视以下四种数据:
- ref界说的数据。
- reactive界说的数据。
- 函数返回一个值(getter函数)。
- 一个包罗上述内容的数组。
我们在Vue3中利用watch的时间,通常会碰到以下几种环境:
* 环境一
监视ref界说的【基本类型】数据:直接写数据名即可,监视的是其value值的改变。
- <template>
- <div class="person">
- <h1>情况一:监视【ref】定义的【基本类型】数据</h1>
- <h2>当前求和为:{{sum}}</h2>
- <button @click="changeSum">点我+1</button>
- </div>
- </template>
- <script lang="ts" setup name="Person">
- import {ref,watch} from "vue";
- //数据
- let sum=ref(0)
- //方法
- function changeSum(){
- sum.value+=1
- }
- //监视,情况一:监视【ref】定义的【基本类型】数据
- const stopWatch=watch(sum,(newValue,oldValue)=>{
- console.log('watch监听到sum的变化,新的值为:',newValue,oldValue)
- if(newValue >= 10){
- console.log('sum大于10,停止watch')
- stopWatch()
- }
- },{immediate:true})
- </script>
- <style>
- .person{
- background-color: aqua;
- box-shadow: 0 0 10px;
- border-radius: 10px;
- padding: 20px;
- }
- button{
- margin: 0 5px;
- }
- </style>
复制代码
* 环境二
监视ref界说的【对象类型】数据:直接写数据名,监视的是对象的【地点值】,若想监视对象内部的数据,要手动开启深度监视。
注意:
- 若修改的是ref界说的对象中的属性,newValue 和 oldValue 都是新值,因为它们是同一个对象。
- 若修改整个ref界说的对象,newValue 是新值, oldValue 是旧值,因为不是同一个对象了。
- <template>
- <div class="person">
- <h1>情况二:监视【ref】定义的【对象类型】数据</h1>
- <h2>姓名:{{ person.name }}</h2>
- <h2>年龄:{{ person.age }}</h2>
- <button @click="changeName">修改名字</button>
- <button @click="changeAge">修改年龄</button>
- <button @click="changePerson">修改整个人</button>
- </div>
- </template>
- <script lang="ts" setup name="Person">
- import {ref,watch} from 'vue'
- // 数据
- let person = ref({
- name:'张三',
- age:18
- })
- // 方法
- function changeName(){
- person.value.name += '~'
- }
- function changeAge(){
- person.value.age += 1
- }
- function changePerson(){
- person.value = {name:'李四',age:90}
- }
- /*
- 监视,情况一:监视【ref】定义的【对象类型】数据,监视的是对象的地址值,若想监视对象内部属性的变化,需要手动开启深度监视
- watch的第一个参数是:被监视的数据
- watch的第二个参数是:监视的回调
- watch的第三个参数是:配置对象(deep、immediate等等.....)
- */
- watch(person,(newValue,oldValue)=>{
- console.log('person变化了',newValue,oldValue)
- },{deep:true})
-
- </script>
复制代码 * 环境三
监视reactive界说的【对象类型】数据,且默认开启了深度监视。
- <template>
- <div class="person">
- <h1>情况一:监视【ref】定义的【基本类型】数据</h1>
- <h2>当前求和为:{{sum}}</h2>
- <button @click="changeSum">点我+1</button>
- <h1>情况三:监视【reactive】定义的【对象类型】数据</h1>
- <h2>当前用户信息为:{{person.name}}</h2>
- <h2>年龄为:{{person.age}}</h2>
- <button @click="changePerson">修改整个人</button>
- </div>
- </template>
- <script lang="ts" setup name="Person">
- import {ref,watch,reactive} from "vue";
- //数据
- let sum=ref(0)
- let person=reactive({name:"张三",age:20})
- //方法
- function changeSum(){
- sum.value+=1
- }
- function changePerson(){
- Object.assign(person,{name:'李四',age:80})
- }
- //监视,情况一:监视【ref】定义的【基本类型】数据
- const stopWatch=watch(sum,(newValue,oldValue)=>{
- console.log('watch监听到sum的变化,新的值为:',newValue,oldValue)
- if(newValue >= 10){
- console.log('sum大于10,停止watch')
- stopWatch()
- }
- },{immediate:true})
- //情况三:监视【reactive】定义的【对象类型】数据
- watch(person,(newValue,oldValue)=>{
- console.log('watch监听到person的变化,新的值为:',newValue,oldValue)
- })
- </script>
- <style>
- .person{
- background-color: aqua;
- box-shadow: 0 0 10px;
- border-radius: 10px;
- padding: 20px;
- }
- button{
- margin: 0 5px;
- }
- </style>
复制代码 * 环境四
监视ref或reactive界说的【对象类型】数据中的某个属性,注意点如下:
- 若该属性值不是【对象类型】,必要写成函数形式。
- 若该属性值是依然是【对象类型】,可直接编,也可写成函数,建议写成函数。
结论:监视的要是对象里的属性,那么最好写函数式,注意点:若是对象监视的是地点值,必要关注对象内部,必要手动开启深度监视。
- <template>
- <div class="person">
- <h1>情况四:监视【ref】或【reactive】定义的【对象类型】数据中的某个属性</h1>
- <h2>姓名:{{ person.name }}</h2>
- <h2>年龄:{{ person.age }}</h2>
- <h2>汽车:{{ person.car.c1 }}、{{ person.car.c2 }}</h2>
- <button @click="changeName">修改名字</button>
- <button @click="changeAge">修改年龄</button>
- <button @click="changeC1">修改第一台车</button>
- <button @click="changeC2">修改第二台车</button>
- <button @click="changeCar">修改整个车</button>
- </div>
- </template>
- <script lang="ts" setup name="Person">
- import {reactive,watch} from 'vue'
- // 数据
- let person = reactive({
- name:'张三',
- age:18,
- car:{
- c1:'奔驰',
- c2:'宝马'
- }
- })
- // 方法
- function changeName(){
- person.name += '~'
- }
- function changeAge(){
- person.age += 1
- }
- function changeC1(){
- person.car.c1 = '奥迪'
- }
- function changeC2(){
- person.car.c2 = '大众'
- }
- function changeCar(){
- person.car = {c1:'雅迪',c2:'爱玛'}
- }
- // 监视,情况四:监视响应式对象中的某个属性,且该属性是基本类型的,要写成函数式
- /* watch(()=> person.name,(newValue,oldValue)=>{
- console.log('person.name变化了',newValue,oldValue)
- }) */
- // 监视,情况四:监视响应式对象中的某个属性,且该属性是对象类型的,可以直接写,也能写函数,更推荐写函数
- watch(()=>person.car,(newValue,oldValue)=>{
- console.log('person.car变化了',newValue,oldValue)
- },{deep:true})
- </script>
复制代码 环境五 监视上述多个数据信息
- <template>
- <div class="person">
- <h1>情况五:监视上述的多个数据</h1>
- <h2>姓名:{{ person.name }}</h2>
- <h2>年龄:{{ person.age }}</h2>
- <h2>汽车:{{ person.car.c1 }}、{{ person.car.c2 }}</h2>
- <button @click="changeName">修改名字</button>
- <button @click="changeAge">修改年龄</button>
- <button @click="changeC1">修改第一台车</button>
- <button @click="changeC2">修改第二台车</button>
- <button @click="changeCar">修改整个车</button>
- </div>
- </template>
- <script lang="ts" setup name="Person">
- import {reactive,watch} from 'vue'
- // 数据
- let person = reactive({
- name:'张三',
- age:18,
- car:{
- c1:'奔驰',
- c2:'宝马'
- }
- })
- // 方法
- function changeName(){
- person.name += '~'
- }
- function changeAge(){
- person.age += 1
- }
- function changeC1(){
- person.car.c1 = '奥迪'
- }
- function changeC2(){
- person.car.c2 = '大众'
- }
- function changeCar(){
- person.car = {c1:'雅迪',c2:'爱玛'}
- }
- // 监视,情况五:监视上述的多个数据
- watch([()=>person.name,person.car],(newValue,oldValue)=>{
- console.log('person.car变化了',newValue,oldValue)
- },{deep:true})
- </script>
复制代码 2.10. 【watchEffect】
watchEffect 是 Vue 3 中提供的一种便捷的响应式函数,用于立即实行并监听内部响应式数据的变革。当依靠的数据变革时,watchEffect 自动重新运行回调函数。与 watch 不同,watchEffect 不必要手动声明详细的依靠,它会自动网络并追踪函数中用到的所有响应式数据。
watchEffect 与 watch 的区别
- watchEffect 不必要手动指定依靠,得当处置惩罚简单的响应式场景。
- watch 得当必要精确控制监听哪些依靠,或在回调中利用旧值和新值的场景。
特点
- 自动网络依靠:watchEffect 不必要指定监听的详细数据,它会自动追踪回调中利用到的响应式数据。
- 立即实行:watchEffect 在注册时会立即实行一次,然后在依靠更新时重新运行。
- 适用于简单场景:watchEffect 得当用来追踪多个响应式数据的变革,但不适用于必要访问旧值或多项复杂数据对比的场景(这些环境可以利用 watch)。
- const stop = watchEffect(() => {
- console.log("count的值为:", count.value);
- });
- // 需要时停止
- stop();
复制代码 举一个案例
- <template>
- <div class="person">
- <h2>需求:当水温达到60度,或水位达到80cm时,给服务器发请求</h2>
- <h2>当前水温:{{temp}}℃</h2>
- <h2>当前水位:{{height}}cm</h2>
- <button @click="changeTemp">水温+10</button>
- <button @click="changeHeight">水位+10</button>
- </div>
- </template>
- <script lang="ts" setup name="Person">
- import {ref,watch,watchEffect} from 'vue'
- // 数据
- let temp = ref(10)
- let height = ref(0)
- // 方法
- function changeTemp(){
- temp.value += 10
- }
- function changeHeight(){
- height.value += 10
- }
- // 监视 -- watch实现
- /* watch([temp,height],(value)=>{
- // 从value中获取最新的水温(newTemp)、最新的水位(newHeight)
- let [newTemp,newHeight] = value
- // 逻辑
- if(newTemp >= 60 || newHeight >= 80){
- console.log('给服务器发请求')
- }
- }) */
- // 监视 -- watchEffect实现
- watchEffect(()=>{
- if(temp.value >= 60 || height.value >= 80){
- console.log('给服务器发请求')
- }
- })
- </script>
- <style scoped>
- .person {
- background-color: skyblue;
- box-shadow: 0 0 10px;
- border-radius: 10px;
- padding: 20px;
- }
- button {
- margin: 0 5px;
- }
- li {
- font-size: 20px;
- }
- </style>
复制代码 2.11. 【标签的 ref 属性】
作用:用于注册模板引用。
- 用在普通DOM标签上,获取的是DOM节点。
- 用在组件标签上,获取的是组件实例对象。
在 Vue 3 中,可以利用 ref 和 onMounted 来注册模板引用。模板引用可以用来直接访问 DOM 节点或组件实例。详细来说:
- 用于普通 DOM 标签:可以获取该 DOM 元素的原生节点。
- 用于组件标签:可以获取该组件的实例,进而访问组件的公开属性和方法。
示例 1:访问普通 DOM 节点
假设我们有一个输入框,必要在组件挂载时获取并聚焦它:
- <template>
- <div>
- <input ref="inputRef" type="text" placeholder="聚焦于此" />
- </div>
- </template>
- <script lang="ts" setup>
- import { ref, onMounted } from "vue";
- // 使用 ref 注册模板引用
- const inputRef = ref<HTMLInputElement | null>(null);
- // 在组件挂载后获取并聚焦输入框
- onMounted(() => {
- if (inputRef.value) {
- inputRef.value.focus();
- }
- });
- </script>
复制代码 在这个例子中,inputRef 引用了 input 元素的 DOM 节点。在 onMounted 钩子中,我们可以访问该节点并调用其 focus 方法。
示例 2:访问子组件实例
假设有一个子组件 ChildComponent,提供了一个方法 showAlert。父组件可以通过模板引用调用这个方法。
子组件 ChildComponent.vue
- <!-- 父组件App.vue -->
- <template>
- <Person ref="ren"/>
- <button @click="test">测试</button>
- </template>
- <script lang="ts" setup name="App">
- import Person from './components/Person.vue'
- import {ref} from 'vue'
- let ren = ref()
- function test(){
- console.log(ren.value.name)
- console.log(ren.value.age)
- }
- </script>
- <!-- 子组件Person.vue中要使用defineExpose暴露内容 -->
- <script lang="ts" setup name="Person">
- import {ref,defineExpose} from 'vue'
- // 数据
- let name = ref('张三')
- let age = ref(18)
- /****************************/
- /****************************/
- // 使用defineExpose将组件中的数据交给外部
- defineExpose({name,age})
- </script>
复制代码 参考文献
【2024最新】vue3的基本利用(超详细)-CSDN博客
|