当前位置: 首页 > news >正文

Vue.js 从入门到精通:全面解析组件化、路由与状态管理(附 Todo 案例)

在当今的前端开发领域,Vue.js 以其简洁、高效和灵活的特点受到了广泛的关注和应用。本文将带你从 Vue 的基础知识入手,逐步深入到高级特性,让你对 Vue 有一个全面的了解,并通过实际案例帮助你更好地掌握 Vue 的开发。

一、Vue 简介

Vue.js 是一个渐进式 JavaScript 框架,它专注于视图层,易于上手且非常灵活。Vue 的核心库只关注视图层,因此可以轻松地与其他库或现有项目集成。

二、环境搭建

  1. 安装 Node.js
    Vue.js 需要 Node.js 环境来运行。你可以从Node.js 官方网站下载并安装适合你操作系统的版本。

  2. 安装 Vue CLI
    Vue CLI 是一个官方提供的命令行工具,用于快速搭建 Vue 项目。打开终端并运行以下命令来安装 Vue CLI:

   npm install -g @vue/cli

三、创建第一个 Vue 项目

 1.使用 Vue CLI 创建项目
  在终端中运行以下命令来创建一个新的 Vue 项目:

   vue create my-vue-project

按照提示选择项目的配置选项,如使用 Vue 2 还是 Vue 3、是否安装路由和状态管理等。

2.项目结构
创建完成后,进入项目目录,可以看到以下主要的文件和目录:

  • src/:项目的源代码目录。
  • main.js:入口文件,用于创建 Vue 实例。
  • App.vue:根组件文件。
  • package.json:项目的配置文件。

四、Vue 的基本语法

1.模板语法
Vue 使用模板语法来将数据渲染到 HTML 中。以下是一个简单的例子:

   <template><div><h1>{{ message }}</h1></div></template><script>export default {data() {return {message: 'Hello, Vue!'};}};</script>

在上面的例子中,使用双大括号{{ message }}来显示数据message的值。

2.指令
Vue 提供了一些指令来增强 HTML 的功能。例如,v-ifv-for指令:

   <template><div><ul><li v-for="item in items" :key="item.id">{{ item.name }}</li></ul><p v-if="showMessage">This message is visible.</p></div></template><script>export default {data() {return {items: [{ id: 1, name: 'Item 1' },{ id: 2, name: 'Item 2' },{ id: 3, name: 'Item 3' }],showMessage: true};}};</script>

在上面的例子中,使用v-for指令遍历items数组并渲染每个元素,使用v-if指令根据showMessage的值来决定是否显示<p>元素。

五、组件化开发

1.创建组件
Vue 鼓励使用组件化开发,将页面拆分成多个可复用的组件。以下是一个简单的组件示例:

   <template><div><h2>{{ title }}</h2><p>{{ content }}</p></div></template><script>export default {props: ['title', 'content'],};</script>

在上面的例子中,创建了一个名为MyComponent的组件,它接受titlecontent两个属性。

2.使用组件
在其他组件或页面中,可以使用<component-name>标签来引用组件,并通过属性传递数据:

   <template><div><MyComponent title="Component Title" content="Component content." /></div></template><script>import MyComponent from './MyComponent.vue';export default {components: {MyComponent}};</script>

组件化开发的优势在于提高代码的可维护性和可复用性。通过将页面拆分成多个小的组件,可以更好地组织代码,使得每个组件的功能更加单一,易于理解和修改。同时,组件可以在不同的页面或项目中复用,减少了重复代码的编写。

组件通信

在 Vue 中,组件之间的通信有多种方式:

1.Props 传递数据:父组件向子组件传递数据可以通过 props 属性。子组件通过接收父组件传递过来的 props 来获取数据。

   <!-- 父组件 --><template><div><ChildComponent :message="parentMessage" /></div></template><script>import ChildComponent from './ChildComponent.vue';export default {data() {return {parentMessage: 'Hello from parent'};},components: {ChildComponent}};</script><!-- 子组件 --><template><div><p>{{ message }}</p></div></template><script>export default {props: ['message']};</script>

