项目难点和优化

难点: 对于同一个位置百度地图定位的经纬度和腾讯地图定位的经纬度不一样?

解决:由于两者所用的算法不同,计算出来的经纬度也是不一样的,将百度地图的经纬度转换成腾讯地图的经纬度/腾讯的经纬度转化百度的经纬度
export function  bMapTransQQMap(lng,lat){
        let x_pi = 3.14159265358979324 * 3000.0 / 180.0;
        let x = lng - 0.0065;
        let y = lat - 0.006;
        let z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_pi);
        let theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_pi);
        let lngs = z * Math.cos(theta);
        let lats = z * Math.sin(theta);
        return {
            longitude: lngs,
            latitude: lats
        }
 }
// 腾讯转百度
export function qqMapTransBMap(lng,lat){
        let x_pi = 3.14159265358979324 * 3000.0 / 180.0;
        let x = lng;
        let y = lat;
        let z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * x_pi);
        let theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * x_pi);
        let lngs = z * Math.cos(theta) + 0.0065;
        let lats = z * Math.sin(theta) + 0.006;
        return {
            longitude: lngs,
            latitude: lats
        }
}

难点 : 移动端使用echarts绘制图表使用tooltip无效果

解决:

echarts 引入的时候,会优先判断当前的环境。

uniapp的又一个全局变量就叫做wx。
导致这里的判断直接走第一个。

在main.js中

window.wx = {}  直接将wx重新赋值。

难点:echarts中的面积图,由于点击区域、折线、折线中的小圆点都会出现提示框,只有点击折线上的点才出现tooltip(提示框),

解决:通过监听echart的鼠标的mouseover事件,函数中设置某个全局变量为当前折线的seriesName(名字),然后再监听鼠标的mouseout事件,函数中设置某个全局变量为空字符串,这两个事件只有直线上的小圆点才执行的,所以可以区分区域点击事件和折线点击事件,之后在提示框的自定义内容中(formatter),如果存在某个全局变量就显示提示框,否则不显示。

难点:在线上,使用window.open方法无法实现下载功能

解决:

webpack构建优化

webpack构建优化

构建前: 编译速度:2.69m

​ 构建速度 :第一次构建速度: 59.93,

​ cache-loader: 默认脚手架使用了cache-loader进行缓存,第二次的构建速度: 39.84 ,构建速度提升了33%

​ 为 loader 指定 include,减少 loader 应用范围,仅应用于最少数量的必要模块,。rule.exclude 可以排除模块范围,也可用于减少 loader 应用范围.

​ thread-loader多线程:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

第一次编译:177 第二次编译: 75 热更新:15

在优化开始之前,需要做一些准备工作。

安装以下 webpack 插件,帮助我们分析优化效率:

1. 编译进度条

一般来说,中型项目的首次编译时间为 5-20s,没个进度条等得多着急,通过 progress-bar-webpack-plugin 插件查看编译进度,方便我们掌握编译情况。

安装:

npm i -D progress-bar-webpack-plugin

vue.config.js 配置如下

const chalk = require('chalk')
const ProgressBarPlugin = require('progress-bar-webpack-plugin')
 configureWebpack: config => {
      config.plugins.push(new ProgressBarPlugin({
      format: `  :msg [:bar] ${chalk.green.bold(':percent')} (:elapsed s)`
    }))
 }

2. 编译速度分析

优化 webpack 构建速度,首先需要知道是哪些插件、哪些 loader 耗时长,方便我们针对性的优化。

通过 speed-measure-webpack-plugin 插件进行构建速度分析,可以看到各个 loader、plugin 的构建时长,后续可针对耗时 loader、plugin 进行优化。

安装:

npm i -D speed-measure-webpack-plugin

vue.config.js 配置如下

const SpeedMeasurePlugin = require("speed-measure-webpack-plugin")
 configureWebpack: config => {
      config.plugins.push(new ProgressBarPlugin({
      format: `  :msg [:bar] ${chalk.green.bold(':percent')} (:elapsed s)`
    }), new SpeedMeasurePlugin())
 }

3. 打包体积分析

