【Vue 快速入门系列】如何更优雅的使用vuex进行组件间通信

news2024/11/20 11:05:12

文章目录

  • 前言
  • 一、vuex是什么?
  • 二、vuex的使用
  • 三、四个重要的映射函数
  • 四、多组件数据共享
  • 五、模块化使用vuex

前言

前面介绍过几种可以实现组件间通信的方式props、ref、自定义事件绑定、全局事件总线、插槽…,这些要么就是实现组件间通信只能在特定条件下使用,要么就是实现起来太复杂,今天介绍到的vuex是Vue中一款强大的插件,使用vuex后可以实现任意组件间通信,并且支持模块化管理。接下来将会围绕一个计数案例进行展开,逐步引入vuex如何使用。
在这里插入图片描述
核心代码:

<template>
  <div>
      <h2>目前的数值结果是:{{n}}</h2>
      <div class="container1">
          <select v-model.number="step">
              <option value="1">1</option>
              <option value="2">2</option>
              <option value="3">3</option>
          </select>
          <button @click="addNum">增加</button>
          <button @click="subNum">减少</button>
          <button @click="oddNum">偶数再加</button>
          <button @click="longTimeAdd">延迟增加</button>
      </div>
  </div>
</template>

<script>
export default {
    // eslint-disable-next-line vue/multi-word-component-names
    name:"Counts",
    data(){
        return {
            n:0,
            step:1
        }
    },
    methods:{
        addNum(){
            this.n+=this.step
        },
        subNum(){
            this.n-=this.step
        },
        oddNum(){
            if (this.n%2==0){
                this.n+=this.step
            }
        },
        longTimeAdd(){
            setTimeout(() => {
                this.n+=this.step
            }, 1000);
        }

    }
}
</script>

<style>
.container1>*{
    margin-left: 10px; 
}
</style>

一、vuex是什么?

简单点说:是一个数据仓库,用于数据存储,数据共享,可以进行数据存放与获取,并全程监视数据的动向

使用官方语言入下:
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式 + 库。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
这个状态自管理应用包含以下几个部分:

  • 状态,驱动应用的数据源;
  • 视图,以声明方式将状态映射到视图;
  • 操作,响应在视图上的用户输入导致的状态变化。
    在这里插入图片描述

但是,当我们的应用遇到多个组件共享状态时,单向数据流的简洁性很容易被破坏:

  • 多个视图依赖于同一状态。
  • 来自不同视图的行为需要变更同一状态。
    对于问题一,传参的方法对于多层嵌套的组件将会非常繁琐,并且对于兄弟组件间的状态传递无能为力。对于问题二,我们经常会采用父子组件直接引用或者通过事件来变更和同步状态的多份拷贝。以上的这些模式非常脆弱,通常会导致无法维护的代码。

因此,我们为什么不把组件的共享状态抽取出来,以一个全局单例模式管理呢?在这种模式下,我们的组件树构成了一个巨大的“视图”,不管在树的哪个位置,任何组件都能获取状态或者触发行为!

通过定义和隔离状态管理中的各种概念并通过强制规则维持视图和状态间的独立性,我们的代码将会变得更结构化且易维护。

这就是 Vuex 背后的基本思想,借鉴了 Flux、Redux 和 The Elm Architecture。与其他模式不同的是,Vuex 是专门为 Vue.js 设计的状态管理库,以利用 Vue.js 的细粒度数据响应机制来进行高效的状态更新。
在这里插入图片描述
vuex适用于大型单页应用的开发,如果是小型的不推荐使用。
其中vuex3适配vue2,vuex4适配vue3。

vue工作原理:

  • vuex中主要包含三个部分

Actions:相当于对数据的预处理(可以在这里使用异步加载进行数据校验等)
Mutations (跟开发者工具关系密切)
State (存放数据的地方,经过校验与变换的数据都存放在这里)

  • vuex中的两种数据操作

dispatch:将数据交给Actions
commit:将数据交给Mutations

vuex在项目中使用

大致有两种(实质上一样):

  • 1.vuex/store.js 创建vuex文件夹,将代码放进store.js中
  • 2.store/index.js 创建store文件夹,将代码放进index.js中

安装vuex

npm i vuex

二、vuex的使用

继续从以下三个模块与两个方法讲起:

  • 三个模块:

