Echarts数据可视化(下)

四、数据可视化项目实战

  • 后台搭建

  • 结合Vue开发图表组件

  • WebSocket实现数据推送

  • 主题切换/页面合并/全屏切换

4.1 Koa2

学习介绍:koa2 - 简书

官网:Koa (koajs) -- 基于 Node.js 平台的下一代 web 开发框架 | Koajs 中文文档

4.1.1 Koa2 的介绍

  • 基于Node.js平台的web开发框架

  • 由Express原班人马打造 Express Koa Koa2

  • 环境依赖 Node v7.6.0及以上

Koa2的特点

  • 支持 async/await

  • 洋葱模型的中间件

4.1.2 Koa2快速上手

  • 检查Node的环境

  • 安装Koa

    npm init -y :可以在当前文件夹下快速创建package.json文件,可以帮我们维护第三方包信息

    npm install koa:下载koa到当前文件夹下(为什么不是koa2:因为它会自己联网下载最新版本的koa,而最新版本的koa就是koa2)

  • 创建并编写app.js文件,服务器的入口文件

    1. 创建koa对象

    2. 编写响应函数(中间件)

    3. 监听端口

  • 启动服务器

    node app.js

  1. 打开终端

D:\Java Project\koa_study>node -v
v16.17.0
​
D:\Java Project\koa_study>npm init -y
Wrote to D:\Java Project\koa_study\package.json:
​
{
  "name": "koa_study",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}
​
​
​
D:\Java Project\koa_study>npm install koa
​
added 42 packages, and audited 43 packages in 4s
​
4 packages are looking for funding
  run `npm fund` for details
​
found 0 vulnerabilities
​
D:\Java Project\koa_study>

2、app.js

/*
//官网教程
const Koa = require('koa');
const app = new Koa();
​
app.use(async ctx => {
    ctx.body = 'Hello World';
});
​
app.listen(8080);
*/
//1、创建koa对象
const Koa = require('koa')
const app = new Koa()
//2、编写响应函数(中间件)
//ctx: 上下文,web容器,ctx.request ctx.response
//next:下一个中间件,下一层中间件是否能够得到执行,取决于next这个函数有没有被调用
app.use(async (ctx,next)=>{
    console.log(ctx.request.url)
    ctx.body = 'Hello Kevin'
    //ctx.response.body = 'Hello Kevin' //这种方式也可以
})
//3、绑定端口号:9090
app.listen(9090)

3、启动服务器

node app.js

访问成功

D:\Java Project\koa_study>node app.js
/    //访问http://localhost:9090/,最后的/
/favicon.ico  //浏览器自己发出的一个图标请求

Koa2中间件的特点

  • Koa对象通过use方法加入一个中间件

    //代码模板
    app.use(async (ctx,next)=>{
        //刚进入中间件想做的事情
        await next()
        //内层所有中间件结束之后想做的事情
    })
  • 一个中间件就是一个函数

  • 中间件的执行顺序符合洋葱模型

  • 内层中间件能否执行取决于外层中间件的next函数是否调用

    //验证洋葱模型
    //第一层中间件
    app.use(async (ctx,next)=>{
        console.log('第一层中间件...1 '+ctx.request.url)  //打印请求
        ctx.response.body = 'Hello Kevin'
        //ctx.body = 'Hello Kevin'
        next()  //进入第二层中间件
        console.log('第一层中间件...2 '+ctx.request.url)  //打印请求
    })
    //第二层中间件
    app.use((ctx,next)=>{
        console.log('第二层中间件...1 '+ctx.request.url)  //打印请求
        next()
        console.log('第二层中间件...2 '+ctx.request.url)  //打印请求
    })
    //第三层中间件
    app.use((ctx,next)=>{
        console.log('第三层中间件...1 '+ctx.request.url)  //打印请求
    })
D:\Java Project\koa_study>node app.js
第一层中间件...1 /
第二层中间件...1 /
第三层中间件...1 /
第二层中间件...2 /
第一层中间件...2 /
第一层中间件...1 /favicon.ico
第二层中间件...1 /favicon.ico
第三层中间件...1 /favicon.ico
第二层中间件...2 /favicon.ico
第一层中间件...2 /favicon.ico

  • 调用next函数得到的是Promise对象

    //验证洋葱模型
    //第一层中间件
    app.use(async (ctx,next)=>{
        console.log('第一层中间件...1 '+ctx.request.url)  //打印请求
        ctx.response.body = 'Hello Kevin'
        //ctx.body = 'Hello Kevin'
        next()
        console.log('第一层中间件...2 '+ctx.request.url)  //打印请求
    })
    //第二层中间件
    app.use((ctx,next)=>{
        console.log('第二层中间件...1 '+ctx.request.url)  //打印请求
        const ret = next()
        console.log(ret)
        console.log('第二层中间件...2 '+ctx.request.url)  //打印请求
    })
    //第三层中间件
    app.use((ctx,next)=>{
        console.log('第三层中间件...1 '+ctx.request.url)  //打印请求
        return 'China'
    })
    D:\Java Project\koa_study>node app.js
    第一层中间件...1 /
    第二层中间件...1 /
    第三层中间件...1 /
    Promise { 'China' }
    第二层中间件...2 /
    第一层中间件...2 /
    第一层中间件...1 /favicon.ico
    第二层中间件...1 /favicon.ico
    第三层中间件...1 /favicon.ico
    Promise { 'China' }
    第二层中间件...2 /favicon.ico
    第一层中间件...2 /favicon.ico
  • 将Promise对象返回为字符串 加入await 和 async即可

    //验证洋葱模型
    //第一层中间件
    app.use(async (ctx,next)=>{
        console.log('第一层中间件...1 '+ctx.request.url)  //打印请求
        ctx.response.body = 'Hello Kevin'
        //ctx.body = 'Hello Kevin'
        next()
        console.log('第一层中间件...2 '+ctx.request.url)  //打印请求
    })
    //第二层中间件
    app.use(async (ctx,next)=>{
        console.log('第二层中间件...1 '+ctx.request.url)  //打印请求
        const ret = await next()
        console.log(ret)
        console.log('第二层中间件...2 '+ctx.request.url)  //打印请求
    })
    //第三层中间件
    app.use((ctx,next)=>{
        console.log('第三层中间件...1 '+ctx.request.url)  //打印请求
        return 'China'
    })
    D:\Java Project\koa_study>node app.js
    第一层中间件...1 /
    第二层中间件...1 /
    第三层中间件...1 /
    第一层中间件...2 /
    China
    第二层中间件...2 /
    第一层中间件...1 /favicon.ico
    第二层中间件...1 /favicon.ico
    第三层中间件...1 /favicon.ico
    第一层中间件...2 /favicon.ico
    China
    第二层中间件...2 /favicon.ico

