版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
教学目标1.学会使用ref和reactive函数来创建响应式对象。2.学会使用toRefs将响应式对象转换为普通对象。3.学会使用computed、watch和watchEffect定义和监听响应式数据。4.学会使用ref引用DOM元素和组件实例。5.理解Vue3生命周期钩子并学会定义钩子函数1第4章
Vue3新特性应用(2学时)24.1响应式基础4.1.1组件选项setup()
setup()钩子是在组件中使用组合式API的入口,通常只在以下情况下使用:需要在非单文件组件中使用组合式API时。需要在基于选项式API的组件中集成基于组合式API的代码时。其他情况下,都应优先使用<scriptsetup>语法。setup()函数是一个新的组件选项,它是组件内部暴露出所有的属性和方法的统一API,也作为在组件内使用CompositionAPI的入口点。从生命周期钩子的视角来看,setup()函数的执行时间会在beforeCreate()、created()之前被调用,可以返回一个对象,这个对象的属性被合并到渲染上下文(context),并可以在模板中直接使用。//在Vue3.0的组件中定义book.vue
export
default
{
setup(props,
context)
{
//
Attributes
(Non-reactive
object)
console.log(context.attrs)
//
Slots
(Non-reactive
object)
console.log(context.slots)
//
Emit
Events
(Method)
console.log(context.emit)
}
}
props是响应式对象,不能使用ES6(ECMAScript6.0)解构,因为它会删除props的响应性。context对象是普通的JavaScript对象,即它不是响应式对象,这意味着可以在其上安全地使用ES6解构context。4.1.1组件选项setup()在Vue3.x中,可以使用context替代了this。例如使用context.attrs、//Vue3.0中组件定义方法import{ref}from"vue"export
default
{
setup(props,
{
attrs,
slots,
emit
})
{constcount=ref(0)constadd=()=>{count.value++}//使用箭头函数定义return{count,add}//返回所有属性和方法
}
}
注意:props要先声明才能取值,context.attrs不用先声明。在props声明过的属性,context.attrs里不会再出现。在props中不可以声明方法,即props不包含事件,但context.attrs可以包含事件。
在Vue3.2.x中,在非组件中使用setup()函数时,可以使用下列两种方法使用响应式API。代码如下:const{ref,reactive}=Vue//1-解构,Vue首字母必须大写constcount=Vue.ref(0)//2-使用全局函数//在Vue3.2中组件定义,不使用exportdefault{}暴露属性和方法,也不使用return<script
setup>
import
{
ref
}
from
"vue";
//导入APIconst
count
=
ref(0);
function
add1()
{
//方法使用function来定义
count.value++;
}
</script>
4.1.1组件选项setup()//Vue3.2中,在非组件中定义(HTML)<script>constApp={setup(){constcount=Vue.ref(0);//也可以先const{ref}=Vue解构,再使用reffunctionadd1(){count.value++;}return{//需要返回所有属性及方法count,add1}}}</script>案例演示:【例4-1】条件渲染综合应用<divid="app">
<h1>{{message}}</h1>
<p>countis:{{counter.count}}</p>
<button@click="add">递增</button>
</div><script>
const{reactive}=Vue;
//解构赋值
constApp={
setup(props,context){
constcounter=reactive({count:0});
constmessage=Vue.ref("HelloVue.js");//Vue.ref()
functionadd(){
counter.count++;
console.log(counter.count);
console.log(props);
console.log(context)
console.log('message',message.value)//控制台输出message的值
}
return{
add,counter,
message,
};
},
};
constapp=Vue.createApp(App).mount("#app");
</script>5
4.1.2ref()、reactive()、toRefs()和toRef()2.reactive()reactive()函数根据给定的普通对象来创建一个响应式数据对象,使用前需要显式导入reactive。定义语法如下:组件中使用import{reactive}from"vue"constperson=reactive({name:'储久良',age:55,sex:'男'})//创建对象const
numArr=reactive([10,20,30,45,89,62])//创建数组return{person,numArr}//返回并暴露,在<scriptsetup>中无需return在非组件中使用const{reactive}=Vue//ES6解构//若不通过解构,也可以直接使用Vue.reactive()来定义constperson=Vue.reactive({name:'储久良',age:55,sex:'男'})//创建对象const
numArr=reactive([10,20,30,45,89,62])//创建数组return{person,numArr}//返回并暴露reactive()一般用于定义对象或数组类型,经过Proxy的加工后返回一个响应式的数据对象(Proxy对象),如图4-2所示。需要注意的是加工后的对象跟原对象是不相等的,并且加工后的对象属于深度克隆的对象。在setup()中使用、person.age、person.sex等形式来获取对象中的具体数据。6
4.1.2ref()、reactive()、toRefs()和toRef()3.工具函数toRefs()和toRef()toRefs()可以将reactive()创建出来的响应式对象,转换为普通的对象,只不过,这个对象上的每个属性节点,都是ref()类型的响应式数据,配合v-model指令能完成数据的双向绑定,在开发中非常有效。toRef()基于响应式对象上的一个属性,创建一个对应的ref。这样创建的ref与其源属性保持同步,当改变源属性的值将更新ref的值,反之亦然。组件中使用import{toRefs,toRef,reactive}from"vue"//在组件中显式导入constperson=reactive({no:'2009231101',name:'储久良',age:55,sex:'男'})//创建对象conststudent=reactive({name:'李小明',className:'20计算机1班'})//创建对象constno=toRef(person,'no')//创建单一ref属性return{person,no,…toRefs(student),student}//返回并暴露,在<scriptsetup>中无需return
在非组件中使用const{toRef,toRefs,reactive}=Vue//非组件中使用ES6解构constperson=reactive({no:'2009231101',name:'储久良',age:55,sex:'男'})//创建对象conststudent=reactive({name:'李小明',className:'20计算机1班'})//创建对象constno=toRef(person,’no’)//创建单一ref属性return{person,no,…toRefs(student),student}//返回并暴露7
4.1.2ref()、reactive()、toRefs()和toRef()案例演示:【例4-2】条件渲染综合应用<divid="app">
<fieldset>
<legend>更新toRef()的创建的ref</legend>
<p>ref-amount:{{amount}}</p>
<p>学生信息:{{student}}</p>
<p>toRef()-班级属性:{{className}}</p>
<button@click="change1">更新ref值</button>
<button@click="add1">增1</button>
</fieldset>
<fieldset>
<legend>更新源响应式对象的属性</legend>
<p>numArris:{{numArr}}</p>
<p>教师信息:{{person}}</p>
<p>toRefs()所有属性:{{name}}-{{age}}-{{sex}}</p>
<button@click="change2">改变源响应式对象的属性</button>
</fieldset>
</div><script>
const{reactive,ref,toRef,toRefs}=Vue;//ES6解构
constApp={
setup(){
constamount=ref(0);//状态
constperson=reactive({name:"储久良",age:55,sex:"男"
});
conststudent=reactive({name:"李小明",className:"20软件1班"
});
constnumArr=reactive([10,20,30,45,89,62]);
constclassName=toRef(student,"className");//复制单个属性
functionchange1(){//更新ref属性,源响应式对象同步更新
className.value="20计算机1班";
console.log(className.value);
onsole.log(person);
console.log(numArr);
//输出代理对象
}
functionchange2(){//更新源对象的属性
="李永远";console.log();
}
functionadd1(){amount.value++;//更新状态}
return{
amount,className,person,numArr,student,
...toRefs(person),
add1,change1,
change2,};
},};
constapp=Vue.createApp(App).mount("#app");
</script>84.1.3watch、watchEffect和computed
Vue3.x中watch、watchEffect和computed等组合式API,在使用之前,必须显式导入。格式如下:import{watch,computed,watchEffect}from"vue";//在组件使用const{watch,computed,watchEffect}=Vue;//非组件中使用或类似Vue.watch()使用1.computed()
接受一个getter函数,返回一个只读的响应式ref对象。该ref通过.value暴露getter函数的返回值。它也可以接受一个带有get和set函数的对象来创建一个可写的ref对象。const
count
=
ref(1)
const
plusOne
=
computed(()
=>
count.value
+
1)
//定义一个计算属性console.log(plusOne.value)
//使用.value,输出2
plusOne.value++
//
error
或者,它可以使用具有get和set功能的对象来创建可写的ref对象。const
count
=
ref(1)
const
plusOne
=
computed({
get:
()
=>
count.value
+
1,
set:
(val)
=>
{
count.value
=
val
-
1
}
})
plusOne.value
=
1
//可以修改console.log(count.value)
//
0
92.watch()
侦听一个或多个响应式数据源,并在数据源变化时调用所给的回调函数。watch()默认是懒侦听的,即仅在侦听源发生变化时才执行回调函数。
第一个参数是侦听器的源。这个来源可以是以下几种:一个函数,返回一个值。一个ref。一个响应式对象。...或是由以上类型的值组成的数组。
第二个参数是在发生变化时要调用的回调函数。这个回调函数接受三个参数:新值、旧值,以及一个用于注册副作用清理的回调函数。该回调函数会在副作用下一次重新执行前调用,可以用来清除无效的副作用,例如等待中的异步请求。当侦听多个来源时,回调函数接受两个数组,分别对应来源数组中的新值和旧值。第三个可选的参数是一个对象,支持以下这些选项:immediate:在侦听器创建时立即触发回调。第一次调用时旧值是undefined。deep:如果源是对象,强制深度遍历,以便在深层级变更时触发回调。flush:调整回调函数的刷新时机。onTrack/onTrigger:调试侦听器的依赖。
与watchEffect()相比,watch()可以:懒惰地执行副作用。更具体地说明什么状态应触发监听程序重新运行。访问监视状态的先前值和当前值。4.1.3watch、watchEffect和computed104.1.3watch、watchEffect和computed
该watchAPI可以监听单一数据源,也可以监听多个数据源。语法如下:1)侦听单一来源。监听数据源可以是返回值的getter函数,也可以是直接ref对象。//
监听
a
getter
const
state
=
reactive({
count:
0
})
watch(
()
=>
state.count,
(count,
prevCount)
=>
{
/*
...
*/
}
)
//
直接监听
a
ref
const
count
=
ref(0)
watch(count,
(count,
prevCount)
=>
{
/*
...
*/
})
2)侦听多个来源。当侦听多个来源时,回调函数接受两个数组,分别对应来源数组中的新值和旧值。watch([fooRef,
barRef],
([foo,
bar],
[prevFoo,
prevBar])
=>
{
/*
...
*/
})
当使用getter函数作为源时,回调只在此函数的返回值变化时才会触发。
如果想让回调在深层级变更时也能触发,就需要使用{deep:true}强制侦听器进入深层级模式。在深层级模式时,如果回调函数由于深层级的变更而被触发,那么新值和旧值将是同一个对象。const
state
=
reactive({
count:
0
})
watch(
()
=>
state,
(newValue,
oldValue)
=>
{
//
newValue
===
oldValue
},
{
deep:
true
}
)
113.watchEffect()
立即运行一个函数,同时响应式地追踪其依赖,并在依赖更改时重新执行。为了应用和自动重新应用基于响应状态的副作用,可以使用watchEffect()方法。使用部分代码如下:const
count
=
ref(0)
watchEffect(()
=>
console.log(count.value))
//
->
输出
0
setTimeout(()
=>
{
count.value++
//
定时执行累增1
},
1000)
当在组件的setup()函数或生命周期钩子期间调用watchEffect()时,监听器将链接到组件的生命周期,并在卸载组件时自动停止。watchEffect()数据变化时立即变化,执行后返回一个句柄ID(stop:停止监听数据变化)。使用stop()可以清除依赖实现停止监听。const
stop
=
watchEffect(()
=>
{…})
//当不在需要时停止stop()
4.1.3watch、watchEffect和computed12
<divid="app">
<fieldset>
<legendalign="center">watch、computed和watchEffect函数实战</legend>
<p>reactObj中的num1={{num1}},reactObj中的计算属性:num2={{num2}}</p>
<button@click="addOne">num1属性值增加1</button>
<button@click="stopWatch">停止监听</button>
</fieldset>
</div><script>
const{reactive,toRefs,watch,computed,watchEffect}=Vue;
constapp=Vue.createApp({
setup(){
constreactObj=reactive({
num1:1,
num2:computed(()=>reactObj.num1*2),//定义一个计算属性
});
//副作用,若响应式属性变更,就会触发这个函数,但他是惰性的
watchEffect(()=>{
console.log(`effect触发了!${reactObj.num1}`);
});
//定义一个监听器,返回停止监听的ID
conststop=watch(reactObj,(val,oldVal)=>{
console.log("watch-旧值:",oldVal.num1+"-新值:"
+val.num1);
});
//响应式对象的属性num1增加1
functionaddOne(){reactObj.num1++;
}
//停止监听
functionstopWatch(){stop();
}
return{...toRefs(reactObj),
addOne,
stopWatch,
};
},
});
app.mount("#app");
</script>【例4-3】Vue3.x中watch()、computed()和watchEffect()函数实战。134.2Vue3生命周期4.2.1Vue3生命周期函数(组合式API)序号Vue3生命周期钩子说明Vue2生命周期选项1setup
初始化数据阶段(创建前)beforeCreate2setup已经创建完成created
3onBeforeMount
组件挂载前beforeMounton4onMounted
实例挂载完毕mounted5onBeforeUpdate响应式数据变化前beforeUpdate6onUpdated
响应式数据变化完成updated7onBeforeUnmount实例销毁前beforeUnmount(beforeDestroy已废弃)8onUnmounted实例已销毁unmounted(destroyed已废弃)9onErrorCaptured错误数据捕捉errorCaptured
144.2.2生命周期钩子函数应用在script标记中显式导入,然后在setup()中
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 《增员十二种方法》课件
- 《汉语拼音g》课件
- 2026年吊装作业安全管理试题(含答案)
- 2026年儿科常见病护理业务考核试题与答案
- 2026年法律法规基础:合同法与知识产权保护考试(含答案)
- 2026年妇女权益保障法知识测试模拟试题及答案
- 2026年山东旅游职业学院综合评价招生素质测试面试模拟题及答案
- 2026年机械测量室模拟试题(含答案)
- 2026年生物实验操作科目测模拟试卷
- 2026年安阳县考试模拟题及答案详解
- 2026年廉政知识专题测试题及答案
- 城乡教育公平之困与破局:现状、成因与路径探索
- 2026-2027学年人美版(新版)初中美术九年级上册(全册)教学设计(附目录p89)
- 2026年机关事业单位工勤人员计算机操作员高级工考试试题及答案
- 大连船舶重工集团笔试题目及答案
- 2026年中小学教师师德师风知识考试试题及答案
- T∕CSIA 022-2025企业体验式安全教育基地建设规范
- GB/T 5124.1-2026硬质合金化学分析方法第1部分:总碳量的测定重量法和气体容量法
- 华为运输包装设计规范(内容系统全面)
- 通辽医院医疗垃圾原位处理建设项目环境影响报告表
- 跨境电商直播内容设计与互动策略
评论
0/150
提交评论