build 构建打包命令加入 --report inspect命令生成一份vue-cli 内置的配置内容

  "scripts": {
    "build": "vue-cli-service build --report",
    "inspect": "vue-cli-service inspect --> output.js"
  },

4. 查看vue.config.js 的输出后的所有配置

  "scripts": {
    "inspect": "vue-cli-service inspect --> output.js"
  },

第一次编译:219s ,第二次编译:72s

加入配置config.resolve.modules 使用绝对路径指明第三方模块存放的位置,以减少搜索步骤 extensions缩小查找后缀的范围

 configureWebpack: config => {
      // 使用绝对路径指明第三方模块存放的位置,以减少搜索步骤
    // __diename 表示当前工作目录,也就是项目根目录
    config.resolve.modules.unshift(resolve('node_modules'))
    config.resolve.extensions = ['.js', '.vue', '.json']
  },

构建完成:第一次编译:173s 153s 第二次编译:65s

加入配置 **config.module.noParse = /^(vue|vue-router|vuex|vuex-router-sync|jquery|lodash|chartjs|echarts)$/ ** 防止 webpack 解析那些任何与给定正则表达式相匹配的文件。忽略的文件中 不应该含有 import, require, define 的调用,或任何其他导入机制。忽略大型的 library 可以提高构建性能。

 configureWebpack: config => {
        // 使用绝对路径指明第三方模块存放的位置,以减少搜索步骤
    // __diename 表示当前工作目录,也就是项目根目录
    config.resolve.modules.unshift(resolve('node_modules'))
    config.resolve.extensions = ['.js', '.vue', '.json']
     // 防止 webpack 解析那些任何与给定正则表达式相匹配的文件。忽略的文件中 
    // 不应该含有 import, require, define 的调用,或任何其他导入机制。忽略大型的 library 可以提高构建性能。
    config.module.noParse = /^(vue|vue-router|vuex|vuex-router-sync|lodash)$/
  },

构建完成:第一次编译:155s 第二次编译:64

加入thread-loader —— 开启多线程优化配置,对于编译时间过长的loader加入thread-loader,

注意:仅在耗时的操作中使用 thread-loader,否则使用 thread-loader 会后可能会导致项目构建时间变得更长,因为每个 worker 都是一个独立的 node.js 进程,其开销大约为 600ms 左右,同时还会限制跨进程的数据交换等。

 configureWebpack: config => {
      // 对babel-loader 使用thread-loader
    config.module.rules[12].use.unshift({
      loader: 'thread-loader',
      options: {
        workers: 3 // 进程3个
      }
    })
    config.module.rules[15].use.unshift({
      loader: 'thread-loader',
      options: {
        workers: 3 // 进程3个
      }
    })
 }
  chainWebpack: config => { 
  	 config.module
      .rule('markdown')
      .test(/\.md$/)
      .use('loader1')
        .loader('loader1') // 第一个 Loader
        .end()
      .use('loader2')
        .loader('loader2') // 第二个 Loader
        .options({ /* Loader 的选项 */ })
        .end()
      .use('loader3')
        .loader('loader3') // 第三个 Loader
        .end();
  }

构建完成:第一次编译:151s 第二次编译:62s

IgnorePlugin

webpack 的内置插件,作用是忽略第三方包指定目录。

例如: moment (2.24.0版本) 会将所有本地化内容和核心功能一起打包,我们就可以使用 IgnorePlugin 在打包时忽略本地化内容。

//webpack.config.js
module.exports = {
    //...
    plugins: [
        //忽略 moment 下的 ./locale 目录
        new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/)
    ]
}

在使用的时候,如果我们需要指定语言,那么需要我们手动的去引入语言包,例如,引入中文语言包:

import moment from 'moment';
import 'moment/locale/zh-cn';// 手动引入

index.js 中只引入 moment,打包出来的 bundle.js 大小为 263KB,如果配置了 IgnorePlugin,单独引入 moment/locale/zh-cn,构建出来的包大小为 55KB

externals

我们可以将一些JS文件存储在 CDN 上(减少 Webpack打包出来的 js 体积),在 index.html 中通过 <script> 标签引入,如:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <div id="root">root</div>
    <script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
</body>
</html>