4.2 项目准备

后台项目的目标:

  1. 计算服务器处理请求的总耗时

  2. 在响应头上加上响应内容的mime类型(mime类型:指的是所返回给前端的数据类型是什么,例如:application/json)

  3. 根据URL读取指定目录下的文件内容

后台项目的实现步骤:

  1. 项目准备

  2. 总耗时中间件

  3. 响应头中间件

  4. 业务逻辑中间件

  5. 允许跨域

项目准备

  1. 安装包

  2. npm init -y:初始化package.json文件

    如果已经存在:则 npm install即可

    npm install koa

  3. 创建文件和目录结构

    app.js

    data/ :此项目的数据存在json文件中,本来是应该存在数据库的(为了简化开发)

    middleware/

    -koa_responsedata.js :处理业务逻辑的中间件,读取某个json文件的数据

    -koa_response_duration.js //计算服务器消耗时长的中间件

    -koa_response_header.js //设置响应头的中间件

    utils/

    -file_untils.js :帮我们快速读取某个目录下的文件

4.2.1总耗时中间件

  • 第一层中间件

  • 计算执行时间

    一进入时记录开始时间

    其他所有中间件执行完后记录结束时间

    两者相减

  • 设置响应头

    X-Response-Time:5ms

未设置之前的响应头

koa_response_duration.js

//计算服务器消耗时长的中间件
module.exports = async (ctx,next)=>{
    //记录开始时间
    const start = Date.now()
    //让内层中间件得到执行
    await next()  //使所有内层中间件得到执行,并返回Promise中存在的东西
    //记录结束时间
    const end = Date.now()
    const duration = end - start
    //设置响应头 X-Response-Time:ctx.set()
    ctx.set('X-Response-Time',duration+'ms')
}

app.js

//服务器的入口文件
//1.创建koa的实例对象
const Koa = require('koa')
const app = new Koa()
//2.绑定中间件
//绑定第一层中间件
const responseDuration = require('./middleware/koa_response_duration')
app.use(responseDuration)
//绑定第二层中间件
//绑定第三层中间件
//3.绑定端口号 8888
app.listen(8888)

启动

4.2.2响应头中间件

  • 第二层中间件(没有固定放在哪,一般放在第二层)

  • 获取mime类型

    application/json

  • 设置响应头(响应头格式)

    Content-Type:application/json;charset=utf-8

koa_response_header.js

//设置响应头的中间件
module.exports =async (ctx,next)=>{
    const contentType = 'application/json;charset=utf-8'
    ctx.set('Content-Type',contentType)
    ctx.response.body = '{"success":true}'
    await next()
}

app.js

//服务器的入口文件
//1.创建koa的实例对象
const Koa = require('koa')
const app = new Koa()
//2.绑定中间件
//绑定第一层中间件
const responseDuration = require('./middleware/koa_response_duration')
app.use(responseDuration)
const responseHeader = require('./middleware/koa_response_header')
app.use(responseHeader)
//绑定第二层中间件
//绑定第三层中间件
//3.绑定端口号 8888
app.listen(8888)

4.2.3业务逻辑中间件

  • 第三层中间件

  • 读取文件内容:http://localhost:8888/api/seller

  • 获取请求路径,拼接文件路径

  • 读取该路径对应的文件的内容

  • 设置响应体

    ctx.response.body

  • 接口总览

    1. 商家销量 /api/seller

    2. 预算开销 /api/budget

    3. 库存信息 /api/stock

    4. 销量趋势 /api/trend

    5. 销量排行 /api/rank

    6. 商家分布 /api/map

    7. 热销商品 /api/hotproduct

koa_responsedata.js

const path = require('path')
const fileUtils = require('../utils/file_utils')
//处理业务逻辑的中间件,读取某个json文件的数据
module.exports = async (ctx,next)=>{
    //根据url读取文件
    const url = ctx.request.url  // url: /api/seller   文件的路径:../data/seller.json
    var filePath = url.replace('/api','../data') //url: ../data/seller
    filePath = filePath+'.json'  // url: ../data/seller.json
    filePath = path.join(__dirname,filePath)  //__dirname:当前文件所处的路径  D:\Java Project\koa_server\data\seller.json
​
    try {
        const  ret = await fileUtils.getFileJsonData(filePath)
        ctx.response.body = ret  //设置响应体
    }catch (error) {
        const errorMessage = {
            message: '读取文件内容失败,文件资源不存在',
            status: 404
        }
        ctx.response.body = JSON.stringify(errorMessage)
    }
​
    console.log(filePath)
    await next()
}

file_utils.js

//读取文件的工具方法
const fs = require('fs')
module.exports.getFileJsonData = (filePath)=>{
    //return 'haha'
    return new Promise((resolve,reject)=>{
        //根据文件路径读取文件内容
        fs.readFile(filePath,'utf-8',(error,data)=>{
            if(error){
                //读取文件失败
                reject(error)
            }else {
                //读取文件成功
                resolve(data)
            }
        })
    })
}

app.js

//服务器的入口文件
//1.创建koa的实例对象
const Koa = require('koa')
const app = new Koa()
//2.绑定中间件
//绑定第一层中间件
const responseDuration = require('./middleware/koa_response_duration')
app.use(responseDuration)
//绑定第二层中间件
const responseHeader = require('./middleware/koa_response_header')
app.use(responseHeader)
//绑定第三层中间件
const responseData = require('./middleware/koa_responsedata')
app.use(responseData)
//3.绑定端口号 8888
app.listen(8888)

4.2.4 允许跨域

  1. 实际是通过Ajax访问服务器

  2. 同源策略

    同协议/同域名/同端口

    当前页面的地址和Ajax获取数据的地址

  3. 设置响应头,即可允许跨域

    //设置响应头的中间件
    module.exports =async (ctx,next)=>{
        ctx.set("Access-Control-Allow-Origin","*")
        ctx.set("Access-Control-Allow-Methods","OPTIONS,GET,PUT,POST,DELETE")
        await next()
    }

4.3 前端项目_项目的创建和准备

项目开发步骤:

  1. 前端项目准备

  2. 单独图表组件的开发

  3. WebSocket的引入

  4. 细节处理

整个项目的架构是基于Vue的,所以我们需要创建Vue项目,然后再Vue项目中开发各个图表组件

4.3.1 vue-cli 脚手架环境的安装

在全局环境中安装 vue-cli 脚手架(一台电脑只需要运行一次即可)

