【Vue学习笔记4】基于Vue3的Composition API + <script setup>

news/2024/12/5 8:14:55/

继续前面的学习笔记。

1. 写一个累加器组件

在 src 下的 components 目录下新建一个 Counter.vue ,并在这个文件里写出下面的代码:

<template><div><h1 @click="add">{{ count }}</h1></div>
</template><script setup>
import { ref } from 'vue';
let count = ref(0)
function add() {count.value++
}
</script><style scoped>
h1 {color: blueviolet;
}
</style>

这里使用了<script setup> 的语法,引入ref函数包裹数字,这样count变量就变成了响应式数据了。使用add修改数字的时候,要修改.value才可以。<script setup> 标签内的变量和函数,都可以在模板<template>中直接使用。

2. 使用累加器组件

src/pages/Home.vue 组件中,使用累加器组件。方法是在<script setup> 中import Counter.vue组件,这样<script setup>就自动把组件注册到当前组件。在模板中直接使用<Counter />即可。


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

通过这种方式,可以实现对业务逻辑的复用。

3. 重构清单组件

3.1 引入ref和setup

在 src 下的 components 目录下新建一个 Todos.vue ,并在这个文件里写出下面的代码:

<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: "学习", done: false }])
function addTodo() {todos.value.push({ title: title.value, done: false });title.value = ""
}
</script><style>  .done {color: gray;text-decoration: line-through;}
</style>

和累加器组件的写法一样。使用ref包裹响应式数据。在修改响应式数据的时候,要修改.value值。
src/pages/Home.vue 组件中,使用Todos组件。


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

3.2 使用 computed 函数实现计算属性

Vue2的 computed 是组件的一个配置项,而Vue3的 computed 的用法是单独引入,并作为函数使用的。

  1. 使用computed函数统计未完成项目和所有项目。
  2. 使用函数实现全选功能。
  3. 使用computed函数清理已完成的项目。