我们希望在使用时,仍然可以通过 import 的方式去引用(如 import $ from 'jquery'),并且希望 webpack 不会对其进行打包,此时就可以配置 externals

//webpack.config.js
module.exports = {
    //...
    externals: {
        //jquery通过script引入之后,全局中即有了 jQuery 变量
        'jquery': 'jQuery'
    }
}

构建完成: 226s 186s 代码体积减少50%,文件数量减少40%

性能优化

性能分析工具:chrome-Lighthouse

分数:25

Eliminate render-blocking resources: 消除渲染阻塞资源

​ 优化前:1.7s

​ 优化后:0s

​ 优化css样式:异步加载css:1、js动态加载css 2、rel=“preload”

 <link type="text/css" rel="preload" href="<%= BASE_URL %>tinymce/skins/lightgray/skin.min.css"/>

​ 优化js:babel-polyfill插件是开发环境才需要,不需要在生产环境上使用,去除掉babel-polyfill的引入,如需引入可异步加载js

splitChunk: 对代码进行分割,合并公用代码块,对第三方库分别独立打包,减少下载次数,合并零散的文件,减少http请求

压缩图片的体积

开启http2请求

开启gzip压缩

分数:57

const path = require('path')
const CompressionPlugin = require('compression-webpack-plugin')

function resolve(dir) {
  return path.join(__dirname, dir)
}

// vue.config.js
module.exports = {
  /*
    Vue-cli3:
    Crashed when using Webpack `import()` #2463
    https://github.com/vuejs/vue-cli/issues/2463
   */
  // 如果你不需要生产环境的 source map,可以将其设置为 false 以加速生产环境构建。
  productionSourceMap: false,
  //qiankuan打包时放开
  //outputDir: "../dist/main",
  // 多入口配置
  // pages: {
  //   index: {
  //     entry: 'src/main.js',
  //     template: 'public/index.html',
  //     filename: 'index.html',
  //   }
  // },
  //打包app时放开该配置
  publicPath: '/health-archives-ui',
  configureWebpack: config => {
    //生产环境取消 console.log
    // if (process.env.NODE_ENV === 'production') {
    //   config.optimization.minimizer[0].options.terserOptions.compress.drop_console = true
    // }
    config.optimization = {
      splitChunks: {
        chunks: 'all',
        minSize: 0,
        minChunks: 1,
        cacheGroups: {
          vendors: {
            name: 'chunk-vendors',
            test: /[\\/]node_modules[\\/]/,
            priority: -10,
            reuseExistingChunk: true,
            chunks: 'all'
          },
          common: {
            name: 'chunk-common',
            minChunks: 2,
            priority: -20,
            reuseExistingChunk: true,
            chunks: 'all'
          },
          elementUI: {
            name: 'chunk-elementUI',
            priority: 20, // initial the weight needs to be larger than libs and app or it will be packaged into libs or app
            test: /[\\/]node_modules[\\/]_?element-ui(.*)/, // in order to adapt to cnpm
            chunks: 'all'
          },
          echarts: {
            name: 'chunk-echarts',
            priority: 20,
            test: /[\\/]node_modules[\\/]_?echarts(.*)/,
            chunks: 'all'
          }
          // moment: {
          //   priority: 20,
          //   test: /[\\/]node_modules[\\/]_?moment(.*)/,
          //   reuseExistingChunk: true
          // }
        }
      }
    }
  },
  chainWebpack: config => {
    config.resolve.alias
      .set('@$', resolve('src'))
      .set('@api', resolve('src/api'))
      .set('@assets', resolve('src/assets'))
      .set('@comp', resolve('src/components'))
      .set('@views', resolve('src/views'))

    //生产环境,开启js\css压缩
    if (process.env.NODE_ENV === 'production') {
      config.plugin('compressionPlugin').use(
        new CompressionPlugin({
          test: /\.(js|css|less)$/, // 匹配文件名
          threshold: 10240, // 对超过10k的数据压缩
          deleteOriginalAssets: false // 不删除源文件
        })
      )
    }

    // 配置 webpack 识别 markdown 为普通的文件
    config.module
      .rule('markdown')
      .test(/\.md$/)
      .use()
      .loader('file-loader')
      .end()

    // 编译vxe-table包里的es6代码,解决IE11兼容问题
    config.module
      .rule('vxe')
      .test(/\.js$/)
      .include.add(resolve('node_modules/vxe-table'))
      .add(resolve('node_modules/vxe-table-plugin-antd'))
      .end()
      .use()
      .loader('babel-loader')
      .end()
  },

  css: {
    loaderOptions: {
      less: {
        modifyVars: {
          /* less 变量覆盖,用于自定义 ant design 主题 */
          'primary-color': '#1890FF',
          'link-color': '#1890FF',
          'border-radius-base': '4px'
        },
        javascriptEnabled: true
      }
    }
  },

  devServer: {
    port: 3000,
    // hot: true,
    // disableHostCheck: true,
    // overlay: {
    //     warnings: false,
    //     errors: true,
    // },
    // headers: {
    //     'Access-Control-Allow-Origin': '*',
    // },
    proxy: {
      /* '/api': {
        target: 'https://mock.ihx.me/mock/5baf3052f7da7e07e04a5116/antd-pro', //mock API接口系统
        ws: false,
        changeOrigin: true,
        pathRewrite: {
          '/jeecg-boot': ''  //默认所有请求都加了jeecg-boot前缀,需要去掉
        }
      },*/
      '/jeecg-boot': {
        target: 'http://localhost:8080', //请求本地 需要jeecg-boot后台项目
        ws: false,
        changeOrigin: true
      }
    }
  },

  lintOnSave: undefined
}