PS D:\Java Project\vue_study> npm install -g @vue/cli
npm WARN deprecated source-map-url@0.4.1: See https://github.com/lydell/source-map-url#deprecated
npm WARN deprecated urix@0.1.0: Please see https://github.com/lydell/urix#deprecated
npm WARN deprecated source-map-resolve@0.5.3: See https://github.com/lydell/source-map-resolve#deprecated
npm WARN deprecated resolve-url@0.2.1: https://github.com/lydell/resolve-url#deprecated
npm WARN deprecated apollo-server-errors@3.3.1: The `apollo-server-errors` package is part of Apollo Server v2 and v3, which are now deprecated (end-of-life October 22nd 2023). This package's functionality is now found in the `@apollo/server` package. See https://www.apollographql.com/docs/apollo-server/previous-versions/ for more details.
npm WARN deprecated apollo-server-env@4.2.1: The `apollo-server-env` package is part of Apollo Server v2 and v3, which are now deprecated (end-of-life October 22nd 2023). This package's functionality is now found in the `@apollo/utils.fetcher` package. See https://www.apollographql.com/docs/apollo-server/previous-versions/ for more details.
npm WARN deprecated apollo-datasource@3.3.2: The `apollo-datasource` package is part of Apollo Server v2 and v3, which are now deprecated (end-of-life October 22nd 2023). See https://www.apollographql.com/docs/apollo-server/previous-versions/ for more details.
npm WARN deprecated subscriptions-transport-ws@0.11.0: The `subscriptions-transport-ws` package is no longer maintained. We recommend you use `graphql-ws` instead. For help migrating Apollo software to `graphql-ws`, see https://www.apollographql.com/docs/apollo-server/data/subscriptions/#switching-from-subscriptions-transport-ws    For general help using `graphql-ws`, see https://github.com/enisdenjo/graphql-ws/blob/master/README.md
​
added 855 packages, and audited 857 packages in 2m
​
6 vulnerabilities (1 moderate, 5 high)
​
To address all issues (including breaking changes), run:
  npm audit fix --force
​
Run `npm audit` for details.
PS D:\Java Project\vue_study>

4.3.2. 工程的创建

使用命令行执行

vue create vision  //vision:项目名称

踩坑链接:摩杜云开发者社区-摩杜云

然后Y进入如下页面

  1. 进行手动选择

  1. 按空格进行选择如下选项

  1. 按下回车选择Vue版本

  2. 是否要选择历史模式路由 n

  3. 选择css预处理模式语言:less

  4. ESLint选择标准配置:ESLint + Standard config

  5. Lint on save

  6. 放在单独的文件中

  7. 是否需要保存成预设N

    以上步骤选择项记录:

    Vue CLI v5.0.8
    ? please pick a preset:     Manually select features
    ? Check the features needed for your project:     Babel, Router, Vuex, CSS Pre-processors, Linter
    ? Choose a version of Vue.js that you want to start the project with      3.x
    ? Use history mode for router? (Requires proper server setup for index fallback in production)    No
    ? Pick a CSS pre-processor (PostCSS, Autoprefixer and CSS Modules are supported by default):    Less
    ? Pick a linter / formatter config:    Standard
    ? Pick additional lint features:    Lint on save
    ? Where do you prefer placing config for Babel, ESLint, etc.?     In dedicated config files
    ? Save this as a preset for future projects? (y/N)    N
  8. 然后就会在线联网下载了

Vue CLI v5.0.8
✨  Creating project in D:\Java Project\vue_study\vision.
🗃  Initializing git repository...
⚙️  Installing CLI plugins. This might take a while...
​
​
added 857 packages in 35s
🚀  Invoking generators...
📦  Installing additional dependencies...
​
​
added 185 packages in 34s
⚓  Running completion hooks...
​
📄  Generating README.md...
​
🎉  Successfully created project vision.
👉  Get started with the following commands:
​
 $ cd vision
 $ npm run serve
​
PS D:\Java Project\vue_study>

下载完毕就会看到生成的项目了

运行Vue项目

PS D:\Java Project\vue_study> cd vision
PS D:\Java Project\vue_study\vision> npm run serve
​
> vision@0.1.0 serve
> vue-cli-service serve
​
 INFO  Starting development server...
​
​
 DONE  Compiled successfully in 6692ms                                                                          18:43:53
​
  App running at:
  - Local:   http://localhost:8080/
  - Network: http://172.16.202.207:8080/
​
  Note that the development build is not optimized.
  To create a production build, run npm run build.

输入链接访问页面:http://localhost:8080/

也可以用IDEA打开然后运行项目

4.3.3 删除无关文件代码

App.vue删除后

<template>
​
  <router-view/>
</template>
​
<style lang="less">
​
</style>

删除Helloworld.vue\AboutView.vue\HomeView.vue

使用vue-cli重新下载一个2.x版本的vision2.0项目,进行和之前一样的操作

App.vue

<template>
  <div id="app">
​
  </div>
</template>
​
<style lang="less">
​
</style>

router/index.js

import Vue from 'vue'
import VueRouter from 'vue-router'
​
Vue.use(VueRouter)
​
const routes = [
​
]
​
const router = new VueRouter({
  routes
})
​
export default router

用另外一种方式创建 vue2.x 项目

PS D:\企业级Java开发> vue init webpack vue-demo
​
  Command vue init requires a global addon to be installed.
  Please run undefined @vue/cli-init and try again.
​
PS D:\企业级Java开发> npm install -g @vue/cli-init
npm WARN deprecated har-validator@5.1.5: this library is no longer supported
npm WARN deprecated uuid@3.4.0: Please upgrade  to version 7 or higher.  Older versions may use Math.random() in certain circumstances, which is known to be problematic.  See https://v8.dev/blog/math-random for details.
npm WARN deprecated request@2.88.2: request has been deprecated, see https://github.com/request/request/issues/3142
npm WARN deprecated vue-cli@2.9.6: This package has been deprecated in favour of @vue/cli
npm WARN deprecated coffee-script@1.12.7: CoffeeScript on NPM has moved to "coffeescript" (no hyphen)
​
added 244 packages, and audited 246 packages in 1m
​
6 vulnerabilities (3 moderate, 3 high)
​
Some issues need review, and may require choosing
a different dependency.
​
Run `npm audit` for details.
PS D:\企业级Java开发> npm install -g cnpm --registry=https://registry.npm.taobao.org
npm WARN deprecated @npmcli/move-file@2.0.1: This functionality has been moved to @npmcli/fs
​
added 425 packages in 25s
PS D:\企业级Java开发> vue init webpack vue-demo
​
? Project name vue-demo
? Project description A Vue.js project
? Author xiaoshu
? Vue build standalone
? Install vue-router? Yes
? Use ESLint to lint your code? No
? Set up unit tests No
? Setup e2e tests with Nightwatch? No
? Should we run `npm install` for you after the project has been created? (recommended) npm
​
   vue-cli · Generated "vue-demo".