Actions:相当于对数据的预处理(可以在这里使用异步加载进行数据校验等)
Mutations (跟开发者工具关系密切)
State (存放数据的地方,经过校验与变换的数据都存放在这里)

  • 两个方法:

dispatch:将数据交给Actions
commit:将数据交给Mutations

如果调用vuex的dispatch方法会将数据提交到Actions中的函数,此时数据并不是最终的结果,在Actions中可以对数据进行进一步加工,然后调用commit方法提交,在Actions与Mutations中定义的函数可以获取到上下文找到state对象中存储的数据。
接下来结合代码看一下vuex如何使用(这一段代码暴露出去一个可以使用的vuex对象):

import Vue from "vue"
import Vuex from "vuex"
Vue.use(Vuex)
const actions={
    odd_Num(comtext,value){
        // 可以通过上下文comtext找到commit方法,dispatch方法
        // 可以找到state对象,并找到其中的属性
        if (comtext.state.n%2===0){
            comtext.commit("add_Num",value)
        }
    },
    long_Time_Add(comtext,value){
        setTimeout(() => {
            comtext.commit("add_Num",value)
        }, 1000);
    }
}
const mutations={
    add_Num(state,value){
        // 这里的state被称为上下文,这里可以拿到state中的数据
        // console.log(state,value)
        state.n+=value
    },
    sub_Num(state,value){
        // console.log(state,value)
        state.n-=value
    },
}
//数据源,源数据
const state={
    n:0
}
//创建一个vuex对象
export default new Vuex.Store({
    actions,
    mutations,
    state
})

以下代码是使用vuex:
main.js

import App from "./App"
//这个便是刚才封装的vuex对象
import store from "./store"
import Vue from "vue"
new Vue({
    el:"#App",
    store,
    render:h=>h(App)
})

功能性组件:

export default {
    // eslint-disable-next-line vue/multi-word-component-names
    name:"Counts",
    data(){
        return {
            step:1
        }
    },
    computed:{
        n(){
            return this.$store.state.n
        }
    }
    ,
    methods:{
        addNum(){
            this.$store.commit("add_Num",this.step)
        },
        subNum(){
            this.$store.commit("sub_Num",this.step)
        },
        oddNum(){
            this.$store.dispatch("odd_Num",this.step)
        },
        longTimeAdd(){
            this.$store.dispatch("long_Time_Add",this.step)
        }

    }
}

除此之外vuex还有一个重要的模块供我们使用getters,这里面的方法通常用于获取定制后的state中的属性
比如下面一个实例,就是将state中的n扩大10倍后返回了出去。

const getters={
    numBig(state){
        return state.n*10
    }
}

三、四个重要的映射函数

如果vuex中的函数较多时,一个一个引入会相当麻烦,官方给出了四个映射函数,可以根据自己的需求将想要的函数一下引进来,分别是:mapState,mapGetters,mapActions,mapMutations。
以下两种写法,在使用时效果是一样的
不使用映射函数:

<script>
export default {
    // eslint-disable-next-line vue/multi-word-component-names
    name:"Counts",
    data(){
        return {
            step:1
        }
    },
    computed:{
        n(){
            return this.$store.state.n
        },
        bigNum(){
            // 以下两种写法均可以
            // return this.$store.getters["numBig"]
            return this.$store.getters.numBig
        }
    }
    ,
    methods:{
        addNum(){
            this.$store.commit("add_Num",this.step)
        },
        subNum(){
            this.$store.commit("sub_Num",this.step)
        },
        oddNum(){
            this.$store.dispatch("odd_Num",this.step)
        },
        longTimeAdd(){
            this.$store.dispatch("long_Time_Add",this.step)
        }

    }
}
</script>

使用映射函数:

<script>
import {mapState,mapGetters,mapActions,mapMutations} from "vuex"
export default {
    // eslint-disable-next-line vue/multi-word-component-names
    name:"Counts",
    data(){
        return {
            step:1
        }
    },
    computed:{
        ...mapState(["n"]),
        ...mapGetters({bigNum:"numBig"})
    }
    ,
    methods:{
        // 传入对象是常规写法,当对象中的键值相等时,可以用传入列表的方式进行传参
        // 例如上面的mapState(["n"])
        ...mapMutations({addNum:"add_Num",subNum:"sub_Num"}),
        ...mapActions({oddNum:"odd_Num",longTimeAdd:"long_Time_Add"})
    }
}
</script>