图片水印

​ 图片如何添加水印步骤:1、选择图片,2、创建canvas对象,ctx.drawImage把图片放入到canvas中,3、设置水印的位置、大小、颜色,4、执行ctx.draw()方 法在回调函数中将执行canvas.canvasToTempFilePath()方法,canvas转换成图片,5、将生成的图片上传到服务器并回显图片

问题:选择多个图片后只上传了一张图片? 原因:遍历多张图片的时间快于canvas.draw回调方法执行时间,canvas.draw回调函数只执行了一次,导致只能上传一张图片

解决:通过使用promise方式解决,在循环中使用promise,promise回调函数执行canvas.draw方法,只有执行完第一次的promise回调函数改变了状态,才会执行第二次的promise,因此canvas.draw方法也会执行多次,就可以上传多个图片了。

  for (let item of that.data.imgList) {
	// 循环遍历promise
   const data = await this.getCanvasImg(item)

   this.uploadFile(data); 

  }

	getCanvasImg(item) {
			const that = this
			return new Promise((resolve, reject) => {
				console.log(245);
				let ctx = that.data.ctx
				console.log("获取图片详情", ctx)
				//将图片src放到cancas内,宽高为图片大小
				ctx.drawImage(item, 0, 0, 375, 375)
				//将声明的时间放入canvas
				ctx.setFontSize(18) //注意:设置文字大小必须放在填充文字之前,否则不生效
				// 添加水印
				// 日期时间 
				const watermar = that.data.watermarks
				watermar[0].text = getTime()

				for (let index = 0; index < watermar.length; index++) {
					const element = watermar[index];
					ctx.setFillStyle(element.color)
					ctx.fillText(element.text, element.x, element.y)
					ctx.strokeText(element.text, element.x, element.y)
				}
				ctx.draw(true, function () {
					wx.canvasToTempFilePath({
						canvasId: 'firstCanvas',
						success: (res) => {
							resolve([res.tempFilePath])
						},
						fail: (e) => {
							console.log(e)
						}
					}, that)
				})
			})
		},
		uploadFile(arrImg) {
			console.log('arrImg', arrImg);
			wx.showLoading({
				title: '正在上传',
			})
			var that = this;
			var t = 0;
			for (var i = 0; i < arrImg.length; i++) {
				wx.uploadFile({
					url: api.upload.img,
					filePath: arrImg[i],
					name: 'file',
					dataType: "json",
					success: function (res) {
						console.log(272, res);
						var redata = JSON.parse(res.data);
						if (t < arrImg.length) {
							if (redata.code == 200) {
								setTimeout(function () {
									that.setTopicResource(redata.data, 1);
								}, 500)
							} else {
								// app.showError('请上传小于5M的图片')

							}
							wx.hideLoading();
						}
						t++;
					},
				})
			}
		},

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

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