​
​
# Installing project dependencies ...
# ========================
​
npm WARN deprecated stable@0.1.8: Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility
npm WARN deprecated source-map-url@0.4.1: See https://github.com/lydell/source-map-url#deprecated
npm WARN deprecated urix@0.1.0: Please see https://github.com/lydell/urix#deprecated
npm WARN deprecated source-map-resolve@0.5.3: See https://github.com/lydell/source-map-resolve#deprecated
npm WARN deprecated chokidar@2.1.8: Chokidar 2 does not receive security updates since 2019. Upgrade to chokidar 3 with 15x fewer dependencies
npm WARN deprecated chokidar@2.1.8: Chokidar 2 does not receive security updates since 2019. Upgrade to chokidar 3 with 15x fewer dependencies
npm WARN deprecated resolve-url@0.2.1: https://github.com/lydell/resolve-url#deprecated
npm WARN deprecated querystring@0.2.0: The querystring API is considered Legacy. new code should use the URLSearchParams API instead.
npm WARN deprecated acorn-dynamic-import@2.0.2: This is probably built in to whatever tool you're using. If you still need it... idk
npm WARN deprecated uuid@3.4.0: Please upgrade  to version 7 or higher.  Older versions may use Math.random() in certain circumstances, which is known to be problematic.  See https://v8.dev/blog/math-random for details.
npm WARN deprecated flatten@1.0.3: flatten is deprecated in favor of utility frameworks such as lodash.
npm WARN deprecated bfj-node4@5.3.1: Switch to the `bfj` package for fixes and new features!
npm WARN deprecated uglify-es@3.3.9: support for ECMAScript is superseded by `uglify-js` as of v3.13.0
npm WARN deprecated svgo@1.3.2: This SVGO version is no longer supported. Upgrade to v2.x.x.
npm WARN deprecated svgo@0.7.2: This SVGO version is no longer supported. Upgrade to v2.x.x.
npm WARN deprecated core-js@2.6.12: core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js.
npm WARN deprecated browserslist@2.11.3: Browserslist 2 could fail on reading Browserslist >3.0 config used in other tools.
npm WARN deprecated extract-text-webpack-plugin@3.0.2: Deprecated. Please use https://github.com/webpack-contrib/mini-css-extract-plugin
npm WARN deprecated html-webpack-plugin@2.30.1: out of support
npm WARN deprecated browserslist@1.7.7: Browserslist 2 could fail on reading Browserslist >3.0 config used in other tools.
npm WARN deprecated browserslist@1.7.7: Browserslist 2 could fail on reading Browserslist >3.0 config used in other tools.
npm WARN deprecated browserslist@1.7.7: Browserslist 2 could fail on reading Browserslist >3.0 config used in other tools.
​
added 1307 packages, and audited 1308 packages in 3m
​
84 packages are looking for funding
  run `npm fund` for details
​
86 vulnerabilities (1 low, 49 moderate, 29 high, 7 critical)
​
To address issues that do not require attention, run:
  npm audit fix
​
To address all issues (including breaking changes), run:
  npm audit fix --force
​
Run `npm audit` for details.
​
# Project initialization finished!
# ========================
​
To get started:
​
  cd vue-demo
  npm run dev
​
Documentation can be found at https://vuejs-templates.github.io/webpack
​
​
PS D:\企业级Java开发> npm install element-ui -S
​
up to date, audited 20 packages in 1s
​
1 package is looking for funding
  run `npm fund` for details
​
found 0 vulnerabilities
PS D:\企业级Java开发>

安装 element-ui 组件

D:\企业级Java开发\vue-demo>npm i element-ui -S
​
added 6 packages, and audited 1314 packages in 16s
​
84 packages are looking for funding
  run `npm fund` for details
​
86 vulnerabilities (1 low, 49 moderate, 29 high, 7 critical)
​
To address issues that do not require attention, run:
  npm audit fix
​
To address all issues (including breaking changes), run:
  npm audit fix --force
​
Run `npm audit` for details.
​
D:\企业级Java开发\vue-demo>

4.3.4 静态资源的引入

将static文件夹放入public文件夹下

在index.html中引入echarts.js文件

也可以通过如下方式引入:在Vue中引入echarts以及使用_vue引入echart_抗争的小青年的博客-CSDN博客

ps:echarts图表需要设置容器的宽度和高度,不然echarts图表展示不出来
<!DOCTYPE html>
<html lang="">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
    <title><%= htmlWebpackPlugin.options.title %></title>
  </head>
  <body>
    <noscript>
      <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
    </noscript>
    <div id="app"></div>
    <!-- built files will be auto injected -->
​
    <!--一旦通过script标签引入了Echarts.js文件后,就可以通过window.echarts进行全局使用echarts -->
    <script src = "static/lib/echarts.min.js"></script>
  </body>
</html>

在main.js中挂载全局echarts对象

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
​
//将全局的echarts对象挂载到Vue的原型对象上
//在别的组件中怎么使用echarts对象?   this.$echarts
Vue.prototype.$echarts = window.echarts   //$echarts:是一个echarts对象名
​
Vue.config.productionTip = false
​
new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')

axios的封装与挂载

D:\Java Project\vue_study\vision2.0>npm install axios -save --legacy-peer-deps  //安装axios
​
added 6 packages, and audited 1038 packages in 10s
​
found 0 vulnerabilities
​
D:\Java Project\vue_study\vision2.0>
​

在main.js中封装与挂载axios

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import axios from 'axios'  //导入axios
​
//请求基准路径的配置
axios.defaults.baseURL = 'http://127.0.0.1:8888/api/'
//将axios挂载到Vue的原型对象上,在别的组件中使用 this.$http 得到 axios 对象,从而就可以发起ajax的请求
Vue.prototype.$http = axios
​
//将全局的echarts对象挂载到Vue的原型对象上
//在别的组件中怎么使用echarts对象?   this.$echarts
Vue.prototype.$echarts = window.echarts   //$echarts:是一个echarts对象名
​
Vue.config.productionTip = false
​
new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')

进行路由配置

创建src/views/SellerPage.vue

<!--
针对 /sellerPage 这个路径显示出来的
在这个组件中,通过子组件注册的方式,要显示出Seller.vue这个组件
-->
<template>
<div>
  sellerpage组件