四、多组件数据共享

经过将多个组件使用到的数据提取到vuex,可以实现多组件间的数据共享,也就是说在a组件修改共享数据之后,在b组件可以渲染出数据改变后的结果,同样b组件中修改a组件也可以渲染。
以下案例一个计数组件负责计数,一个person组件,负责将人员列表渲染出来,person组件支持增加用户,我们要做的就是person组件中进行人员添加后,计数组件感应到人数变动,重新渲染列表,将总人数进行改变。
在这里插入图片描述
vuex插件

import Vue from "vue"
import Vuex from "vuex"
import {nanoid} from "nanoid"
Vue.use(Vuex)
const actions={
    odd_Num(comtext,value){
        // 可以通过上下文comtext找到commit方法,dispatch方法
        // 可以找到state对象,并找到其中的属性
        if (comtext.state.n%2===0){
            comtext.commit("add_Num",value)
        }
    },
    long_Time_Add(comtext,value){
        setTimeout(() => {
            comtext.commit("add_Num",value)
        }, 1000);
    },
    add_Person(context,value){
        var someone={id:nanoid(),name:value}
        context.commit("add_Person",someone)
    }
}
const mutations={
    add_Num(state,value){
        // 这里的state被称为上下文,这里可以拿到state中的数据
        // console.log(state,value)
        state.n+=value
    },
    sub_Num(state,value){
        // console.log(state,value)
        state.n-=value
    },
    add_Person(state,value){
        state.personList.unshift(value)
    }
}
const state={
    n:0,
    personList:[
        {
            id:"0001",
            name:"张三"
        }
    ]
}
const getters={
    numBig(state){
        return state.n*10
    },
    personNum(state){
        return state.personList.length
        // console.log("index"+state.personList.length)
    }
}
export default new Vuex.Store({
    actions,
    mutations,
    state,
    getters
})

计数组件

<template>
  <div>
      <h2>目前的数值结果是:{{n}}</h2>
      <h2>放大后的数值结果是:{{bigNum}}</h2>
      <div class="container1">
          <select v-model.number="step">
              <option value="1">1</option>
              <option value="2">2</option>
              <option value="3">3</option>
          </select>
          <button @click="addNum(step)">增加</button>
          <button @click="subNum(step)">减少</button>
          <button @click="oddNum(step)">偶数再加</button>
          <button @click="longTimeAdd(step)">延迟增加</button>
      </div>
      <h2>当前的总人数为{{personNum}}</h2>
  </div>
</template>

<script>
import {mapState,mapGetters,mapActions,mapMutations} from "vuex"
export default {
    // eslint-disable-next-line vue/multi-word-component-names
    name:"Counts",
    data(){
        return {
            step:1
        }
    },
    computed:{
        ...mapState(["n"]),
        ...mapGetters({bigNum:"numBig",personNum:"personNum"})
    }
    ,
    methods:{
        // 传入对象是常规写法,当对象中的键值相等时,可以用传入列表的方式进行传参
        // 例如上面的mapState(["n"])
        ...mapMutations({addNum:"add_Num",subNum:"sub_Num"}),
        ...mapActions({oddNum:"odd_Num",longTimeAdd:"long_Time_Add"})
    }
}
</script>

<style>
.container1>*{
    margin-left: 10px; 
}
</style>

person组件

<template>
  <div>
      <h2>目前的计算结果为{{n}}</h2>
      //监听的键盘事件,当输入enter时添加用户
      <input v-model="tempname" @keydown.enter="add_Person(tempname)">
      <ul>
          <li v-for="p in personList" :key="p.id">
              学生id:{{p.id}} 学生姓名:{{p.name}}
          </li>
      </ul>
  </div>
</template>

<script>
import {mapState,mapActions} from "vuex"
export default {
    // eslint-disable-next-line vue/multi-word-component-names
    name:"Persons",
    data(){
        return {
            tempname:""
        }
    },
    computed:{
        ...mapState(["n","personList"])
    },
    methods:{
        ...mapActions(["add_Person"])
    }
}
</script>

<style>

</style>

五、模块化使用vuex