2.触发事件:子组件向父组件传递数据可以通过触发自定义事件并使用emit` 方法。父组件在使用子组件时监听这个自定义事件来获取子组件传递过来的数据。

   <!-- 父组件 --><template><div><ChildComponent @customEvent="handleCustomEvent" /></div></template><script>import ChildComponent from './ChildComponent.vue';export default {methods: {handleCustomEvent(data) {console.log(data);}},components: {ChildComponent}};</script><!-- 子组件 --><template><div><button @click="emitEvent">Emit Event</button></div></template><script>export default {methods: {emitEvent() {this.$emit('customEvent', 'Data from child');}}};</script>

3.Vuex 状态管理:对于复杂的应用,多个组件之间需要共享数据时,可以使用 Vuex 进行状态管理。Vuex 提供了一个集中式的存储,使得组件可以方便地获取和修改共享状态。

六、路由管理

1.安装 Vue Router
Vue Router 是 Vue.js 的官方路由管理器。在项目中安装 Vue Router:

   npm install vue-router

2.配置路由
创建一个router.js文件来配置路由:

   import Vue from 'vue';import VueRouter from 'vue-router';import Home from './views/Home.vue';import About from './views/About.vue';Vue.use(VueRouter);const routes = [{path: '/',name: 'Home',component: Home},{path: '/about',name: 'About',component: About}];const router = new VueRouter({mode: 'history',routes});export default router;

在上述代码中,首先导入VueVueRouter以及两个视图组件Home.vueAbout.vue。然后使用Vue.use(VueRouter)安装路由插件。接着定义了一个路由数组routes,其中每个对象代表一个路由,包括路径path、路由名称name和对应的组件component。最后,创建一个VueRouter实例并将其导出。

3.使用路由
main.js文件中引入路由并将其挂载到 Vue 实例上:

   import Vue from 'vue';import App from './App.vue';import router from './router';Vue.config.productionTip = false;new Vue({render: h => h(App),router}).$mount('#app');

在组件中,可以使用<router-link>标签来导航到不同的路由,使用<router-view>标签来显示当前路由对应的组件:

   <template><div><nav><router-link to="/">Home</router-link><router-link to="/about">About</router-link></nav><router-view></router-view></div></template>

<router-link>标签会生成一个链接,点击链接时会导航到对应的路由。<router-view>标签是一个占位符,用于显示当前路由对应的组件。

路由参数和查询参数

1.路由参数:可以在路由中定义参数,以便在不同的页面之间传递特定的值。例如:

   const routes = [{path: '/user/:id',name: 'User',component: User}];

在组件中,可以通过this.$route.params.id来获取路由参数的值。

2.查询参数:可以在路由链接中添加查询参数,用于传递额外的信息。例如:

   <router-link :to="{ path: '/user', query: { id: 123 } }">User Page</router-link>

在组件中,可以通过this.$route.query.id来获取查询参数的值。

路由导航守卫

路由导航守卫可以在路由切换的不同阶段进行拦截和控制。主要有以下几种导航守卫:

1.全局前置守卫:在路由切换之前执行,可以用于判断用户是否登录等权限控制。

   router.beforeEach((to, from, next) => {// 判断用户是否登录if (to.meta.requiresAuth &&!isLoggedIn()) {next('/login');} else {next();}});

2.全局后置守卫:在路由切换之后执行,可以用于统计页面访问等操作。

   router.afterEach((to, from) => {// 统计页面访问trackPageView(to.fullPath);});

3.组件内守卫:可以在组件内定义beforeRouteEnterbeforeRouteUpdatebeforeRouteLeave守卫,分别在进入组件、路由参数变化和离开组件时执行。

   export default {beforeRouteEnter(to, from, next) {// 在进入组件之前执行next(vm => {// 可以访问组件实例 vm});},beforeRouteUpdate(to, from, next) {// 在路由参数变化时执行next();},beforeRouteLeave(to, from, next) {// 在离开组件之前执行next();}};

七、状态管理

 1.安装 Vuex
  Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。安装 Vuex:

   npm install vuex

  2.配置 Vuex
  创建一个store.js文件来配置 Vuex:

   import Vue from 'vue';import Vuex from 'vuex';Vue.use(Vuex);const store = new Vuex.Store({state: {count: 0},mutations: {increment(state) {state.count++;}},actions: {increment(context) {context.commit('increment');}},getters: {doubleCount(state) {return state.count * 2;}}});export default store;

       在上述代码中,首先导入VueVuex,然后使用Vue.use(Vuex)安装状态管理插件。接着创建一个Vuex.Store实例,其中包含状态state、 mutations、 actions 和 getters。

  • state:存储应用的状态数据。
  • mutations:定义了修改状态的方法,只能通过提交 mutation 来修改状态。
  • actions:用于处理异步操作,可以提交 mutation 来修改状态。
  • getters:可以从状态中派生出一些计算属性,方便在组件中使用。

3.使用 Vuex
在组件中,可以通过this.$store来访问 Vuex 状态和方法:

   <template><div><p>Count: {{ count }}</p><p>Double Count: {{ doubleCount }}</p><button @click="increment">Increment</button></div></template><script>export default {computed: {count() {return this.$store.state.count;},doubleCount() {return this.$store.getters.doubleCount;}},methods: {increment() {this.$store.dispatch('increment');}}};</script>

在上述代码中,通过计算属性countdoubleCount分别访问Vuex中的状态和计算属性。在methods中定义了一个方法increment,用于触发Vuex中的 action。

模块

对于大型应用,可以将 Vuex 的状态拆分成多个模块,每个模块有自己的 state、mutations、actions 和 getters。这样可以更好地组织代码,提高可维护性。

const moduleA = {state: {// 模块 A 的状态},mutations: {// 模块 A 的 mutations},actions: {// 模块 A 的 actions},getters: {// 模块 A 的 getters}
};const moduleB = {state: {// 模块 B 的状态},mutations: {// 模块 B 的 mutations},actions: {// 模块 B 的 actions},getters: {// 模块 B 的 getters}
};const store = new Vuex.Store({modules: {a: moduleA,b: moduleB}
});

在组件中访问模块的状态和方法时,需要加上模块名:

<template><div><p>Module A Count: {{ moduleACount }}</p><p>Module B Count: {{ moduleBCount }}</p><button @click="incrementModuleA">Increment Module A</button><button @click="incrementModuleB">Increment Module B</button></div>
</template><script>
export default {computed: {moduleACount() {return this.$store.state.a.count;},moduleBCount() {return this.$store.state.b.count;}},methods: {incrementModuleA() {this.$store.dispatch('a/increment');},incrementModuleB() {this.$store.dispatch('b/increment');}}
};
</script>

八、案例:Todo 应用

下面我们通过一个 Todo 应用的案例来综合运用 Vue 的知识。

  1. 创建组件
    创建以下组件:

    • TodoList.vue:显示待办事项列表。
    • TodoInput.vue:输入新的待办事项。
  2. 配置路由
    创建两个路由://completed,分别显示所有待办事项和已完成的待办事项。

  3. 状态管理
    使用 Vuex 来管理待办事项的状态,包括添加、删除、标记为完成等操作。

  4. 实现功能

    • TodoInput.vue组件中,用户可以输入新的待办事项并提交。
    • TodoList.vue组件中,显示待办事项列表,每个待办事项可以被标记为完成或删除。
    • 在路由/completed中,只显示已完成的待办事项。

以下是部分代码示例:

TodoInput.vue

<template><div><input v-model="newTodo" @keyup.enter="addTodo" placeholder="Add a new todo" /></div>
</template><script>
export default {data() {return {newTodo: ''};},methods: {addTodo() {if (this.newTodo.trim()) {this.$store.dispatch('addTodo', this.newTodo);this.newTodo = '';}}}
};
</script>

TodoList.vue

<template><div><ul><li v-for="todo in todos" :key="todo.id"><input type="checkbox" v-model="todo.completed" @change="toggleTodo(todo)" />{{ todo.text }}<button @click="deleteTodo(todo)">Delete</button></li></ul></div>
</template><script>
export default {computed: {todos() {return this.$store.state.todos;}},methods: {toggleTodo(todo) {this.$store.dispatch('toggleTodo', todo);},deleteTodo(todo) {this.$store.dispatch('deleteTodo', todo);}}
};
</script>

store.js

import Vue from 'vue';
import Vuex from 'vuex';Vue.use(Vuex);const store = new Vuex.Store({state: {todos: []},mutations: {addTodo(state, text) {state.todos.push({ id: Date.now(), text, completed: false });},toggleTodo(state, todo) {todo.completed =!todo.completed;},deleteTodo(state, todo) {state.todos = state.todos.filter(item => item!== todo);}},actions: {addTodo(context, text) {context.commit('addTodo', text);},toggleTodo(context, todo) {context.commit('toggleTodo', todo);},deleteTodo(context, todo) {context.commit('deleteTodo', todo);}}
});export default store;

router.js

import Vue from 'vue';
import VueRouter from 'vue-router';
import TodoList from './views/TodoList.vue';
import CompletedTodos from './views/CompletedTodos.vue';Vue.use(VueRouter);const routes = [{path: '/',name: 'TodoList',component: TodoList},{path: '/completed',name: 'CompletedTodos',component: CompletedTodos}
];const router = new VueRouter({mode: 'history',routes
});export default router;

CompletedTodos.vue

<template><div><h2>Completed Todos</h2><ul><li v-for="todo in completedTodos" :key="todo.id">{{ todo.text }}</li></ul></div>
</template><script>
export default {computed: {completedTodos() {return this.$store.state.todos.filter(todo => todo.completed);}}
};
</script>

通过这个案例,你可以看到如何使用 Vue 的组件化、路由管理和状态管理来构建一个完整的应用程序。

九、总结

本文介绍了 Vue.js 的基础知识和高级特性,并通过一个 Todo 应用的案例展示了如何综合运用这些知识。Vue.js 是一个非常强大的前端框架,通过不断学习和实践,你可以更好地掌握它,并开发出高效、美观的前端应用程序。

希望本文对你学习 Vue.js 有所帮助!

相关文章:

Vue.js 从入门到精通:全面解析组件化、路由与状态管理(附 Todo 案例)

在当今的前端开发领域&#xff0c;Vue.js 以其简洁、高效和灵活的特点受到了广泛的关注和应用。本文将带你从 Vue 的基础知识入手&#xff0c;逐步深入到高级特性&#xff0c;让你对 Vue 有一个全面的了解&#xff0c;并通过实际案例帮助你更好地掌握 Vue 的开发。 一、Vue 简…...

AI Weekly#1:过去一周重要的AI资讯汇总

&#x1f680;热点头条 诺贝尔奖青睐AI领域&#xff1a;2024年诺贝尔物理学奖和化学奖均授予了与人工智能相关的研究。物理学奖颁发给了约翰霍普菲尔德和杰弗里辛顿&#xff0c;表彰他们在机器学习领域的开创性工作。化学奖则授予了大卫贝克、德米斯哈萨比斯和约翰江珀&#xf…...

图论刷题

卡码网 98. 所有可达路径 使用邻接矩阵存储&#xff1a; #include<iostream> #include<vector> using namespace std;vector<vector<int>>res;//收集符合条件的路径vector<int>path;//0节点到终点的路径//确定递归函数 参数和返回值void dfs(c…...

ICM20948 DMP代码详解(85)

接前一篇文章:ICM20948 DMP代码详解(84) 上一回解析了inv_icm20948_ctrl_enable_sensor函数的大部分代码,只剩下一行代码没有解析。为了便于理解和回顾,再次贴出inv_icm20948_ctrl_enable_sensor函数源码,在EMD-Core\sources\Invn\Devices\Drivers\ICM20948\Icm20948Data…...

深入解析:Linux tcpdump命令在网络流量分析中的实战应用

tcpdump是一个强大的命令行工具&#xff0c;用于捕获和分析TCP、UDP、ICMP等协议的网络流量。 功能与用途 捕获网络流量&#xff1a;tcpdump可以捕获和显示来自本地计算机或通过网络传输的数据包&#xff0c;提供有关数据包的详细信息&#xff0c;如源和目的IP地址、端口号、…...

Java集合常见知识总结(上)

Java 集合概览 Java 集合&#xff0c;也叫作容器&#xff0c;主要是由两大接口派生而来&#xff1a;一个是 Collection接口&#xff0c;主要用于存放单一元素&#xff1b;另一个是 Map 接口&#xff0c;主要用于存放键值对。对于Collection 接口&#xff0c;下面又有三个主要的…...

【算法】力扣:K个一组反转链表

前置知识 数据结构-链表反转部分链表算法题的手写栈使用 难度&#xff1a; 初阶&#xff1a;使用容器&#xff0c; 难度中等。进阶&#xff1a;纯coding修改指针 &#xff0c;难度中等&#xff0c;虽然leetcode是困难题。不过更加注重细节。 题目&#xff1a;反转 k 组中的…...

Matlab报错——错误使用 vertcat

错误提示&#xff1a; 原因&#xff1a; 这个错误表明 segment_lengths 的维度和 0 不一致。在 MATLAB 中&#xff0c;有时&#xff0c;diff 函数的输出可能是行向量&#xff0c;而segment_lengths 应该是一个列向量才能与 0 正确连接。 解决方法&#xff1a; 使用转置操作 …...

【如何获取股票数据10】Python、Java等多种主流语言实例演示获取股票行情api接口之沪深A股历史分时KDJ数据获取实例演示及接口API说明文档

最近一两年内&#xff0c;股票量化分析逐渐成为热门话题。而从事这一领域工作的第一步&#xff0c;就是获取全面且准确的股票数据。因为无论是实时交易数据、历史交易记录、财务数据还是基本面信息&#xff0c;这些数据都是我们进行量化分析时不可或缺的宝贵资源。我们的主要任…...

进入 Searing-66 火焰星球:第一周游戏指南

Alpha 第四季已开启&#xff0c;穿越火焰星球 Searing-66&#xff0c;带你开启火热征程。准备好勇闯炙热的沙漠&#xff0c;那里有无情的高温和无情的挑战在等待着你。从高风险的烹饪对决到炙热的冒险&#xff0c;Searing-66 将把你的耐力推向极限。带上充足的水&#xff0c;天…...

考研论坛设计小程序ssm+论文源码调试讲解

2相关技术 2.1微信小程序 小程序是一种新的开放能力&#xff0c;开发者可以快速地开发一个小程序。小程序可以在微信内被便捷地获取和传播&#xff0c;同时具有出色的使用体验。尤其拥抱微信生态圈&#xff0c;让微信小程序更加的如虎添翼&#xff0c;发展迅猛。 2.2 MYSQL数据…...

JAVA笔记 | EasyExcel创建带有简单下拉框的导入模板

目录 前文 业务需求 具体代码 新增Handler 控制层 前文 SpringBoot笔记 | EasyExcel导入导出及基于模板导出_easyexcel模板导出-CSDN博客 业务需求 需要一个导出模板。一个列需要填写固定的值&#xff0c;或者方便用户填写。 自己需求&#xff0c;几个固定的字段对应固…...

【含开题报告+文档+PPT+源码】贫困儿童一对一扶贫帮扶系统设计与实现

开题报告 根据《中华人民共和国慈善法》第五十八条规定&#xff0c;慈善组织确定慈善受益人&#xff0c;应当坚持公开、公平、公正的原则&#xff0c;不得指定慈善组织管理人员的利害关系人作为受益人[2]。以上所列举的平台基本没有做到公开、公平、公正的原则&#xff0c;例如…...

多系统萎缩不慌张,这些维生素是你的“隐形盾牌”!️

在这个快节奏的时代&#xff0c;健康成为了我们最宝贵的财富。而对于多系统萎缩&#xff08;MSA&#xff09;的患者来说&#xff0c;合理的营养补充更是维护身体机能、提升生活质量的关键一步。今天&#xff0c;就让我们一起揭秘那些能够成为多系统萎缩患者“守护神”的维生素吧…...

IGFBP7:免疫治疗新靶点

前 言 胰岛素样生长因子结合蛋白7&#xff08;IGFBP7&#xff09;是胰岛素超家族的生长促进肽成员&#xff0c;可与胰岛素和IGF结合&#xff0c;调控细胞生长和分化。IGFBP7在不同的肿瘤类型中表现出抑制或促进肿瘤生长的“自相矛盾”活性。研究发现IGFBP7可增强治疗性单克隆…...

深度学习模型的架构与应用:技术解析与未来展望

1. 引言 深度学习(Deep Learning)模型是当代人工智能的核心技术之一,广泛应用于语音识别、计算机视觉、自然语言处理、推荐系统等众多领域。深度学习通过构建多层神经网络,能够自动从大规模数据中学习复杂的特征和模式,其应用成果不仅推动了技术的飞跃,也带来了智能化产…...

机器学习——主要分类

前言&#xff1a; 机器学习是人工智能的重要分支之一&#xff0c;它通过分析数据来构建模型&#xff0c;并通过这些模型进行预测、分类或决策。随着数据量的迅速增长&#xff0c;机器学习在多个领域展现出巨大的应用潜力&#xff0c;推动了科技的进步。根据学习方式和数据的使用…...

Java密封类(Sealed Classes)增强详解

Java密封类&#xff08;Sealed Classes&#xff09;增强详解 Java 17引入了一个重要的新特性——密封类&#xff08;Sealed Classes&#xff09;&#xff0c;这一特性旨在增强Java编程语言的能力&#xff0c;提供了一种机制来限制哪些类可以继承一个给定的类或者实现一个给定的…...

鸿蒙如何自动生成二维码?QRCode组件

QRCode 用于显示单个二维码的组件。 说明&#xff1a; 该组件从API Version 7开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 二维码组件的像素点数量与内容有关&#xff0c;当组件尺寸过小时&#xff0c;可能出现无法展示内容的情况&…...

【分布式知识】MapReduce详细介绍

文章目录 MapReduce概述1. MapReduce编程模型Map阶段Reduce阶段 2. Shuffle和Sort阶段3. MapReduce作业的执行流程4. MapReduce的优化和特性5. MapReduce的配置和调优 MapReduce局限性相关文献 MapReduce概述 MapReduce是一个分布式计算框架&#xff0c;它允许用户编写可以在大…...

JAVA八股

快速失败&#xff08;fail-fast&#xff09; 设计的目的是为了避免在遍历时对集合进行并发修改&#xff0c;从而引发潜在的不可预料的错误。 通过迭代器遍历集合时修改集合&#xff1a; 如果你使用Iterator遍历集合&#xff0c;然后直接使用集合的修改方法&#xff08;如add(…...

关于武汉芯景科技有限公司的限流开关芯片XJ6288开发指南(兼容SY6288)

一、芯片引脚介绍 1.芯片引脚 二、系统结构图 三、功能描述 1.EN引脚控制IN和OUT引脚的通断 2.OCB引脚指示状态 3.过流自动断开...

指令:计算机的语言(五)

2.9 人机交互 ASCII与二进制 对应表略 字节转移指令 lbu&#xff1a;加载无符号字节&#xff0c;从内存中加载1个字节&#xff0c;放在寄存器最右边8位。 sb&#xff1a;存储字节指令&#xff0c;从寄存器的最右边取1个字节并将其写入内存。 复制1个字节顺序如下&#xf…...

C#笔记(1)

解决方案&#xff1a; 【1】组织项目&#xff1a;把项目放在放在一个解决方案中&#xff0c;统一开发&#xff0c;统一编译。 【2】管理项目&#xff1a;开发中的任何问题&#xff0c;在统一编译过程中&#xff0c;都能随时发现。也可以添加第三方的库文件。 命名空间: 命名空…...

SSDF攻击、防御与展望

摘要&#xff1a; 随着无线通信业务的不断发展&#xff0c;频域也越来越成为了一种珍贵的稀缺资源&#xff0c;与此同时&#xff0c;相应的无线电安全问题层出不穷&#xff0c;为无线通信造成了十分恶劣的影响&#xff0c;本文从深入理解认知无线电安全开始&#xff0c;对一些典…...

MedMamba代码解释及用于糖尿病视网膜病变分类

MedMamba原理和用于糖尿病视网膜病变检测尝试 1.MedMamba原理 MedMamba发表于2024.9.28&#xff0c;是构建在Vision Mamba基础之上&#xff0c;融合了卷积神经网的架构&#xff0c;结构如下图&#xff1a; 原理简述就是图片输入后按通道输入后切分为两部分&#xff0c;一部分走…...

单点登录的要点

单点登录&#xff08;SSO&#xff09;是一种身份验证服务&#xff0c;它允许用户使用一组凭据登录一次&#xff0c;然后在多个应用程序中访问其他应用程序而无需重新进行身份验证。这样&#xff0c;用户只需一次登录即可访问整个应用生态系统&#xff0c;提高了用户体验并简化了…...

linux线程 | 一点通你的互斥锁 | 同步与互斥

前言&#xff1a;本篇文章主要讲述linux线程的互斥的知识。 讲解流程为先讲解锁的工作原理&#xff0c; 再自己封装一下锁并且使用一下。 做完这些就要输出一堆理论性的东西&#xff0c; 但博主会总结两条结论&#xff01;&#xff01;最后就是讲一下死锁。 那么&#xff0c; 废…...

全栈开发小项目

用到的技术栈&#xff1a; nodejswebpackknockoutmongodbPM2rabbitmq 以下是一个综合指南&#xff0c;展示如何将 Node.js、Webpack、Knockout.js、MongoDB、PM2 和 RabbitMQ 集成到一个项目中。 我们将在这一项目中添加 RabbitMQ&#xff0c;用于处理消息队列。这对于任务分…...

批处理一键创建扫描仪桌面打开快捷方式图标 简单直接有效 扫描文档图片的应急策略

办公生活中&#xff0c;我们在安装完多功能一体机的打印驱动之后&#xff0c;找不到扫描文件的地方&#xff0c;如果驱动程序安装正确&#xff0c;我们可以用系统自带的扫描仪程序调用这种打印机或复印机的扫描程序即可&#xff0c;它在电脑系统中的位置一般是&#xff1a;C:\W…...