<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>全选<input type="checkbox" v-model="allDone" /><span>{{ active }} / {{ all }}</span></div></div>
</template><script setup>
import { computed, ref } from 'vue';
let title = ref("");
let todos = ref([{ title: "学习", 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(() => { return todos.value.length });
// 全选
let allDone = computed({get: function(){return active.value === 0;},set: function(value){todos.value.forEach((todo)=>{todo.done = value;});}
});
</script><style scoped>  
.done {color: gray;text-decoration: line-through;}
</style>

在 style 标签上,加上 scoped 这个属性的时候,定义的 CSS 就只会应用到当前组件的元素上,这样就很好地避免了一些样式冲突的问题。

4. 使用重构后的清单组件


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

5. 把功能独立的模块封装成独立的函数

使用 Composition API 的逻辑来拆分代码,把一个功能相关的数据和方法都维护在一起。
在utils里面,我们新建了一个todos.js文件,里面定义一个函数 useTodos:

import { computed, ref } from 'vue';export function useTodos() {let title = ref("");let todos = ref([{ title: "学习", 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(() => { return 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 };
}

这个函数就是把那些和清单相关的所有数据和方法,都放在函数内部定义并且return。注意函数要export。

Todos.vue组件入口,也就是<script setup>中的代码,就可以变得非常简单和清爽了。只需要调用 useTodos,并且获取所需要的变量即可,具体的实现逻辑可以去 useTodos 内部维护,代码可维护性大大增强。

<script setup>
import {useTodos} from '../utils/todos'
let { title, todos, addTodo, clear, active, all, allDone } = useTodos();
</script>

Tips:
export default和export都能导出一个模块里面的常量,函数,文件,模块等,在其它文件或模块中通过import来导入常量,函数,文件或模块。这样就可以使用它们了。
在一个文件或模块中,export和import可以有多个,export default却只能有一个。
通过export方式导出,在导入的时候需要加{}大括号,export default 就不需要{}.

6. CSS 中使用 JavaScript 中的变量

script 里定义了一个响应式的 color 变量,并且在累加的时候,将变量随机修改为红或者蓝。在 style 内部,我们使用 v-bind 函数绑定 color 的值,就可以动态地通过 JavaScript 的变量实现 CSS 的样式修改。

<template><div><h1 @click="add">{{ count }}</h1></div>
</template><script setup>
import { ref } from 'vue';
let count = ref(0)
let color = ref('red')   //定义了一个响应式的 color 变量
function add() {count.value++;color.value = Math.random()>0.5? "blue":"red"  //随机修改为红或者蓝。
}
</script><style scoped>
h1 {color:v-bind(color);  // v-bind 函数绑定 color 的值
}
</style>

http://www.ppmy.cn/news/62482.html

相关文章

代码随想录刷题-栈与队列-删除字符串中的所有相邻重复项

文章目录 删除字符串中的所有相邻重复项习题栈string实现 删除字符串中的所有相邻重复项 本节对应代码随想录中&#xff1a;代码随想录&#xff0c;对应视频链接为&#xff1a;暂无 习题 题目链接&#xff1a;1047. 删除字符串中的所有相邻重复项 - 力扣&#xff08;LeetCod…

第三章数据链路层

1.数据链路层的概述 1.0地位 数据链路层在网络体系结构中所处的地位 链路(Link)就是从一个结点到相邻结点的一段物理线路&#xff0c;而中间没有任何其他的交换结点。数据链路(Data Link)是指把实现通信协议的硬件和软件加到链路上&#xff0c;就构成了数据链路。数据链路层以帧…

Mac安装docker

一、docker是什么&#xff1f; 1、Docker的三个基本概念: Image(镜像)Container(容器)Repository(仓库) Docker的思想来自于集装箱&#xff0c;集装箱解决了什么问题&#xff1f; 在一艘大船上&#xff0c;可以把货物规整的摆放起来。并且各种各样的货物被集装箱标准化了&a…

【网络】-- IP协议

应用层&#xff08;http、https&#xff09;&#xff1a; 数据的使用。传输层&#xff08;UDP、TCP&#xff09;&#xff1a;网络通讯的细节&#xff0c;将数据可靠的从A主机跨网络送到B主机。网络层&#xff08;IP&#xff09;&#xff1a;提供一种能力&#xff0c;将数据从A主…

Linux搭建我的世界MC服务器 - MCSM面板 【外网远程联机教程】

文章目录 1. 安装JAVA2. MCSManager安装3.局域网访问MCSM4.创建我的世界服务器5.局域网联机测试6.安装cpolar内网穿透7. 配置公网访问地址8.远程联机测试9. 配置固定远程联机端口地址9.1 保留一个固定tcp地址9.2 配置固定公网TCP地址9.3 使用固定公网地址远程联机 Linux使用MCS…

Android 面试笔记总结,建议吸收一下灵气~

android消息机制 消息机制指Handler、Looper、MessageQueue、Message之间如何工作的。 handler是用来处理消息和接收消息的中间者&#xff0c;handler的创建会伴随着handler中产生looper和MessageQueue&#xff0c;handler依赖于looper&#xff0c;looper依赖于MessageQueue&a…

基于Java ME无线网络移动端的俄罗斯方块游戏的实现

摘 要 本系统是一个基于Java ME平台的无线网络移动端的俄罗斯方块游戏,利用Java ME Wireless Toolkit(WTK)开发包工具在无线网络移动端上实现经典的俄罗斯方块游戏。论文开始部分对无线网络移动系统开发中常使用几种开发语言和环境作了比较,说明了选择Java ME Wireless Tool…

解密银行客户经理展业利器系列一:商机共享、创收增长

2023年银行业面临存款、贷款、利润三大变局&#xff0c;与此同时&#xff0c;商业银行的数字化转型正延展至前台建设&#xff0c;期望通过科技手段布局应对&#xff0c;数字化重装身处一线的客户经理&#xff0c;带动单位时间创收提升&#xff0c;更有力地支撑银行业务战略发展…