首页 > 其他分享 >Vue3实战06-CompositionAPI+<script setup>好在哪?

Vue3实战06-CompositionAPI+<script setup>好在哪?

时间:2023-09-07 18:07:44浏览次数:54  
标签:06 CompositionAPI value API let Vue3 组件 ref todos

Vue 3 的Composition API + <script setup>这种最新的代码组织方式。

Vue3实战06-CompositionAPI+<script setup>好在哪?_Vue

<script setup>是啥?为啥尤大在微博强推?

本文就使用Composition API 和 <script setup> 重构第2讲的清单应用。

重构过程将明白, Composition API 让我们更好组织代码结构, <script setup>本质是更精简方式写Composition API 。

1 Composition API && <script setup>

02讲开发清单应用时,是直接在浏览器里使用 Options API 的方式写代码;接下来开发,直接用单文件组件.vue 文件。这种文件格式允许把 Vue 组件的HTML、CSS和JavaScript写在单个文件内容。

已搭建好项目骨架,以后在这个骨架之内会有很多页面和组件。逐步适应组件化开发思路,新功能以组件方式组织。

1.1 实现累加器

按上讲规范,先打开项目文件夹src/components目录,新建Todolist.vue :

<!--放置模板-->
 <template>
   <div>
     <h1 @click="add">{{ count }}</h1>
   </div>
 </template>
 
 <!--放置逻辑代码-->
 <!--使用<script setup>的语法-->
 <script setup>
 import {ref} from "vue";
 
 let count = ref(1)
 
 // 实现累加器
 function add() {
   count.value++
 }
 </script>
 
 <!--放置CSS样式-->
 <style>
 h1 {
   color: red;
 }
 </style>

<script setup> 标签内定义的变量和函数,都可以在模板中直接使用。

1.2 显示清单应用

实现累加器后,回到src/pages/Home.vue 组件,使用如下代码显示清单应用。

直接import TodoList.vue组件,然后<script setup>会自动把组件注册到当前组件,这样我们就可以直接在template中使用 来显示清单的功能。

<template>
     <h1>这是首页</h1>
     <TodoList />
 </template>
 
 <script setup>
 import TodoList from '../components/TodoList.vue'
 </script>

这就把清单功能独立出来,可在任意需要的地方复用。

基于组件去搭建应用,可实现对业务逻辑的复用。如有其他页面也需要用到这功能,直接复用。

然后,就可基于新语法实现清单应用。

把之前的代码移植过来后,使用ref包裹的响应式数据。修改title和todos时,注意修改响应式数据的value属性。

<template>
   <div>
     <input type="text" v-model="title" @keydown.enter="addTodo" />
     <ul v-if="todos.length">
       <li v-for="todo in todos">
         <input type="checkbox" v-model="todo.done" />
         <span :class="{ done: todo.done }"> {{ todo.title }}</span>
       </li>
     </ul>
   </div>
 </template>
 
 <script setup>
 import { ref } from "vue";
 let title = ref("");
 let todos = ref([{title:'学习Vue',done:false}])
 
 function addTodo() {
   todos.value.push({
     title: title.value,
     done: false,
   });
   title.value = "";
 }
 </script>

2 计算属性

Composition API语法中,计算属性和生命周期等功能,都可脱离Vue的组件机制单独使用 。

向TodoList.vue加入:

<template>
   <div>
     <input type="text" v-model="title" @keydown.enter="addTodo"/>
     <button v-if="active < all" @click="clear">清理</button>
     <ul v-if="todos.length">
       <li v-for="todo in todos">
         <input type="checkbox" v-model="todo.done"/>
         <span :class="{ done: todo.done }"> {{ todo.title }}</span>
       </li>
     </ul>
     <div v-else>暂无数据</div>
     <div>
       全选<input type="checkbox" v-model="allDone"/>
       <span> {{ active }} / {{ all }} </span>
     </div>
   </div>
 </template>
 
 <script setup>
 import {ref, computed} from "vue";
 
 let title = ref("");
 let todos = ref([{title: '学习Vue', done: false}])
 
 function addTodo() {
 ...
 }
 
 function clear() {
   todos.value = todos.value.filter((v) => !v.done);
 }
 
 let active = computed(() => {
   return todos.value.filter((v) => !v.done).length;
 });
 let all = computed(() => todos.value.length);
 let allDone = computed({
   get: function () {
     return active.value === 0;
   },
   set: function (value) {
     todos.value.forEach((todo) => {
       todo.done = value;
     });
   },
 });
 </script>

具体的计算属性的逻辑和02讲一样,区别仅在computed用法。

02讲的computed是组件的一个配置项,而这的computed的用法是单独引入使用。

3 Composition API 拆分代码

之前的累加器和清单,虽功能简单,但也属于两个功能模块。如在一个页面有俩功能,就需在data和methods里分别配置。但如此,数据和方法相关的代码会写在一起,在组件代码行数多了后难维护。

所以,要使用Composition API 逻辑拆分代码,把一个功能相关的数据和方法维护在一起。

但所有功能代码都写在一起,也有问题:随功能复杂,script内部代码越来越多。因此,可进步对代码拆分,把功能独立的模块封装成一个独立函数,做到按需拆分。

新建函数 useTodos:

function useTodos() {
   let title = ref("");
   let todos = ref([{ title: "学习Vue", done: false }]);
   function addTodo() {
     todos.value.push({
       title: title.value,
       done: false,
     });
     title.value = "";
   }
   function clear() {
     todos.value = todos.value.filter((v) => !v.done);
   }
   let active = computed(() => {
     return todos.value.filter((v) => !v.done).length;
   });
   let all = computed(() => todos.value.length);
   let allDone = computed({
     get: function () {
       return active.value === 0;
     },
     set: function (value) {
       todos.value.forEach((todo) => {
         todo.done = value;
       });
     },
   });
   return { title, todos, addTodo, clear, active, all, allDone };
 }

就是把和清单相关的所有数据和方法,都放在函数内部定义并返回,这个函数就可放在任意地方维护。

而组件入口即<script setup>中的代码,就变得非常简洁。在下面的代码中,只需调用useTodos并获取所需变量即可,具体实现逻辑useTodos内部维护,代码可维护性增强太多。

<script setup>
 import { ref, computed } from "vue";
 
 let count = ref(1)
 function add(){
     count.value++
 }
 
 let { title, todos, addTodo, clear, active, all, allDone } = useTodos();
 </script>

使用Composition API 拆分功能时,即执行useTodos时,ref、computed等功能都是从 Vue 单独引入,而不依赖this上下文。可将组件内部的任何一段代码,从组件文件里抽离出一个独立的文件维护。

引入追踪鼠标位置

可能有很多地方需要显示鼠标坐标,就可在src/utils新建mouse.js。

,然后暴露一个函数,函数内部和useTodos类似,不过这次独立成文件,放在utils独立维护,提供给项目所有组件使用:

// 先从 Vue 引入ref函数
 import {ref} from 'vue'
 
 // 定义 useMouse 自定义钩子函数
 export function useMouse(){
 
     // 使用 ref 函数创建对 x、y 值的响应式引用,以便能够追踪它们的变化
     const x = ref(0)
     const y = ref(0)
 
     // 它返回一个包含属性 x 和 y 的对象,表示当前鼠标坐标
     return {x, y}
 
 }

想获取鼠标位置,需监听mousemove事件。这要在组件加载完毕后执行,在Composition API中,可直接引入:

  • onMounted
  • onUnmounted

实现生命周期。

组件加载时触发onMounted,执行监听mousemove事件,更新鼠标位置的x和y的值

组件卸载时触发onUnmounted,解除mousemove事件。