如果不按照数据功能对数据进行模块划分,那么vuex将会显得非常杂乱,我们希望vuex可以根据数据的不同作用将其进行模块化,便于我们管理,对于接下来的代码大家需要熟悉的是如何使用划分后的函数、函数映射。
划分后的代码大概长这个样子,其中store中的index会将count.js与person.js引入并使用。vue代码中使用vuex依旧是引入index.js,值得注意的是进行模块划分后的vuex,在使用时跟以往有了不同。详细看代码
在这里插入图片描述
index.js

import Vue from "vue"
import Vuex from "vuex"
import counts from "./count"
import person from "./person"
Vue.use(Vuex)
export default new Vuex.Store({
    modules:{
        counts,
        person

    }
})

count.js

// import axios from "axios"
export default{
    namespaced:true,
    actions:{
    /* ... */
    },
    mutations:{
    /* ... */
    },
    state:{
        n:0,
    },
    getters:{
        numBig(state){
            return state.n*10
        }
    }
}

person.js

import {nanoid}  from "nanoid"
export default{
    namespaced:true,
    actions:{
    /* ... */
    },
    mutations:{
    /* ... */
    },
    state:{
        personList:[
            {
                id:"0001",
                name:"张三"
            }
        ]
    },
    getters:{
        personNum(state){
            return state.personList.length
            // console.log("index"+state.personList.length)
        }
    }
}

count.vue

<template>
  <div>
      <h2>目前的数值结果是:{{n}}</h2>
      <h2>放大后的数值结果是:{{bigNum}}</h2>
      <div class="container1">
          <select v-model.number="step">
              <option value="1">1</option>
              <option value="2">2</option>
              <option value="3">3</option>
          </select>
          <button @click="addNum(step)">增加</button>
          <button @click="subNum(step)">减少</button>
          <button @click="oddNum(step)">偶数再加</button>
          <button @click="longTimeAdd(step)">延迟增加</button>
      </div>
      <h2>当前的总人数为{{personNum}}</h2>
  </div>
</template>

<script>
import {mapState,mapGetters,mapActions,mapMutations} from "vuex"
export default {
    // eslint-disable-next-line vue/multi-word-component-names
    name:"Counts",
    data(){
        return {
            step:1
        }
    },
    computed:{
        ...mapState("counts",["n"]),
        ...mapGetters("counts",{bigNum:"numBig"}),
        ...mapGetters("person",{personNum:"personNum"})
    }
    ,
    methods:{
        // 传入对象是常规写法,当对象中的键值相等时,可以用传入列表的方式进行传参
        // 例如上面的mapState(["n"])
        ...mapMutations("counts",{addNum:"add_Num",subNum:"sub_Num"}),
        ...mapActions("counts",{oddNum:"odd_Num",longTimeAdd:"long_Time_Add"})
    }
}
</script>

<style>
.container1>*{
    margin-left: 10px; 
}
</style>

persons.vue

<template>
  <div>
      <h2>目前的计算结果为{{n}}</h2>
      <input v-model="tempname" @keydown.enter="addPerson(tempname)">
      <button v-if="tag" @click="tag=!tag">目前可增加任意姓氏</button>
      <button v-if="!tag" @click="tag=!tag">目前只可以添加王氏</button>
      <ul>
          <li v-for="p in personList" :key="p.id">
              学生id:{{p.id}} 学生姓名:{{p.name}}
          </li>
      </ul>
  </div>
</template>

<script>
import {mapState,mapActions} from "vuex"
export default {
    // eslint-disable-next-line vue/multi-word-component-names
    name:"Persons",
    data(){
        return {
            tag:true,
            tempname:""
        }
    },
    computed:{
        ...mapState("counts",["n"]),
        ...mapState("person",["personList"])
    },
    methods:{
        ...mapActions("person",["add_Person"]),
        addPerson(){
            if (this.tempname===""){
                return ""
            }
            if(this.tag){
                // 映射出来的函数
                this.add_Person(this.tempname)
            }else{
//[Vue warn]: Error in v-on handler: "TypeError: this.addPersonWang is not a function"
// 如果没有使用映射的话,不能这样使用
// this.addPersonWang(this.tempname)


                // 正确的使用方式(使用模块命名空间进行限定)
                this.$store.dispatch("person/addPersonWang",this.tempname)
            }
            this.tempname=""
        },
    }
}
</script>

<style>

</style>

除此之外还可以通过下面方法获取到vuex中的state中的属性。
this.$store.state.模块名.属性
this.$store.state.loginModel.userInfo


