前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >1小时构建Vu3知识体系-之工程化构建&响应式数据

1小时构建Vu3知识体系-之工程化构建&响应式数据

作者头像
方才编程_公众号同名
发布2024-11-13 10:19:23
发布2024-11-13 10:19:23
9300
代码可运行
举报
文章被收录于专栏:方才编程方才编程
运行总次数:0
代码可运行

本文转载自:https://fangcaicoding.cn/course/12/61 完整的vue3知识图谱请阅读:如何1小时掌握Vue3

要开启你的 Vue 之旅,最重要的是少走弯路,用最快的方式掌握从Node.js环境安装、基于Vite创建项目,再到单文件组件的定义和推荐项目结构。和方才兄一起来搞定这些基础吧,让你的 Vue 开发之路不再迷茫!

Node.js 环境安装

进军 Vue 的第一步就是安装Node.js,不要小看它,这可是所有前端大牛必备的“武器”。可以直接去 Node.js 官网(地址:https://nodejs.org/en/download/prebuilt-installer)下载对应的LTS版本,这个就是稳定版——不稳定的我们不考虑。【ps:具体的安装教程,也可以直接参考Vue+Springboot 前后端分离项目如何部署? 中的node环境安装部分】

安装后,打开命令行输入:

代码语言:javascript
代码运行次数:0
复制
node -v
npm -v

能看到版本号就是安装成功,说明你已经正式迈出了 Vue 世界的第一步!

基于 Vite 创建一个Vue项目

有了Node.js,我们立刻就可以创建第一个 Vue 项目了!选择Vite来启动,为什么?因为它比传统方法更快,能让你体验飞速启动的快乐。【ps:官方也有关于基于CDN方式的运行,但实际项目中都是工程化开发,基本不会用CDN方法,大家知晓即可】

进入到你期望运行项目的目录下,打开命令行,输入:

代码语言:javascript
代码运行次数:0
复制
npm create vite@latest

然后按照提示输入项目名称、选择框架(选vue)和语言(选JavaScript)。几秒钟后,Vite就会创建好项目。这时候进入项目文件夹并启动:

代码语言:javascript
代码运行次数:0
复制
cd your-project-name
# 安装依赖包
npm install
# 运行开发环境
npm run dev

项目自动在浏览器打开,是不是一键到位、毫无压力?这样,你就从零到有了一个 Vue 项目!

单文件组件的语法定义

接下来,我们在idea中去打开项目,开始正式的vue学习啦。【ps:方才兄这里使用开发工具是的IntelliJ IDEA 2023.3,前端同学一般用vsCode偏多,但本质就是一个工具而已,没有优劣之分,还是看大家的使用习惯。】关于idea中如何配置node.js环境,在上次分享中已经讲解过了,这里就不重复了。

我们以App.vue文件为例,来学习下单文件组件的结构是怎样的。

image-20241109231954546

简单解释下3个核心的标签:

  • <template>:负责 HTML 结构的部分,所有展示的内容都在这里定义。
  • <script>:逻辑的“后台”,数据、方法和生命周期钩子全在这里,JavaScript的代码就编写在这个标签下。
  • <style scoped>:用CSS定义组件样式,加上scoped后样式只会在这个组件内生效,不会影响别的地方。

整个组件从结构到逻辑一览无余,对代码洁癖的开发者来说,简直不要太完美。

推荐的项目结构

在 Vue 项目里,结构清晰可以让你未来的开发之路更加顺畅。

vue项目的默认的结构比较简单,但并不能满足工程化开发,以下是方才兄推荐的项目结构:

代码语言:javascript
代码运行次数:0
复制
my-vue-project/
├── public/                # 放静态资源
├── src/
│   ├── api/               # API定义和公共方法相关
│   ├── https://fangcaicoding.cn/oss/assets/            # 图片、样式等资源
│   ├── components/        # 公共组件
│   ├── views/             # 页面视图
│   ├── router/            # 路由管理
│   ├── store/             # 状态管理
│   ├── utils/             # 一些工具类
│   └── App.vue            # 根组件
├── .gitignore             # Git 忽略文件配置
├── index.html             # 项目入口 HTML 文件
├── package.json           # 项目信息及依赖管理,运行和打包脚本
├── package-lock.json      # 是npm生成的自动锁定文件,确保每次安装的依赖版本一致,不需要管。
└── vite.config.js         # Vite 配置文件,配置路径别名、代理服务器、环境变量

这样布局既清晰,又适合扩展。找文件时也不会头大,因为所有的功能模块都分门别类。对追求效率的开发者来说,这种结构能大大提高工作效率。

ps:大家可以先参考这个项目结构对vue自动构建的目录进行调整,后续所有的demo,方才兄都会基于按项目结构进行编码演示。

Vue的响应式,让数据动起来

Holle!大家好,我是方才兄,接着刚刚新建的vue项目,我们一起开始学习vue3的响应式。整体内容如下:

重置下demo项目

为了方便后续的知识点学习,我们把一些不需要的内容先全部删除掉,包括style.cssHellowWord.vue等等文件。只保留必要的内容:

同时将App.vue的内容重置为一个空的单文件组件:

代码语言:javascript
代码运行次数:0
复制
<!--负责 HTML 结构的部分,所有展示的内容都在这里定义。-->
<template>

</template>

<!--逻辑的“后台”,数据、方法和生命周期钩子全在这里,`JavaScript`的代码就编写在这个标签下。-->
<script setup>

</script>


<!--用``CSS``定义组件样式,加上``scoped``后样式只会在这个组件内生效,不会影响别的地方。-->
<style scoped>

</style>

index.html的内容也可以修正下:

代码语言:javascript
代码运行次数:0
复制
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>方才coding</title>
  </head>
  <body>
    <div id="app"></div>
    <script type="module" src="./src/main.js"></script>
  </body>
</html>

重新运行vue3项目:

插值表达式-取值

接下来,我们将直接编写App.vue的内容,来学习响应式数据。

要让数据和页面互动起来,Vue 给我们提供了插值表达式。简单来说,就是在 HTML 中插入{{ }}双大括号,把变量展示出来。

场景示例:比如,想在页面上展示网站名称,我们可以这样写:

代码语言:javascript
代码运行次数:0
复制
  <h1>欢迎来到:{{webName}}</h1>

只要给webName一个值,页面就会实时更新。如果网站名字从“方才”变成“方才coding“,这个变化会立刻反映到页面上。不用手动更新 DOM,Vue 会自动帮我们完成。那如何赋值呢?

基础响应式

接下来,是 Vue 响应式的两位主角——ref()reactive()。它们能让你的数据在变动时自动更新视图,具体选哪个,还得看你的数据结构。

ref():让数据成为响应式

我们可以先通过ref()来动态传值:

代码语言:javascript
代码运行次数:0
复制
<!--负责 HTML 结构的部分,所有展示的内容都在这里定义。-->
<template>
  <h1>欢迎来到:{{ webName }}</h1>
</template>

<!--逻辑的“后台”,数据、方法和生命周期钩子全在这里,`JavaScript`的代码就编写在这个标签下。-->
<script setup>
import {ref} from "vue";

const webName = ref("方才coding")
</script>

<!--用``CSS``定义组件样式,加上``scoped``后样式只会在这个组件内生效,不会影响别的地方。-->
<style scoped>
h1 {
  color: goldenrod;
}

</style>

结合之前学习的JavaScript,我们增加一个按钮,来改变变量webName的值,让数据动起来看看效果:

代码语言:javascript
代码运行次数:0
复制
<!--负责 HTML 结构的部分,所有展示的内容都在这里定义。-->
<template>
  <h1>欢迎来到:{{ webName }}</h1>
  <button @click="randomName">加随机数</button>
</template>

<!--逻辑的“后台”,数据、方法和生命周期钩子全在这里,`JavaScript`的代码就编写在这个标签下。-->
<script setup>
import {ref} from "vue";

const webName = ref("方才coding")

const randomName = () => {
  webName.value = "方才coding +" + Math.random();
}
</script>

<!--用``CSS``定义组件样式,加上``scoped``后样式只会在这个组件内生效,不会影响别的地方。-->
<style scoped>
h1 {
  color: goldenrod;
}
</style>

注意点:

  • ref()提供的变量,在script标签的代码中的函数使用,需要通过xxx.value的形式进行访问;
  • template标签中访问,使用插值表达式,直接使用变量即可,因为 <script setup>中的setup 会自动解包。

reactive():让对象成为响应式

另一种声明响应式状态的方式,即使用 reactive() API。与将内部值包装在特殊对象中的 ref 不同,reactive() 将使对象本身具有响应性:

代码语言:javascript
代码运行次数:0
复制
const webInfo = reactive({
  name: "方才coding2",
  author:"方才"
})

使用reactive包装对象,然后直接修改对象的属性,页面就会自动更新。完整的代码示例:

代码语言:javascript
代码运行次数:0
复制
<!--负责 HTML 结构的部分,所有展示的内容都在这里定义。-->
<template>
  <h1>欢迎来到:{{ webName }}</h1>
  <button @click="randomName">加随机数</button>

  <h2>欢迎来到:{{ webInfo.name }}</h2>
  <h3>作者:{{ webInfo.author }}</h3>
</template>

<!--逻辑的“后台”,数据、方法和生命周期钩子全在这里,`JavaScript`的代码就编写在这个标签下。-->
<script setup>
import {reactive, ref} from "vue";

const webName = ref("方才coding")

const webInfo = reactive({
  name: "方才coding2",
  author:"方才"
})
const randomName = () => {
  webName.value = "方才coding +" + Math.random();
  webInfo.name = "方才coding2 +" + Math.random();
}
</script>

<!--用``CSS``定义组件样式,加上``scoped``后样式只会在这个组件内生效,不会影响别的地方。-->
<style scoped>
h1 {
  color: goldenrod;
}
</style>

两者的区别

通过上面的demo,我们发现ref()reactive()都可以做到响应式更新数据的效果。那两者有什么区别呢?方才兄这里针对使用层面做一些简单的总结,供大家参考(官方更建议使用 ref() 作为声明响应式状态的主要 API):

对比项

ref()

reactive()

支持的数据类型

可以持有任何类型的值,包括原始类型、深层嵌套的对象、数组或者 JavaScript 内置的数据结构

只能用于对象类型 (对象、数组和如 Map、Set 这样的集合类型)。它不能持有如 string、number 或 boolean 这样的原始类型。

值修改

当持有的是对象类型时,可以直接替换整个对象。

不能替换整个对象,当使用let修饰时,替换整个对象,会导致与第一个引用的响应性连接的丢失。

简单通过代码演示下区别点:

  • 数据类型:

image-20241111230941237

image-20241111231045482

值修改:

代码语言:javascript
代码运行次数:0
复制
const webInfoRef = ref({
  name: "方才coding-ref",
  author:"方才"
})
// 只能使用 let 修饰符,因为在下面的方法中会导致引用值的改变
let webInfo = reactive({
  name: "方才coding-reactive",
  author:"方才"
})

const randomName = () => {
  webInfoRef.value = {name:"randomName 替换了"  + Math.random()}
  webInfo = {name:"randomName 替换了" + Math.random()};
  webInfo.author = "randomName" + Math.random()
}

计算属性:节省计算资源的小帮手

当一个数据依赖于另一个数据时,你可以考虑用computed()。它能把计算逻辑集中在一起,提高代码的可读性,并且只有当依赖的数据发生变化时才重新计算。

场景示例const userCtTotal = computed(() => webInfo.userCt + webInfoRef.value.userCt)当依赖的数据发生变化时就会重新计算。

代码语言:javascript
代码运行次数:0
复制
<!--负责 HTML 结构的部分,所有展示的内容都在这里定义。-->
<template>
  <h1>ref()</h1>
  <h2>欢迎来到:{{ webInfoRef.name }}</h2>
  <h3>作者:{{ webInfoRef.author }}</h3>
  <h3>userCt:{{ webInfoRef.userCt }}</h3>

  <button @click="randomRef">testRef</button>

  <h1>reactive</h1>
  <h2>欢迎来到:{{ webInfo.name }}</h2>
  <h3>作者:{{ webInfo.author }}</h3>
  <button @click="testReactive">testReactive</button>

  <p>用户总数{{ userCtTotal }}</p>
</template>

<!--逻辑的“后台”,数据、方法和生命周期钩子全在这里,`JavaScript`的代码就编写在这个标签下。-->
<script setup>
import {computed, reactive, ref} from "vue";

const webInfoRef = ref({
  name: "方才coding-ref",
  author: "方才",
  userCt: 12
})
// 只能使用let修饰符,因为在下面的方法中会导致引用值的改变
let webInfo = reactive({
  name: "方才coding-reactive",
  author: "方才",
  userCt: 13
})

const randomRef = () => {
  webInfoRef.value = {name: "randomRef 替换了" + Math.random()}
  webInfoRef.value.userCt = Math.ceil(Math.random() * 10);
}

const testReactive = () => {
  webInfo.name = "testReactive 替换了" + Math.random()
  webInfo.userCt = Math.ceil(Math.random() * 10);
}

const userCtTotal = computed(() => webInfo.userCt + webInfoRef.value.userCt)

</script>

<!--用``CSS``定义组件样式,加上``scoped``后样式只会在这个组件内生效,不会影响别的地方。-->
<style scoped>
h1 {
  color: goldenrod;
}

</style>

侦听器:灵活应对数据变化

虽然 Vue 能自动追踪大部分数据变动,但当你需要在数据变化时执行一些特定逻辑,比如发起请求、写入日志,就可以用watch()来实现。

场景示例:比如想在用户总数发生变更时,做一个弹窗提醒:

代码语言:javascript
代码运行次数:0
复制
watch(
    // 第一个参数可以是不同形式的“数据源”:它可以是一个 ref (包括计算属性)、一个响应式对象、一个 getter 函数、或多个数据源组成的数组;
    userCtTotal,
    // 回调函数,默认提供变化前后的参数
    (newValue,oldValue)=>{
      let msg = `用户总数变化啦!变化前:【${oldValue}】,变化后:【${newValue}】`;
      alert(msg)
    }
)

每当userCtTotal的值变化时,watch都会触发,帮你执行相关的逻辑。

倾听器有3个参数:

代码语言:javascript
代码运行次数:0
复制
watch(
    // 第一个参数可以是不同形式的“数据源”:它可以是一个 ref (包括计算属性)、一个响应式对象、一个 getter 函数、或多个数据源组成的数组;
    userCtTotal,
     // 第一个参数是回调函数,默认提供变化前后的参数
    (newValue, oldValue) => {
      let msg = `用户总数变化啦!变化前:【${oldValue}】,变化后:【${newValue}】`;
      alert(msg)
    },
    // 第三个参数是可选配置:三个可选配置
    {immediate: true, deep: true, once: true}
)

可选配置说明:

  • immediatewatch 默认是懒执行的:仅当数据源变化时,才会执行回调。希望在创建侦听器时,立即执行一遍回调,可以通过传入 immediate: true 选项来强制侦听器的回调立即执行,默认为false;
  • deep 参数:(默认值)表示仅监视对象的顶层属性的变化,deep: true 则表示递归监视对象所有嵌套属性的变化;
  • once:每当被侦听源发生变化时,侦听器的回调就会执行。如果希望回调只在源变化时触发一次,请使用 once: true 选项,默认为false。

仅了解:只读和浅响应式

虽然上面几种已经能满足很多场景需求,但 Vue 还为我们提供了更深入的优化手段。

readonlyshallowReadonly:只读保护数据

当你希望一个数据不被更改时,可以使用readonly()或者shallowReadonly()。前者是完全只读,后者只针对对象的外层属性。这样可以避免一些误操作导致数据污染。

代码语言:javascript
代码运行次数:0
复制
import { readonly, shallowReadonly } from 'vue';

const readOnlyUser = readonly({ name: '方才兄' });
const shallowReadOnlyUser = shallowReadonly({ name: '方才兄' });

用这两个方法创建的数据,开发中就不用担心它会被误改,非常适合做常量配置等数据。

shallowRefshallowReactive:浅层响应提升性能

Vue 默认是深层响应式,但有时只需要外层响应,这时候shallowRefshallowReactive就是理想选择。它们只追踪对象的第一层属性,内部属性不会响应式更新,可以优化性能。

场景示例:比如管理一大批用户信息,但并不关心用户的每一项详细信息。

代码语言:javascript
代码运行次数:0
复制
import { shallowReactive } from 'vue';

const users = shallowReactive([{ name: '方才兄', age: 28 }, { name: '小明', age: 24 }]);

users.push({ name: '小红', age: 21 }); // 新增的用户会触发响应,但不会追踪每个用户的详细变化

使用浅层响应性,节省了大量性能开销,适合大量数据和不频繁更新的场景。

结语

掌握了 Vue 的响应式,你在数据和视图之间就如鱼得水,开发起来畅通无阻。记得多动手实践,用ref()reactive()实现基本功能,再通过computedwatch优化逻辑。更高级的功能如readonly和浅响应式,可以根据场景选择。关注方才兄,带你 Vue 路上从入门到进阶,代码效率飞起!---

近期更新计划

近期更新计划(有需要的小伙伴,记得点赞关注哟!)

  1. 输出vue、router、elementplus等前端框架技术文章,期望能帮助大家快速建立相关的知识体系;
  2. 基于vue3+springboot3的前后端分离的博客系统已经开源啦,欢迎大家star!https://gitee.com/fangcaicoding/fangcai-coding-blog

“学编程,一定要系统化”——若你也是系统学习的践行者,记得点赞关注,期待与你一起 From Zero To Hero!

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-11-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 方才编程 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Node.js 环境安装
  • 基于 Vite 创建一个Vue项目
  • 单文件组件的语法定义
  • 推荐的项目结构
  • Vue的响应式,让数据动起来
    • 重置下demo项目
    • 插值表达式-取值
    • 基础响应式
      • ref():让数据成为响应式
      • reactive():让对象成为响应式
      • 两者的区别
    • 计算属性:节省计算资源的小帮手
    • 侦听器:灵活应对数据变化
    • 仅了解:只读和浅响应式
      • readonly与shallowReadonly:只读保护数据
      • shallowRef与shallowReactive:浅层响应提升性能
    • 结语
    • 近期更新计划
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档