import {ref, onMounted,onUnmounted} from 'vue'
 
 export function useMouse(){
     const x = ref(0)
     const y = ref(0)
     function update(e) {
       x.value = e.pageX
       y.value = e.pageY
     }
     onMounted(() => {
       window.addEventListener('mousemove', update)
     })
 
     onUnmounted(() => {
       window.removeEventListener('mousemove', update)
     })
     return { x, y }
 }
 

完成鼠标事件封装后,在组件的入口就可以和普通函数一样使用useMouse函数。

上面代码返回的xy值可在模板任意地方使用,也随鼠标移动而改变数值。

import {useMouse} from '../utils/mouse'
 
 let {x,y} = useMouse()
 

因为ref和computed等功能都可从 Vue 中全局引入,所以就可把组件进行任意颗粒度拆分组合,大大提高代码可维护性和复用性。

4 <script setup> 好用功能

Composition API 好处已掌握,而<script setup>是为提高使用Composition API 效率。

累加器若无<script setup>,需如下代码实现:

<script >
 import { ref } from "vue";
 export default {
   setup() {
     let count = ref(1)
     function add() {
       count.value++
     }
     return {
       count,
       add
     }
   }
 }
 </script>
 

要在<script>中导出一个对象。在setup配置函数中写代码时,和Options的写法比,也多两层嵌套。

还要在setup函数中,返回所有需要在模板中使用的变量和方法。上面setup函数就返回count和add。

使用 <script setup> 可让代码更精简,这也是Vue3项目必备写法

5 style样式的特性

style标签上,加上scoped属性时,我们定义的CSS就只会应用到当前组件的元素,避免样式冲突。

项目中的样式也可加如下标签:

<style scoped>
 h1 {
   color: red;
 }
 </style>>

组件就会解析如下:标签和样式的属性上,新增data-的前缀,确保只在当前组件生效。

<h1 data-v-3de47834="">1</h1>
 <style scoped>
 h1[data-v-3de47834] {
     color: red;
 }
 </style>

如在scoped内部,你还想写全局样式,可用:global标记,这确保你可很灵活组合你的样式代码。甚至可通过v-bind,直接在CSS中使用js中的变量。

v-bind在CSS使用js变量

script里定义了一个响应式的color变量,累加时,将变量随机修改为红或蓝。

style内部使用v-bind函数绑定color值,就可动态通过js变量实现CSS样式修改,点击累加器时文本颜色会随机切换为红或蓝:

<template>
   <div>
     <h1 @click="add">{{ count }}</h1>
   </div>
 </template>
 
 <script setup>
 import { ref } from "vue";
 let count = ref(1)
 let color = ref('red')
 function add() {
   count.value++
   color.value = Math.random()>0.5? "blue":"red"
 }
 </script>
 
 <style scoped>
 h1 {
   color:v-bind(color);
 }
 </style>>
 

点击累加器时文本颜色的切换效果:

Vue3实战06-CompositionAPI+<script setup>好在哪?_数据_02

6 总结

使用Composition API +<script setup>复现清单应用,

先通过累加器的例子介绍了ref函数使用;Composition API的语法中,所有功能都是通过全局引入的方式使用的,并通过<script setup>的功能,我们定义的变量、函数和引入的组件,都不需要额外的生命周期,就可直接在模板中使用

然后,通过把功能拆分成函数和文件的方式,掌握到Composition API组织代码的方式,我们可以任意拆分组件的功能,抽离出独立的工具函数,大大提高了代码的可维护性。

最后学习style标签的特殊属性,通过标记scoped可以让样式只在当前的组件内部生效,还可以通过v-bind函数来使用JavaScript中的变量去渲染样式,如果这个变量是响应式数据,就可以很方便地实现样式的切换。

Composition API 和 <script setup> 带来新语法:

  • ref返回的数据就需要修改 value属性
  • 响应式和生命周期也需要import后才能使用