到此vuex的使用也就介绍完了,如果大家有什么好的想法欢迎评论区留言。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/110376.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

一个基于.Net开发的Windows截屏录制工具

今天给大家推荐一个UI漂亮、功能强大的截屏录制工具。 项目简介 这是基于.Net开发的&#xff0c;屏幕截图、录屏的开源项目。功能非常强大&#xff0c;功能列表如下&#xff1a; 1、截图&#xff1a;全屏截图、滚动截图、检测窗口截图、自动截图、倒计时截图 2、录制&#…

Treap树堆

1.概念 当串行一直插入连续的数字&#xff0c;会导致树成为一个链表&#xff0c;时间复杂度变为0N 树堆概念&#xff1a; 主要体现的思想是随机插入数字&#xff0c;会给每个数字赋予一个优先级——>目的是让插入的关键字满足二叉树&#xff08;节点的性质满足&#xff08…

155. SAP Smart Table 的 Personalization(个性化配置)

本教程的前一步骤,我们介绍了 SAP Smart Table 和 Smart Filter Bar 配合起来的使用方法: SAP UI5 应用开发教程之一百五十四 - SAP UI5 Smart Table 和 Smart Filter Bar 的联合使用方法介绍本文我们在此基础上更进一步,为 Smart Table 增添一个 Personalization(个性化配置…

蓝桥杯备赛Day2——知识拾遗

目录 字符串 格式化输出 字符串的常用方法 1、去掉空格和特殊符号 2、字符串的测试和替换函数 3、字符串的分割 4、连接字符串 5.截取字符串(切片&#xff09; ​编辑 6、eval函数 7、关键字in&#xff08;返回布尔值&#xff09; 8、startswith()、endswith() 9、…

第5章 管理端(Vue)布局面的重构与路由的全局存储

1 重构路由&#xff1a;src\router\index.js import { createRouter, createWebHashHistory } from vue-router import HomeView from ../views/HomeView.vue //注意&#xff1a;path属性所对应的字符串不能与“*.vue”文件名相同否则会出现错误。 const routes [{ path: …

https搭建-基于phpstudy+openssl实现https网站搭建

目录 一、前言 1.https简介 2.生成ssl证书 二、下载安装phpstudy 1.下载phpstudy 2.启动phpstudy 三、利用openssl证书搭建https 1.进行phpstudy的配置https 2.把CA自签名证书导入受信任的根证书中 3.更改主机host文件 一、前言 1.https简介 HTTPS &#xff0c;是以…

扫雷游戏的设计——大型程序的设计思路

目录 &#x1f33a;了解扫雷游戏的作用原理并梳理思路 &#x1f33a;扫雷游戏前期部分完善 &#x1f337;文件的创建 &#x1f337;创建菜单&#xff0c;完善主函数 &#x1f333;代码呈现&#xff1a; &#x1f33a;扫雷游戏主题内容 &#x1f335;第一步初始化棋盘 &#x1…

CSDN博客运营团队2022年H2总结

前言 在2022年的年中&#xff0c;我们对外公布了我们的年中盘点&#xff1a;2022年上半年部分团队的总结 我们希望尽可能的公开我们的工作内容&#xff0c;让更多人可以了解CSDN的变化&#xff0c;同时也希望收到大家的真实反馈&#xff1a;你期待的新功能上线了吗&#xff1…

创建react项目

1.安装Node.js:官网Node.js下载 2.检查安装 3.命令安装&#xff1a;cnpm:npm install -g cnpm --registryhttps://registry.npm.taobao.org(cnpm比较快) 4.查cnpm安装是否成功&#xff1a;命令&#xff1a;cnpm -v 5.react脚手架安装命令&#xff1a;cnpm i -g create-react…

深度!用“极速统一”,开启金融行业数据分析新范式

作者&#xff1a;51CTO 赵立京 数据库作为金融信息系统的核心基础设施&#xff0c;历经数十年发展&#xff0c;为金融行业转型升级提供了有力的技术支撑。同时&#xff0c; 以银行为代表的金融行业是数据库销售额占比最高的市场&#xff0c;也是对数据库技术依赖度最高、要求最…

写出更现代化的Python代码:聊聊 Type Hint

Type Hint是 Python 3.5 新增的支持&#xff0c;中文可以译为 类型提示。屏幕前的你或许听过&#xff0c;又或许没有。所以今天&#xff0c;让我们一起了解了解。本文基于 Python 3.10.4&#xff0c;部分代码需要在 Python 3.10.0 及以上运行&#xff0c;原因在后续文章中会有说…

kali系统渗透window实现屏幕监控

1安装 VMware15.5,kali系统&#xff0c;桥接模式 链接&#xff1a;https://pan.baidu.com/s/1Y3ftPnzCj0NaMQNDAhIUjw 提取码&#xff1a;3k2w 2修改sshd_config vim /etc/ssh/sshd_config 去掉这两行注释 完成后保存 esc : wq! 重启SSH服务 /etc/init.d/ssh restart Fina…

一文看懂Linux内核页缓存(Page Cache)

我们知道文件一般存放在硬盘&#xff08;机械硬盘或固态硬盘&#xff09;中&#xff0c;CPU 并不能直接访问硬盘中的数据&#xff0c;而是需要先将硬盘中的数据读入到内存中&#xff0c;然后才能被 CPU 访问。 由于读写硬盘的速度比读写内存要慢很多&#xff08;DDR4 内存读写…

C语言期末集训3(大一,超基础,小猫猫大课堂配套练习)——循环结构

更新不易&#xff0c;麻烦多多点赞&#xff0c;欢迎你的提问&#xff0c;感谢你的转发&#xff0c; 最后的最后&#xff0c;关注我&#xff0c;关注我&#xff0c;关注我&#xff0c;你会看到更多有趣的博客哦&#xff01;&#xff01;&#xff01; 喵喵喵&#xff0c;你对我…

[第十二届蓝桥杯/java/算法]F——时间显示

&#x1f9d1;‍&#x1f393;个人介绍&#xff1a;大二软件生&#xff0c;现学JAVA、Linux、MySQL、算法 &#x1f4bb;博客主页&#xff1a;渡过晚枫渡过晚枫 &#x1f453;系列专栏&#xff1a;[编程神域 C语言]&#xff0c;[java/初学者]&#xff0c;[蓝桥杯] &#x1f4d…

五步法搞定BI业务需求梳理

五步法搞定BI业务需求梳理。高手就是把复杂的事情简单化&#xff0c;简单的东西重复做、认真做。 五步法是哪五步 第一&#xff0c; 明确用户。商业智能BI项目的规划一切以用户需求为导向&#xff0c;首先需要明确各层次的需求用户。用户都不能明确&#xff0c;调研的入口就没…

前端工程化与 webpack:webpack 的基本使用

1. 什么是 webpack 概念&#xff1a;webpack 是前端项目工程化的具体解决方案。 主要功能&#xff1a;它提供了友好的前端模块化开发支持&#xff0c;以及代码压缩混淆、处理浏览器端 JavaScript 的兼容性、性 能优化等强大的功能。 好处&#xff1a;让程序员把工作的重心放…

自动控制原理笔记-信号流图-Mason公式-控制系统的传递函数

目录 信号流图与结构图的比较&#xff1a; 掌握结构图与信号流图的转换&#xff1a; Mason增益公式&#xff1a; 式子详解&#xff1a; 使用Mason增益公式步骤&#xff1a; 使用Mason增益公式的例题&#xff1a; ​编辑 控制系统的传递函数 &#xff1a; 开环传递函数…

当红齐天再捧“绽放杯”金奖:全流程算力网络夯实元宇宙“底座”

近日&#xff0c;由工信部主办的第五届“绽放杯”5G应用征集大赛在深圳落幕。本届大赛以“5G赋能数字化&#xff0c;扬帆助力新征程 ”为主题&#xff0c;超7000家单位的2.8万个项目参赛&#xff0c;共享5G赋能实体经济的新技术、新成果。英特尔联合行业合作伙伴再获佳绩。 其…

java ssm热带水果网上商城系统--

目录 第一章 绪论 5 1.1 研究背景 5 1.2系统研究现状 5 1.3 系统实现的功能 6 1.4系统实现的特点 6 1.5 本文的组织结构 6 第二章开发技术与环境配置 7 2.1 Java语言简介 7 2.2JSP技术 8 2.3 MySQL环境配置 8 2.4 MyEclipse环境配置 9 2.5 mysql数据库介绍 9 2.6 B/S架构 9 第三…