</div>
</template>
​
<script>
export default {
  name: 'SellerPage'
}
</script>
​
<style scoped>
​
</style>

创建src/components/Seller.vue

<!--商家销量统计的横向柱状图-->
<template>
​
</template>
​
<script>
export default {
  name: 'Seller.vue'
}
</script>
​
<style scoped>
​
</style>

进行路由配置src/router/index.js

import Vue from 'vue'
import VueRouter from 'vue-router'
import SellerPage from '@/views/SellerPage.vue'  // 引入SellerPage文件
​
Vue.use(VueRouter)
​
const routes = [
  // 配置路由规则
  {
    path: '/sellerpage',
    component: SellerPage
  }
]
​
const router = new VueRouter({
  routes
})
​
export default router

设置路由占位符src/App.vue

<template>
  <div id="app">
    <!--   路由占位符  -->
    <router-view></router-view>
  </div>
</template>
​
<style lang="less">
​
</style>

进行访问http://127.0.0.1:8888/#/sellerpage

进行子组件注册

<!--
针对 /sellerPage 这个路径显示出来的
在这个组件中,通过子组件注册的方式,要显示出Seller.vue这个组件
-->
<template>
<div class="com-page">
  <!--子组件标签-->
  <seller>
​
  </seller>
</div>
</template>
​
<script>
import Seller from '@/components/Seller'  //引入子组件
export default {
  name: 'SellerPage',
  components:{
    seller: Seller     //进行子组件注册:components,seller是变量名
  }
}
</script>
​
<style scoped>
​
</style>

4.3.5 如何在vue文件中引入js文件

  1. 引用echarts默认主题的情况下

  2. 将下载好的主题chalk.js文件放到同级vue文件的static/theme/文件夹下,并修改如下代码,如下图

    //require('echarts/theme/vintage')
    import chalk from "@/components/statisticsAndCharts/static/theme/chalk";
    ...
    //this.chartInstance = this.$echarts.init(this.$refs.deptInfo_ref,"vintage") 
    this.chartInstance = this.$echarts.init(this.$refs.deptInfo_ref,"chalk") 

  3. 看效果(出现如下视图便可说明js导入成功)

4.3.6 主要的代码结构

<template>
<div class="com-container">
  <div class="com-chart" ref="trend_ref">
​
  </div>
</div>
</template>
​
<script>
export default {
  name: 'Trend.vue',
  data(){
    return {
      chartInstance: null,  //创建一个echarts实例对象
      allData: null  //从服务器中获取出来的所有数据
    }
  },
  //生命周期函数
  mounted () {
    this.initCharts()
    this.getData()
    window.addEventListener('resize',this.screenAdapter)  //进行对窗口事件进行监听
    this.screenAdapter()  //主动的进行窗口大小的计算
  },
  destroyed () {
    window.removeEventListener('resize',this.screenAdapter)  //将事件取消监听
  },
  methods:{
    //初始化echarts实例对象的方法
    initCharts () {
      this.chartInstance = this.$echarts.init(this.$refs.trend_ref)
      const initOption = {
​
      }
      this.chartInstance.setOption(initOption)
    },
    async getData(){
      //await this.$http.get()
      //对allData进行赋值
      this.updateCharts()
    },
    updateCharts () {
      //处理数据
      const dataOption = {
​
      }
      this.chartInstance.setOption(dataOption)
    },
    screenAdapter () {
      const adapterOption = {
​
      }
      this.chartInstance.setOption(adapterOption)
      this.chartInstance.resize()
    }
  }
}
</script>
​
<style scoped>
​
</style>

4.3.7 基于vue获取json文件数据

文件物理路径

获取路径:http://127.0.0.1:9999/static/map/china.json

4.3.8 js相关

js中字符串使用‘’和“”有什么区别?

在 JavaScript 中,字符串可以用单引号('')或双引号("")来表示。在大多数情况下,这两种方式是等效的,但是它们在一些细节上是不同的。

其中一个主要区别是,如果你在字符串中使用了单引号,则需要使用双引号来将该字符串括起来,反之亦然。例如:

var str1 = 'It\'s a nice day.'; // 使用单引号包含字符串,需要使用转义符号来转义单引号
var str2 = "He said \"hello\"."; // 使用双引号包含字符串,需要使用转义符号来转义双引号

另一个区别是,当字符串本身包含单引号或双引号时,需要使用相反的引号来避免语法错误。例如:

var str1 = "It's a nice day."; // 使用双引号包含字符串,避免了使用转义符号
var str2 = 'He said "hello".'; // 使用单引号包含字符串,避免了使用转义符号

总的来说,单引号和双引号在大多数情况下是可以互换的,但在某些情况下,需要选择正确的引号以避免语法错误。

4.3.9 不使用WebSocket的agePage

<template>
  <div class="com-container">
    <!--    hot-->
    <div class="com-chart" ref="age_ref"></div>
    <!-- 向左的箭头 :style:绑定方法  -->
    <span class="iconfont arr-left" @click="toLeft" :style="comStyle">&#xe6ef;</span>
    <!-- 向右的箭头   -->
    <span class="iconfont arr-right" @click="toRight" :style="comStyle">&#xe6ed;</span>
    <span class="title-name" :style="comStyle">{{ titleName }}年龄分布</span>
  </div>
