组合API1、什么是组合API2、setup()函数3、响应式API3.1、reactive()方法3.2、watchEffect()方法3.3、ref()方法3.4、computed()方法3.5、watch()方法4、生命周期钩子函数5、使用ref获取DOM元素使用选项编写组件的逻辑代码在大多数情况下都有效。但是当使用Vue构建大型项目时组件代码会比较复杂这可能会导致组件难以阅读和理解尤其对于一开始没有参与编写这些组件的人。能够将与一个逻辑关注点相关的代码配置在一起会更好而这正是组合式API能够做到的。1、什么是组合APIVue 3.0中新增了组合API的功能它是一组附加的、基于函数的API可以更加灵活地组织组件代码。通过组合API可以使用函数而不是声明选项的方式来编写Vue组件。因此使用组合API可以将组件代码编写为多个函数每个函数处理一个特定的功能不再需要按选项组织代码。组合API可以更好地和TypeScript集成同时组合API可以和现有的基于选项的API一起使用。需要注意的是组合API是在选项(data、methods和computed)之前进行解析因此组合API无法访问这些选项中定义的属性。2、setup()函数setup()函数是一个新的组件选项它是组件内部使用组合API的入口。setup()函数在组件实例创建之前、初始化Prop之后调用而且setup()函数是在beforeCreate钩子函数之前调用。setup()函数可以返回一个对象或函数对象的属性会合并到组件模板渲染的上下文中。示例代码如下scriptsrchttps://unpkg.com/vue3/dist/vue.global.js/scriptscripttypetext/javascriptconstvmVue.createApp({setup(){//创建一个响应式对象constdataVue.reactive({number:10});functionadd(){data.number1;}//返回一个对象对象中的属性可以在模板中使用return{data,add}}});vm.mount(#app);/script上述代码中setup()函数返回的是一个对象该对象有两个属性一个是响应式对象另一个是函数。在组件的模板中可以直接使用这两个属性。代码如下dividappbuttonclickadd{{data.number}}/button/divsetup()函数中不能使用this。但是当和现有的基于选项的API一起使用时在选项中可以通过this访问setup()函数返回的属性。setup()函数可以接收两个可选的参数。第一个参数是响应式的props对象通过该参数可以访问props选项中定义的Prop。第二个参数是一个上下文(context)对象该对象是一个JavaScript对象它暴露了attrs、slots和emit三个属性。其中attrs和slots是有状态的对象它们会随着组件的更新而发生变化但是这两个对象本身并不是响应式的因此不能对它们进行解构。由于setup()函数接收的props对象是响应式的因此在组件外部传入新的Prop值时props对象会随着更新。示例代码如下dividappmy-demo:msgmsg/my-demo/divscriptsrchttps://unpkg.com/vue3/dist/vue.global.js/scriptscripttypetext/javascriptconstvmVue.createApp({data(){return{msg:海阔凭鱼跃天高任鸟飞。}}});vm.component(my-demo,{props:[msg],setup(props){Vue.watchEffect((){console.log(props.msg);})},template:p{{msg}}/p})vm.mount(#app);/script在浏览器中打开上述示例的页面后在控制台中输入constappdocument.querySelector(#app).__vue_app__ app._instance.proxy.msghello按Enter键后可以看到页面内容发生了变化。因此调用watchEffect()方法或watch()方法可以监听props对象并对修改做出响应。3、响应式API3.1、reactive()方法reactive()方法用于将定义的JavaScript对象转换为响应式对象。示例代码如下dividappdiv姓名{{data.name}}/divdiv年龄{{data.age}}/divpbuttonclickdata.age25修改年龄/button/p/divscriptsrchttps://unpkg.com/vue3/dist/vue.global.js/scriptscripttypetext/javascriptconstvmVue.createApp({setup(){//创建一个响应式对象constdataVue.reactive({name:Tony,age:20});//返回一个对象对象中的属性可以在模板中使用return{data}}});vm.mount(#app);/script上述代码中使用reactive()方法创建了一个响应式对象data并以对象的形式返回该对象。当data对象发生变化时视图会自动更新。运行结果如图所示。3.2、watchEffect()方法watchEffect()方法用来监听数据的变化类似于Vue 2.x中的watch选项。该方法接收一个函数作为参数它会立即执行一次该函数同时会跟踪函数里面用到的所有响应式状态当状态发生变化时会重新运行该函数。示例代码如下dividapp/divscriptsrchttps://unpkg.com/vue3/dist/vue.global.js/scriptscripttypetext/javascriptconstvmVue.createApp({setup(){//创建一个响应式对象constdataVue.reactive({count:1});Vue.watchEffect((){document.body.innerHTML计数器${data.count}});setInterval((){data.count;},1000);}});vm.mount(#app);/script上述代码中当响应式对象data发生变化时会重新运行watchEffect()方法的参数。运行结果如图所示。3.3、ref()方法reactive()方法可以为一个JavaScript对象创建响应式代理如果需要对某个基本数据类型如数值类型、字符串类型的数据创建响应式代理对象可以通过ref()方法实现。该方法接收一个原始值作为参数返回一个响应式的对象该对象只有一个value属性指向内部值。示例代码如下dividappp{{data}}/p/divscriptsrchttps://unpkg.com/vue3/dist/vue.global.js/scriptscripttypetext/javascriptconstvmVue.createApp({setup(){//创建一个响应式对象constdataVue.ref(100);setInterval((){data.value;},1000);return{data}}});vm.mount(#app);/script如果将ref()方法创建的响应式代理对象作为属性返回那么在模板中访问时不需要添加.value。示例更改商品数量。实现购物车中更改商品数量的操作。单击“”按钮增加商品数量单击“-”按钮减少商品数量代码如下dividapp商品数量buttonclickdata--:disableddata 1 ? true :false-/button{{data}}buttonclickdata/button/divscriptsrchttps://unpkg.com/vue3/dist/vue.global.js/scriptscripttypetext/javascriptconstvmVue.createApp({setup(){//创建一个响应式对象constdataVue.ref(1);return{data}}});vm.mount(#app);/script3.4、computed()方法和computed选项的作用一样computed()方法用于创建计算属性。该方法接收一个getter函数并返回一个不可修改的ref对象。示例代码如下dividappp{{newData}}/p/divscriptsrchttps://unpkg.com/vue3/dist/vue.global.js/scriptscripttypetext/javascriptconstvmVue.createApp({setup(){constdataVue.ref(10);constnewDataVue.computed(()data.value10);return{newData}}});vm.mount(#app);/script示例转换字符串。将字符串“HTMLCSSJavaScript”转换为首字母大写其他字母小写的形式。代码如下dividappp{{newData}}/p/divscriptsrchttps://unpkg.com/vue3/dist/vue.global.js/scriptscripttypetext/javascriptconstvmVue.createApp({setup(){constdataVue.ref(HTML CSS JavaScript);constnewDataVue.computed((){constddata.value;returnd.charAt(0).toUpperCase()d.substr(1).toLowerCase();});return{newData}}});vm.mount(#app);/script3.5、watch()方法watch()方法相当于Vue根实例选项对象中的watch选项。该方法用于监听特定的数据并在回调函数中应用。当被监听的数据发生变化时才会调用回调函数。watch()方法可以接收两个参数。如果使用该方法监听的是一个ref对象那么第一个参数是需要监听的ref对象第二个参数是当监听的数据发生变化时触发的回调函数。示例代码如下dividapp请输入米数inputtypetextsize6v-modeldata/divscriptsrchttps://unpkg.com/vue3/dist/vue.global.js/scriptscripttypetext/javascriptconstvmVue.createApp({setup(){constdataVue.ref(0);Vue.watch(data,(){console.log(data.value米 data.value*100厘米);});return{data}}});vm.mount(#app);/script运行上述代码当文本框中的数字发生变化时浏览器控制台会输出单位“米”和“厘米”之间的换算结果如图所示。如果使用watch()方法监听一个响应式对象中的某个属性那么第一个参数需要使用返回该属性的函数的方式。示例代码如下dividappp商品原价格{{data.price}}/p请输入新价格inputtypetextsize6v-modeldata.newpricep{{data.text}}/p/divscriptsrchttps://unpkg.com/vue3/dist/vue.global.js/scriptscripttypetext/javascriptconstvmVue.createApp({setup(){constdataVue.reactive({price:399,newprice:,text:});Vue.watch(()data.newprice,(newValue){data.text原价格data.price 新价格newValue;});return{data}}});vm.mount(#app);/script4、生命周期钩子函数与基于选项的API相比组合API中的生命周期钩子函数也发生了变化将选项中的生命周期钩子函数改成了onXxx()函数的形式。需要注意的是beforeCreate和created两个钩子函数被删除了取而代之的是setup()函数。选项API和组合API的钩子函数的对应关系如表所示。选项API钩子函数组合API钩子函数beforeCreate没有对应的onXxx()函数取而代之的是setup()函数created有对应的onXxx()函数取而代之的是setup()函数beforeMountonBeforeMountmountedonMountedupdatedonUpdatedbeforeUnmountonBeforeUnmountunmountedonUnmounted5、使用ref获取DOM元素在Vue 3.0中使用ref()方法除了可以对某个原始值创建响应式代理对象还可以获取模板中的指定DOM元素。要获取指定DOM元素首先需要为该元素添加一个ref属性然后在setup()函数中声明一个名称与ref属性值相同的变量并传入一个空值null再通过“变量名.value”的形式就可以获取到该元素。示例代码如下dividappdivrefele/div/divscriptsrchttps://unpkg.com/vue3/dist/vue.global.js/scriptscripttypetext/javascriptconstvmVue.createApp({setup(){//变量名必须和模板中ref属性值相同并传入一个空值nullconsteleVue.ref(null);Vue.onMounted((){//获取指定元素的标签名并显示document.body.innerHTMLele.value.tagName;});return{ele}}});vm.mount(#app);/script上述代码中为div元素添加了ref属性属性值为ele在setup()函数中声明了一个名称同样为ele的变量并传入空值null这样通过ele.value就可以获取到该div元素。运行结果如图所示。示例单机文本改变样式。定义一行文本当单击文本时为文本设置颜色和大小代码如下dividappdivrefdemoclicksetStyle{{text}}/div/divscriptsrchttps://unpkg.com/vue3/dist/vue.global.js/scriptscripttypetext/javascriptconstvmVue.createApp({setup(){consttextVue.ref(一寸光阴一寸金);constdemoVue.ref(null);constsetStyle(){demo.value.stylecolor:blue; font-size:50px;};return{text,demo,setStyle};}});vm.mount(#app);/script