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

Vue 3 的Composition API +


h1 { color: red; }

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

### 1.2 显示清单应用

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

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

```vue
<template>
    <h1>这是首页</h1>
    <TodoList />
</template>

<script setup>
import TodoList from '../components/TodoList.vue'
</script>

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

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

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

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

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:'学习Vue',done:false}])

function addTodo() {
  todos.value.push({
    title: title.value,
    done: false,
  });
  title.value = "";
}
</script>

2 计算属性

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

向TodoList.vue加入:

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:

js 复制代码
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 };
}

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

而组件入口即

vue 复制代码
<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独立维护,提供给项目所有组件使用:

js 复制代码
// 先从 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事件。

js 复制代码
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值可在模板任意地方使用,也随鼠标移动而改变数值。

js 复制代码
import {useMouse} from '../utils/mouse'

let {x,y} = useMouse()

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

4

Composition API 好处已掌握,而
累加器若无

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

要在
还要在setup函数中,返回所有需要在模板中使用的变量和方法。上面setup函数就返回count和add。
使用 。
**## 5 style样式的特性
style标签上,加上scoped属性时,我们定义的CSS就只会应用到当前组件的元素,避免样式冲突。
项目中的样式也可加如下标签:

css 复制代码
<style scoped>
h1 {
color: red;
}
</style>>

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

css 复制代码
<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样式修改,点击累加器时文本颜色会随机切换为红或蓝:

vue 复制代码
<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>>

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

6 总结

使用Composition API +
先通过累加器的例子介绍了ref函数使用;Composition API的语法中,所有功能都是通过全局引入的方式使用的,并通过
然后,通过把功能拆分成函数和文件的方式,掌握到Composition API组织代码的方式,我们可以任意拆分组件的功能,抽离出独立的工具函数,大大提高了代码的可维护性。
最后学习style标签的特殊属性,通过标记scoped可以让样式只在当前的组件内部生效,还可以通过v-bind函数来使用JavaScript中的变量去渲染样式,如果这个变量是响应式数据,就可以很方便地实现样式的切换。
Composition API 和

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

本文由博客一文多发平台 OpenWrite 发布!**

相关推荐
徐*红18 分钟前
java 线程池
java·开发语言
尚学教辅学习资料18 分钟前
基于SSM的养老院管理系统+LW示例参考
java·开发语言·java毕设·养老院
2401_8576363918 分钟前
计算机课程管理平台:Spring Boot与工程认证的结合
java·spring boot·后端
1 9 J20 分钟前
Java 上机实践4(类与对象)
java·开发语言·算法
Code apprenticeship21 分钟前
Java面试题(2)
java·开发语言
憨子周1 小时前
2M的带宽怎么怎么设置tcp滑动窗口以及连接池
java·网络·网络协议·tcp/ip
霖雨3 小时前
使用Visual Studio Code 快速新建Net项目
java·ide·windows·vscode·编辑器
SRY122404193 小时前
javaSE面试题
java·开发语言·面试
Fiercezm3 小时前
JUC学习
java
无尽的大道3 小时前
Java 泛型详解:参数化类型的强大之处
java·开发语言