</template>
​
<script>
import {getData} from "@/api/system/dict/data";
​
export default {
  name: 'AgePage',
  data(){
    return {
      chartInstance: null,  //创建一个echarts实例对象
      allData: null,  //从服务器中获取出来的所有数据
      currentIndex: 0,  //当前所展示出的一级分类数据
      titleFontSize: 0
    }
  },
  //计算属性
  computed: {
    titleName (){
      if(!this.allData){
        return ''
      }else {
        return this.allData[this.currentIndex].name
      }
    },
    comStyle() {
      return {
        fontSize: this.titleFontSize / 3 + 'px'
      }
    }
  },
  //生命周期函数(带括号的是函数,不带括号的是属性),页面从这里开始一步步加载
  mounted () {
    this.initCharts()
    this.getData()
    window.addEventListener('resize',this.screenAdapter)  //进行对窗口事件进行监听
    this.screenAdapter()  //主动的进行窗口大小的计算
  },
  destroyed () {
    window.removeEventListener('resize',this.screenAdapter)  //将事件取消监听
  },
  methods:{
    //初始化echarts实例对象的方法
    initCharts () {
      this.chartInstance = this.$echarts.init(this.$refs.age_ref,'chalk')
      const initOption = {
        title:{
          text: '▎各部门教职工年龄分布',
          left: 20,
          top: 20
        },
        legend: {
          top: '10%',
          icon: 'circle'
        },
        tooltip:{
          show: true,
          formatter: arg=>{
            //console.log(arg)
            return "年龄段:" + arg.name+"<br/>人数:" + arg.value + "<br/>占比:" + arg.percent+"%"
          }
        },
        series: [
          {
            type: 'pie',
            //标签
            label:{
              show: false //不显示标签
            },
            //高亮状态显示文字
            emphasis:{
              label: {
                show: true
              },
              labelLine:{
                show: false
              }
            }
          }
        ]
      }
      this.chartInstance.setOption(initOption)
    },
    async getData(){
      //await this.$http.get()
      const {data: ret}= await this.$http.get('age')
      this.allData = ret
      console.log(this.allData)
      //对allData进行赋值
      this.updateCharts()
    },
    updateCharts () {
      //const legendData = this.allData[0].children.map(item =>{
      const legendData = this.allData[this.currentIndex].children.map(item =>{
          return {
            name: item.name
          }
      })
      //this.allData[0]  一级分类   this.allData[0].children  二级分类
      //const seriesData = this.allData[0].children.map(item =>{
      const seriesData = this.allData[this.currentIndex].children.map(item =>{
        return {
          name: item.name,
          value: item.value
        }
      })
      console.log(seriesData)
      //处理数据
      const dataOption = {
        legend: {
          data: legendData
        },
        series:[
          {
            data: seriesData
          }
        ],
      }
      this.chartInstance.setOption(dataOption)
    },
    screenAdapter () {
      this.titleFontSize = this.$refs.age_ref.offsetWidth / 100 * 3.6
      const adapterOption = {
        //控制标题的大小
        title:{
          textStyle:{
            fontSize: this.titleFontSize / 2
          }
        },
        //控制图例的大小
        legend:{
          itemWidth: this.titleFontSize / 2,
          itemHeight: this.titleFontSize / 2,
          itemGap:  this.titleFontSize / 2,
          textStyle: {
            fontSize: this.titleFontSize / 2
          }
        },
        //控制饼图的大小,饼图的大小是通过半径来控制的
        series:[
          {
            radius: this.titleFontSize * 3,  //控制饼图的大小
            center: ['50%','50%']  //['50%','50%'] --> ['X轴位置百分比','Y轴位置百分比']:将饼图的圆心放在界面的正中心
          }
        ]
      }
      this.chartInstance.setOption(adapterOption)
      this.chartInstance.resize()
    },
    toLeft(){
      this.currentIndex--
      if(this.currentIndex < 0){
        this.currentIndex = this.allData.length-1
      }
      this.updateCharts()
    },
    toRight(){
      this.currentIndex++
      if(this.currentIndex > this.allData.length-1){
        this.currentIndex = 0
      }
      this.updateCharts()
    }
  }
}
</script>
​
<style scoped>
.arr-left{
  position: absolute;  /*绝对定位:https://www.runoob.com/w3cnote/css-position-static-relative-absolute-fixed.html*/
  left: 10%;
  top: 50%;
  transform: translateY(-50%);
  cursor: pointer;  /*鼠标移入样式*/
  color: white;
}
.arr-right{
  position: absolute;  /*绝对定位:https://www.runoob.com/w3cnote/css-position-static-relative-absolute-fixed.html*/
  right: 10%;
  top: 50%;
  transform: translateY(-50%);
  cursor: pointer; /*鼠标移入样式*/
  color: white;
}
.title-name{
  position: absolute;  /*不会占容器的位置*/
  left: 80%;
  top: 20px;
  color: white;
}
</style>

4.3.10 使用WebSocket的agePage

<template>
  <div class="com-container">
    <!--    hot-->
    <div class="com-chart" ref="age_ref"></div>
    <!-- 向左的箭头 :style:绑定方法  -->
    <span class="iconfont arr-left" @click="toLeft" :style="comStyle">&#xe6ef;</span>
    <!-- 向右的箭头   -->
    <span class="iconfont arr-right" @click="toRight" :style="comStyle">&#xe6ed;</span>
    <span class="title-name" :style="comStyle">{{ titleName }}年龄分布</span>
  </div>