相关文章

在Spring Boot中使用ZXing开源库生成带有Logo的二维码

在上一篇文章的基础上&#xff0c;我们将进一步扩展功能&#xff0c;实现在生成的二维码中嵌入Logo图片。这样的二维码更具个性化和识别度。让我们逐步完成这个功能。 第一步&#xff1a;引入Logo图片 首先&#xff0c;准备一张用作Logo的图片&#xff0c;并确保它的大小适中…

图像处理------负片

什么是负片&#xff1f; 负片是经曝光和显影加工后得到的影像&#xff0c;其明暗与被摄体相反&#xff0c;其色彩则为被摄体的补色&#xff0c;它需经印放在照片上才还原为正像。我们平常所说的用来冲洗照片的底片就是负片。 """将彩色图像转换成负片 "&…

Java的异常 Exception

从继承关系可知:Throwable 是异常体系的根&#xff0c;它继承自Object 。Throwable 有两个体系: Error 和Exception. Error表示严重的错误&#xff0c;程序对此一般无能为力,例如: OutOfMemoryError :内存耗尽NoClassDefFoundError :无法加载某个ClassStackOverflowError :虚…

V∗: Guided Visual Search as a Core Mechanism in Multimodal LLMs

摘要 当我们环顾四周并执行复杂任务时&#xff0c;我们如何看待和选择性地处理我们所看到的是至关重要的。然而&#xff0c;这种视觉搜索机制的缺乏&#xff0c;在目前的多模态LLM&#xff08;MLLM&#xff09;阻碍了他们的能力&#xff0c;专注于重要的视觉细节&#xff0c;特…

c++:类和对象(2),对象的初始化和清理

目录 构造函数和析构函数 构造函数语法&#xff1a;类名&#xff08;&#xff09;{} 析构函数语法: ~类名 () {} 例子&#xff1a; 构造函数的分类及调用 两种分类的方式&#xff1a; 三种调用方法&#xff1a; 括号法​编辑 显示法 隐式转换法 拷贝构造函数调用时…

Python range函数

Python中的range()函数是一个强大的工具&#xff0c;用于生成一系列的整数。它在循环、迭代和序列生成等方面都有广泛的应用。本文将深入探讨range()函数的用法&#xff0c;提供详细的示例代码&#xff0c;并讨论其在Python编程中的实际应用。 什么是range()函数&#xff1f; …

springboot导出数据到excel模板,使用hutool导出数据到指定excel,java写入数据到excel模板

最近遇到一个需求&#xff0c;需要从数据库查询数据&#xff0c;写入到对应的excel导入模板中。再把导出的数据进行修改&#xff0c;上传。 我们项目用的是easyExcel&#xff0c;一顿百度搜索&#xff0c;不得其法。 主要是要把数据填充到指定单元格中&#xff0c;跟平时用到的…

计算机网络实验二:Packet Tracer的简单使用

目录 实验二&#xff1a;Packet Tracer的简单使用 2.1 实验目的 2.2 实验步骤 2.2.1 构建网络拓扑 2.2.2 配置各网络设备 2.2.3 网络功能验证测试 2.3 实验总结 实验二&#xff1a;Packet Tracer的简单使用 2.1 实验目的 ①练习packet tracer仿真软件的安装&#xff1…

mc我的世界服务器多少钱一个月?

我的世界服务器多少钱一个月&#xff1f;低至7元一个月&#xff0c;阿里云和腾讯云均可以选择mc服务器&#xff0c;阿里云2核2G3M轻量服务器87元一年、腾讯云轻量2核2G3M服务器88元一年&#xff0c;阿里云ECS云服务器2核2G3M带宽99元一年&#xff0c;腾讯云2核4G5M带宽轻量应用…

活动回顾丨云原生技术实践营上海站「云原生 AI 大数据」专场(附 PPT)

AI 势不可挡&#xff0c;“智算”赋能未来。2024 年 1 月 5 日&#xff0c;云原生技术实践营「云原生 AI &大数据」专场在上海落幕。活动聚焦容器、可观测、微服务产品技术领域&#xff0c;以云原生 AI 工程化落地为主要方向&#xff0c;希望帮助企业和开发者更快、更高效地…