标签:06,CompositionAPI,value,API,let,Vue3,组件,ref,todos
From: https://blog.51cto.com/JavaEdge/7399341

相关文章

  • vite + vue3 自动导入点击路由刷新问题记录
     exportdefaultdefineConfig(()=>{//这里只加入了element的有其他的也加在这里constoptimizeDepsElementPlusIncludes=['element-plus/es'];//预加载element样式有其他组件也是如此设置即可fs.readdirSync('node_modules/element-plus/es/components').......
  • Vue3实战06-CompositionAPI+<script setup>好在哪?
    Vue3的CompositionAPI+<scriptsetup>标签内定义的变量和函数,都可以在模板中直接使用。###1.2显示清单应用实现累加器后,回到src/pages/Home.vue组件,使用如下代码显示清单应用。直接importTodoList.vue组件,然后<scriptsetup>会自动把组件注册到当前组件,这样......
  • 米联客ZYNQ MLK-F6-CZ06-7020 开发平台硬件手册
    1整体概述米联客ZYNQ系列开发平台和核心模块经过多次迭代升级,在工业自动化、水利电力控制设备、医疗图像设备等领域广泛应用,产品性能接受了广大客户的检验,稳定可靠。2021年因芯片普遍紧缺涨价,核心模块再次升级以确保供货稳定和降低用户的使用成本。2硬件参数概述 MLK-F......
  • python基础 06while循环和for循环
    while循环当你需要重复干一件事情的时候,叫做循环age=17whileTrue:inp_age=int(input('age:'))ifinp_age>age:print('猜大了')elifinp_age<age:print('猜小了')else:print('猜对了')......
  • 用友畅捷通T+ Upload.aspx任意文件上传漏洞CNVD-2022-60632
    漏洞描述用友畅捷通T+Upload.aspx接口存在任意文件上传漏洞,攻击者通过preload参数绕过身份验证进行文件上传,控制服务器漏洞影响用友畅捷通T+漏洞复现fofa语法:app="畅捷通-TPlus"登录页面如下:上传文件类型验证不完善,可上传任意文件到服务器中的任意位置,验证POCPOST/......
  • 【2023-09-06】稳定内心
    20:00一个人如果有勇气承认错误,那么,他所犯的错误总是可以原谅的。                                                 ——李小龙何太跟我反馈说,她们单位又开始翻起数......
  • 可以无脑将Vue2项目升级到Vue3吗?
    Vue3如此优秀,是不是应该赶紧把项目都升级到Vue3?但不是所有项目都适合升级。1应该从2升到3吗?如开启一个新项目,直接使用Vue3最佳选择。以前独立使用Vue2开发应用,不管咋组织代码,无法避免在data、template、methods中上下反复横跳,这种弊端在项目规模上来后更明显。由于vue-cli基......
  • 2023-09-06
    1.一天都在做售后工作,帮客户远程调试设备,修改文件系统配置。2.C#爬虫项目,按网址要求爬取产品价格、型号、内存等参数信息,分类导入表格。3.STM32继续调试。4.无人机项目继续。5.Genshin带一个男同事小萌新。 ......
  • vue3集成jsoneditor
    一、背景之前在做录制回放平台的时候,需要前端展示子调用信息,子调用是一个请求列表数组结构,jsoneditor对数组的默认展示结构是[0].[1].[2]..的方式,为了达到如下的效果,必须用到onNodeName的钩子函数,因此深入调研了下vue3如何集成jsoneditor最后做出来的效果图onNodeName的参考......
  • 华为S7706交换机设置 DHCP
    1.登陆S7706核心交换机后1.建立新的VLANvlan156vlan1572.为VLAN156VLAN157分别设置DHCP的POOL(也就是需要分配的地址)ippoolvlan156gateway-list10.10.156.1network10.10.156.0mask255.255.255.0excluded-ip-address10.10.156.210.10.156.50excluded-ip-ad......