</template>
​
<script>
import {getData} from "@/api/system/dict/data";
​
export default {
  name: 'AgePage',
  data(){
    return {
      chartInstance: null,  //创建一个echarts实例对象
      allData: null,  //从服务器中获取出来的所有数据
      currentIndex: 0,  //当前所展示出的一级分类数据
      titleFontSize: 0
    }
  },
  //计算属性
  computed: {
    titleName (){
      if(!this.allData){
        return ''
      }else {
        return this.allData[this.currentIndex].name
      }
    },
    comStyle() {
      return {
        fontSize: this.titleFontSize / 3 + 'px'
      }
    }
  },
  created() {
    //在组件创建完成之后 进行回调函数的注册
    this.$socket.registerCallBack('ageData',this.getData)
  },
  //生命周期函数(带括号的是函数,不带括号的是属性),页面从这里开始一步步加载
  mounted () {
    this.initCharts()
    //this.getData()
    //发送数据给服务器,告诉服务器现在需要数据
    this.$socket.send({
      action: 'getData',
      socketType: 'ageData',
      chartName: 'age',
      value: ''
    })
    window.addEventListener('resize',this.screenAdapter)  //进行对窗口事件进行监听
    this.screenAdapter()  //主动的进行窗口大小的计算
  },
  destroyed () {
    window.removeEventListener('resize',this.screenAdapter)  //将事件取消监听
    //在组件销毁的时候 进行回调函数的取消
    this.$socket.unRegisterCallBack('ageData')
  },
  methods:{
    //初始化echarts实例对象的方法
    initCharts () {
      this.chartInstance = this.$echarts.init(this.$refs.age_ref,'chalk')
      const initOption = {
        title:{
          text: '▎各部门教职工年龄分布',
          left: 20,
          top: 20
        },
        legend: {
          top: '10%',
          icon: 'circle'
        },
        tooltip:{
          show: true,
          formatter: arg=>{
            //console.log(arg)
            return "年龄段:" + arg.name+"<br/>人数:" + arg.value + "<br/>占比:" + arg.percent+"%"
          }
        },
        series: [
          {
            type: 'pie',
            //标签
            label:{
              show: false //不显示标签
            },
            //高亮状态显示文字
            emphasis:{
              label: {
                show: true
              },
              labelLine:{
                show: false
              }
            }
          }
        ]
      }
      this.chartInstance.setOption(initOption)
    },
    // ret 就是服务端发送给客户端的图表的数据
    getData(ret){
      //await this.$http.get()
      //const {data: ret}= await this.$http.get('age')
      this.allData = ret
      console.log(this.allData)
      //对allData进行赋值
      this.updateCharts()
    },
    updateCharts () {
      //const legendData = this.allData[0].children.map(item =>{
      const legendData = this.allData[this.currentIndex].children.map(item =>{
          return {
            name: item.name
          }
      })
      //this.allData[0]  一级分类   this.allData[0].children  二级分类
      //const seriesData = this.allData[0].children.map(item =>{
      const seriesData = this.allData[this.currentIndex].children.map(item =>{
        return {
          name: item.name,
          value: item.value
        }
      })
      console.log(seriesData)
      //处理数据
      const dataOption = {
        legend: {
          data: legendData
        },
        series:[
          {
            data: seriesData
          }
        ],
      }
      this.chartInstance.setOption(dataOption)
    },
    screenAdapter () {
      this.titleFontSize = this.$refs.age_ref.offsetWidth / 100 * 3.6
      const adapterOption = {
        //控制标题的大小
        title:{
          textStyle:{
            fontSize: this.titleFontSize
          }
        },
        //控制图例的大小
        legend:{
          itemWidth: this.titleFontSize ,
          itemHeight: this.titleFontSize ,
          itemGap:  this.titleFontSize ,
          textStyle: {
            fontSize: this.titleFontSize
          }
        },
        //控制饼图的大小,饼图的大小是通过半径来控制的
        series:[
          {
            radius: this.titleFontSize * 6,  //控制饼图的大小
            center: ['50%','50%']  //['50%','50%'] --> ['X轴位置百分比','Y轴位置百分比']:将饼图的圆心放在界面的正中心
          }
        ]
      }
      this.chartInstance.setOption(adapterOption)
      this.chartInstance.resize()
    },
    toLeft(){
      this.currentIndex--
      if(this.currentIndex < 0){
        this.currentIndex = this.allData.length-1
      }
      this.updateCharts()
    },
    toRight(){
      this.currentIndex++
      if(this.currentIndex > this.allData.length-1){
        this.currentIndex = 0
      }
      this.updateCharts()
    }
  }
}
</script>
​
<style scoped>
.arr-left{
  position: absolute;  /*绝对定位:https://www.runoob.com/w3cnote/css-position-static-relative-absolute-fixed.html*/
  left: 10%;
  top: 50%;
  transform: translateY(-50%);
  cursor: pointer;  /*鼠标移入样式*/
  color: white;
}
.arr-right{
  position: absolute;  /*绝对定位:https://www.runoob.com/w3cnote/css-position-static-relative-absolute-fixed.html*/
  right: 10%;
  top: 50%;
  transform: translateY(-50%);
  cursor: pointer; /*鼠标移入样式*/
  color: white;
}
.title-name{
  position: absolute;  /*不会占容器的位置*/
  left: 80%;
  top: 20px;
  color: white;
}
</style>

4.3.11使用vue生成一个在线天气预报

要使用Vue生成一个在线天气预报,需要先获取天气数据,并使用Vue将其呈现在用户界面上。以下是一些基本的步骤:

  1. 获取天气数据:使用一个天气API(例如OpenWeatherMap或Weather Underground)来获取天气数据。这些API通常需要您注册并获得一个API密钥。

  2. 创建Vue应用程序:创建一个Vue应用程序,并将其连接到您的HTML和CSS。

  3. 获取和处理天气数据:使用Vue的生命周期钩子,在Vue实例创建时,使用Ajax或Fetch等方法从API中获取天气数据。然后,将天气数据保存到Vue组件的状态中,并使用计算属性处理数据以便呈现到用户界面上。

  4. 呈现数据:在Vue组件的模板中,使用Vue指令和插值表达式来呈现天气数据。您可以使用HTML和CSS来设计和样式化您的天气预报。

下面是一个简单的Vue组件,它获取并呈现天气数据:

phpCopy code<template>
  <div>
    <h1>{{ city }}</h1>
    <h2>{{ weather }}</h2>
    <img :src="iconUrl" alt="weather icon">
    <p>{{ temperature }} &deg;{{ units }}</p>
  </div>
</template>
​
<script>
export default {
  data() {
    return {
      city: "",
      weather: "",
      temperature: "",
      icon: "",
      units: "C"
    };
  },
  created() {
    fetch(`https://api.openweathermap.org/data/2.5/weather?q=${this.city}&appid=<your api key>`)
      .then(response => response.json())
      .then(data => {
        this.weather = data.weather[0].description;
        this.temperature = Math.round(data.main.temp - 273.15);
        this.icon = data.weather[0].icon;
      });
  },
  computed: {
    iconUrl() {
      return `http://openweathermap.org/img/wn/${this.icon}.png`;
    }
  }
};
</script>
​
<style>
​
</style>

在这个组件中,我们通过在created()生命周期钩子中使用Fetch API来获取天气数据。然后,我们将数据存储在组件的状态中,并使用计算属性来获取天气图标的URL。最后,我们在模板中使用Vue指令和插值表达式来呈现天气数据。

请注意,在上面的代码示例中,您需要将<your api key>替换为您在OpenWeatherMap上获得的API密钥,并且还需要为city属性提供一个值。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

百度智能云对象存储BOS批量下载文件方法

百度智能云对象存储BOS支持批量打包下载吗&#xff1f;目前对象存储BOS浏览器端不支持批量下载&#xff0c;可以使用对象存储BOS桌面或BOSCMD批量下载&#xff0c;也可以使用API/SDK调用接口循环下载。新手站长网来详细说下百度云对象存储BOS批量下载的方法&#xff1a; 目录 …

Git 分布式版本控制工具

文章目录 Git 分布式版本控制工具课程内容1. 前言1.1 什么是Git1.2 使用Git能做什么 2. Git概述2.1 Git简介2.2 Git下载与安装 TODO3. Git代码托管服务3.1 常用的Git代码托管服务3.2 码云代码托管服务3.2.1 注册码云账号3.2.2 登录码云3.2.3 创建远程仓库3.2.4 邀请其他用户成为…

c++小知识

1、一般头文件&#xff1a; #include<iostream> using namespace std; 2、ios::sync_with_stdio(false); 其含义是取消cin与stdin的同步&#xff0c;cout和stdout的同步 cin.tie(0); tie是将两个stream绑定的函数&#xff0c;空参数的话返回当前的输出流指针。 3、…

为什么网络安全缺口很大,招聘却很少?