菜鸡后端的前端学习记录

前言 记录一下看视频学习前端的的一些笔记&#xff0c;以前对Html、Js、CSS有一定的基础&#xff08;都认得&#xff0c;没用过&#xff09;&#xff0c;现在不想从头再来了&#xff0c;学学Vue框架&#xff0c;不定时更新&#xff0c;指不定什么时候就鸽了。。。。 Vue2 01…

初识汇编指令

1. ARM汇编指令 目的 认识汇编, 从而更好的进行C语言编程 RAM指令格式: 了解 4字节宽度 地址4字节对齐 方便寻址 1.1 指令码组成部分 : condition: 高4bit[31:28] 条件码 0-15 &#xff08;16个值 &#xff09; 条件码: 用于指令的 条件执行 , ARM指定绝大部分 都可…

Linux之快速入门(CentOS 7)

文章目录 一、Linux目录结构二、常用命令2.1 切换用户2.2查看ip地址2.3 cd2.4 目录查看2.5 查看文件内容2.6 创建目录及文件2.7 复制和移动2.82.93.0 一、Linux目录结构 目录作用/bin是 Binaries (二进制文件) 的缩写,这个目录存放着最经常使用的命令/dev是 Device(设备) 的缩写…

【GitHub项目推荐--不错的Rust开源项目】【转载】

01 Rust 即时模式 GUI 库 egui 是一个简单、快速且高度可移植的 Rust 即时模式 GUI 库&#xff0c;可以轻松地将其集成到你选择的游戏引擎中&#xff0c;旨在成为最易于使用的 Rust GUI 库&#xff0c;以及在 Rust 中制作 Web 应用程序的最简单方法。 项目地址&#xff1a;ht…

go 依赖注入设计与实现

在现代的 web 框架里面&#xff0c;基本都有实现了依赖注入的功能&#xff0c;可以让我们很方便地对应用的依赖进行管理&#xff0c;同时免去在各个地方 new 对象的麻烦。比如 Laravel 里面的 Application&#xff0c;又或者 Java 的 Spring 框架也自带依赖注入功能。 今天我们…

【ASOC全解析(一)】ASOC架构简介和欲解决的问题

【ASOC全解析&#xff08;一&#xff09;】ASOC架构简介和欲解决的问题 一、什么是ASOC以及ASOC解决的三个问题二、ASOC的组成与功能解决第一个问题解决第二个问题解决第三个问题 三、ASOC基本工作原理 /********************************************************************…

Parade Series - Android Studio

硬件支持 CPU i7 RAM 16Gb -------------- ------- Java 3Gb Android 33GbJava Enviroment C:\ ├─ Java │ ├─ jdk1.8.0_181 │ ├─ jre1.8.0_181 │ ├─ maven-3.8.5 │ └─ gradle-6.5 └─ Cache├─ gr…

基于中文垃圾短信数据集的经典文本分类算法实现

垃圾短信的泛滥给人们的日常生活带来了严重干扰&#xff0c;其中诈骗短信更是威胁到人们的信息与财产安全。因此&#xff0c;研究如何构建一种自动拦截过滤垃圾短信的机制有较强的实际应用价值。本文基于中文垃圾短信数据集&#xff0c;分别对比了朴素贝叶斯、逻辑回归、随机森…

哈希--73. 矩阵置零/medium 理解度A

73. 矩阵置零 1、题目2、题目分析3、复杂度最优解代码示例4、适用场景 1、题目 给定一个 m x n 的矩阵&#xff0c;如果一个元素为 0 &#xff0c;则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,1,1],[1,0,1],[1,…

Overleaf(LaTeX文档在线编写平台)使用学习记录

一、LaTeX简概[1] LaTeX&#xff0c;是一种基于TEX的排版系统&#xff0c;是一种可以处理排版和渲染的标记语言。由美国计算机科学家莱斯利兰伯特在20世纪80年代初期开发&#xff0c;利用这种格式系统的处理&#xff0c;即使用户没有排版和程序设计的知识也可以充分发挥由TEX所…