2020年我国网络空间安全人才数量缺口超过了140万&#xff0c;就业人数却只有10多万&#xff0c;缺口高达了93%。这里就有人会问了&#xff1a; 1、网络安全行业为什么这么缺人&#xff1f; 2、明明人才那么稀缺&#xff0c;为什么招聘时招安全的人员却没有那么多呢&#xff1…

给想涨薪和正在学习Android的朋友们一些建议

前言 相信很多从事Android开发工作的朋友&#xff0c;在入职一年后会有申请涨薪的想法&#xff0c;但由于某些原因&#xff0c;公司拒绝了您的加薪申请&#xff0c;在我看来&#xff0c;出现这种情况主要有两种原因&#xff1a;第一个原因可能是你在工作中就只知道埋头苦干&am…

手撕Udp套接字|实现群聊通信|实现Windows Linux通信交互

​ 专栏和Git地址 操作系统https://blog.csdn.net/yu_cblog/category_12165502.html?spm1001.2014.3001.5482UdpSockethttps://github.com/Yufccode/BitCode/tree/main/Linux/%E4%BB%A3%E7%A0%81/0215Udp%E5%A5%97%E6%8E%A5%E5%AD%97 README 本项目通过Linux套接字编程&…

如何选择CDN厂商

如果您的在线业务面临着流量和访客数量的增加&#xff0c;如果您想提高网站速度和用户体验&#xff0c;选择合适的CDN提供商是朝着正确方向迈出的一步&#xff0c;那么如何来选择最合适的CDN厂商呢&#xff0c;火伞云小编今天为您解答&#xff1a; 一、测试潜在的CDN提供商 对…

Python实现批量图片下载及去重处理

背景 在爬虫应用开发中&#xff0c;常常需要批量下载图片&#xff0c;并对图片进行去重处理。Python 是一种非常流行的编程语言&#xff0c;也是开发爬虫应用的首选&#xff0c;本文将介绍如何使用 Python 下载图片&#xff0c;并对下载的图片进行去重处理。 内容 首先&…

OpenText 企业内容管理平台介绍

OpenText 企业内容管理平台介绍 将 ECM 扩展到领先的业务应用程序中&#xff0c;为内容添加上下文&#xff0c;从而提高效率和决策能力 突出优点&#xff1a; 1、企业拥有更多数据、更多来源、更多用途并按需提供 2、员工需要一种新的交互、共享和消费内容的方式 3、更多内容需…

Linux -- Web服务器-Apache 快速安装及主配置文件分析

目录 快速安装 Apache : 预处理 &#xff1a; 关闭安全上下文检测 : 关闭防火墙 : 启动 Apache 服务 &#xff08; 启动 httpd &#xff09;: 测试 &#xff1a; 主配置文件分析 &#xff1a; 常见配置文件所在位置 &#xff1a; 目录文件结构 &#xff1a;…

云原生时代,不可不知的基础设施即代码(IaC)

&#x1f4a1; IaC 是 DevOps 的必要支撑。 近日&#xff0c;在极狐TechTalk 直播上&#xff0c;极狐(GitLab) 高级网站可靠性工程师SRE 戚加欣&#xff0c;从 SRE 视角出发&#xff0c;与大家分享了 IaC 基础知识、工具和方法和基于极狐GitLab 的具体实践经验。 以下内容整理自…

ubuntu输入法问题汇总

Xfce4桌面环境输入法 Ubuntu20.04、ubuntu21.04中安装xfce4桌面环境&#xff0c;自带中文输入法&#xff1b; 原生xubuntu20.04中文输入法问题解决办法&#xff1a; 更新语言支持失败的话&#xff0c;终端键入&#xff1a;sudo apt-get install cmake qt5-default qtcreator…

Node【四】内置模块 【fs模块】

文章目录 &#x1f31f;前言&#x1f31f;fs模块&#x1f31f; 使用fs模块&#x1f31f; 异步编程和同步编程&#x1f31f; 异步编程&#x1f31f; 同步编程 &#x1f31f;常用操作&#x1f31f; 文件操作&#x1f31f; readFile异步读取文件&#x1f31f; readFileSync同步读取…

【智能电网】智能电网中针对DOS和FDIA的弹性分布式EMA(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

【C语言学习3——基本的C语言语法知识1】

C语言学习3——基本的C语言语法知识 主函数什么是主函数&#xff1f;写一个自己的函数主函数是整个C语言程序的入口要调用函数&#xff0c;必须先知道函数什么是变量&#xff1f; #include <stdio.h> int main() { printf("Hello World\n"); return 0; }相信你…

SpringMVC的入门案例

三层架构和mvc 三层架构&#xff1a; 我们的开发架构一般都是基于两种形式&#xff0c;一种是C/S 架构&#xff0c;也就是客户端/服务器&#xff0c;另一种是 B/S 架构&#xff0c;也就是测览器服务器。在 avaEE开发中&#xff0c;几乎全都是基于 B/S 架构的开发。那么在 B/S…

Java语言数据类型与c语言数据类型的不同

目录 一、c语言数据类型 1.基本类型&#xff1a; 2.枚举类型&#xff1a; 3.空类型&#xff1a; 4.派生类型&#xff1a; 二、C语言编程需要注意的64位和32机器的区别 三、 不同之处 一、c语言数据类型 首先&#xff0c;先来整体介绍一下C语言的数据类型分类。 1.基…

创新,阿里首发微服务实施手册我粉了,原来微服务还可以这样玩

微服务 相信大家在网上会看到很多帖子把分布式跟微服务放在一起讨论。确实&#xff0c;微服务就是一种分布式架构的设计方法。但是&#xff0c;在微服务概念还没有出现之前&#xff0c;分布式这个概念并不能引起人们的强烈关注&#xff0c;如果说自己擅长分布式架构设计&#…

使用SeaFile搭建私有云盘并公网访问【cpolar内网穿透】

文章目录 1. 前言2. SeaFile云盘设置2.1 Owncould的安装环境设置2.2 SeaFile下载安装2.3 SeaFile的配置 3. cpolar内网穿透3.1 Cpolar下载安装3.2 Cpolar的注册3.3 Cpolar云端设置3.4 Cpolar本地设置 4. 公网访问测试5. 结语 1. 前言 现在我们身边的只能设备越来越多&#xff…

面试官:String s = new String(“xyz“) 创建了几个对象?

这个问题相信每个学习 java 的同学都不陌生&#xff0c;作为一个经典的面试题&#xff0c;到现在工作这么多年了我真是认为挺操蛋的一个问题&#xff0c;在网上到现在你仍然可以看见很多讨论这个问题的人&#xff0c;其中不乏工作很多年的人都有争论&#xff0c;我认为还是有必…