前端开发学习 (五) 生命周期函数、Ajax请求

news2024/11/17 22:37:54

      关于vue实例的声明周期,从Vue实例创建、运行、到销毁期间,总是伴随着各种各样的事件,这些事件,统称为生命周期  (https://cn.vuejs.org/v2/guide/instance.html#实例生命周期 )

   而声明周期勾子就是生命周期事件的别名而已 (https://cn.vuejs.org/v2/api/#选项-生命周期钩子 )

   生命周期钩子 = 生命周期函数 = 生命周期事件

 一、生命周期函数的主要分类

1、创建期间的生命周期函数

1、beforeCreate  #实例刚在内存中被创建出来,此时,还没有初始化好 data 和 methods 属性

2、created   #实例已经在内存中创建OK,此时 data 和 methods 已经创建OK
             #此时还没有开始 编译模板。我们可以在这里进行Ajax请求。

3、beforeMount  #此时已经完成了模板的编译,但是还没有挂载到页面中

4、mounted   #此时,已经将编译好的模板,挂载到了页面指定的容器中显示
            #(mounted之后,表示真实DOM渲染完了,可以操作DOM了)
案例
<!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>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
</head>

<body>

<!--这个div区域就是MVVM中的 View 视图-->
<div id="app1">
</div>
</body>

<script>

    new Vue({
        el: '#app1',
        data: {
            msg: 'hello vuejs'
        },
        // 这是第1个生命周期函数,表示实例完全被创建出来之前,会执行它
        beforeCreate: function () {
            console.log('01 beforeCreate', this.msg);
            //注意:在 beforeCreate 生命周期函数执行的时候,data 和 methods 中的 数据都还没有没初始化
        },

        // 这是第2个生命周期函数
        created: function () {
            console.log('02 created', this.msg);
            //注意:如果要调用 methods 中的方法,或者操作 data 中的数据,最早,只能在 created 中操作
        },

        // 这是第3个生命周期函数,表示 模板已经在内存中编辑完成了,但是尚未把模板渲染到页面中
        beforeMount: function () {
            console.log('03 beforeMount', this.msg);
            // 在 beforeMount 执行的时候,页面中的元素,还没有被真正替换过来,只是之前写的一些模板字符串
        },

        // 这是第4个生命周期函数,表示,内存中的模板,已经真实的挂载到了页面中,用户已经可以看到渲染好的页面了
        mounted: function () {
            console.log('04 mounted', this.msg);
            // 注意: mounted 是 实例创建期间的最后一个生命周期函数,当执行完 mounted 就表示,实例已经被完全创建好了
            // 此时,如果没有其它操作的话,这个实例,就静静的 躺在我们的内存中,一动不动
        }
    });
</script>


</html>

2、运行期间的生命周期函数

1、beforeUpdate  #状态更新之前执行此函数, 此时 data 中的状态值是最新的
                 #但是界面上显示的 数据还是旧的,因为此时还没有开始重新渲染DOM节点

2、updated    #实例更新完毕之后调用此函数,此时 data 中的状态值 和 界面上显示的数据
              #都已经完成了更新,界面已经被重新渲染好了


PS:数据发生变化时,会触发这两个方法。不过,我们一般用watch来做
<!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>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
</head>

<body>

<!--这个div区域就是MVVM中的 View-->
<div id="app1">
    <input type="button" value="修改flag" @click="myMethod">
    <h3 id="h3">{{ flag }}</h3>
</div>
</body>
<script>

    new Vue({
        el: '#app1',
        data: {
            msg: 'hello vue',
            flag: false
        },

        methods: {
            myMethod: function () {
                this.flag = true;
            }
        },


        // 接下来的是运行中的两个事件
        // 这时候,我们的界面还没有被更新【但是,数据被更新了吗?  数据肯定被更新了】
        beforeUpdate() {
            console.log('-------------05 beforeUpdate', this.msg);

            // 结论:当执行 beforeUpdate 的时候,页面中的显示的数据,还是旧的,此时 data 数据是最新的,页面尚未和 最新的数据保持同步
            console.log('界面上DOM元素显示的内容:' + document.getElementById('h3').innerText)
            console.log('data 中的 msg 数据:' + this.flag)
        },
        updated() {
            console.log('-------------06 updated', this.msg);

            // 结论:updated 事件执行的时候,页面和 data 数据已经保持同步了,都是最新的
            console.log('界面上DOM元素显示的内容:' + document.getElementById('h3').innerText)
            console.log('data 中的 msg 数据:' + this.flag)
        }
    });
</script>


</html>

 

 

可以看得到,当执行 beforeUpdate 的时候,页面中的显示的数据还是旧的,但此时 data 数据是最新的。 updated 事件执行的时候,页面和 data 数据已经保持同步了,都是最新的

3、销毁期间的生命周期函数

1、beforeDestroy   #实例销毁之前调用。在这一步,实例仍然完全可用。

2、destroyed    #Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定
               #所有的事件监听器会被移除,所有的子实例也会被销毁



PS:
   可以在beforeDestroy里清除定时器、或清除事件绑定

4、生命周期函数图解

二、axios 发送Ajax请求

#参考文档
https://blog.csdn.net/sunyctf/article/details/129002056
https://blog.csdn.net/weixin_40017062/article/details/131810859

我们直接所有的vue代码都是写在index.html文件中的,这样其实很不好,我们将他修改一下,改成从.vue中读取配置

vi public/index.html

<!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>
    <div id="app"></div>
  </body>
</html>

index.html文件回归初始状态,声明app表示入口

vi my-vue-app/src/main.js

import { createApp } from 'vue'
import App from './App.vue'


const app = createApp(App)
app.mount('#app')

vi my-vue-app/src/App.vue

<template>
    <div id="app">
        <HelloWorld></HelloWorld>
    </div>
</template>

<script>
import HelloWorld from './components/HelloWorld.vue'

export default {
    name: 'App',
    components: {
        HelloWorld
    }
}
</script>

vi my-vue-app/src/components/HelloWorld.vue

<template>
123
</template>

<script>
export default {
    name: "HelloWorld",
}
</script>

<style scoped>

</style>

访问

http://127.0.0.1:8080/

 

我们上面经过绑定配置,已经将HelloWorld.vue 绑定到了index.html中了,后续配置都是基于HelloWorld.vue文件

安装axios

cd .\my-vue-app\
npm install axios --save

三、GET请求

创建测试json文件

vi my-vue-app/public/data.json

{
  "ret": "0",
  "data": [
    { "path": "page1", "component": "Page1" , "ip": "Page1" },
    { "path": "page2", "component": "Page2" , "ip": "Page1"},
    { "path": "page3", "component": "Page3" , "ip": "Page1"}
  ]
}

我们通过get请求其他后端的api通常会返回类似上面的一个json配置,我们通过这个来模拟请求接口返回的数据,因为我们这个json文件是直接添加到index.html的同级目录,可以直接通过浏览器访问

http://127.0.0.1:8080/data.json

vi my-vue-app/src/components/HelloWorld.vue

<template>
    {{json}}
</template>

<script>
import axios from "axios"
export default {
    name: "HelloWorld",
    data(){
        return{
            json: ""   //定义一个空数据,与div交互用
        }
    },
    created() { //created 页面部署时自动执行
        axios.get("http://localhost:8080/data.json")
            .then((result) => {
                this.json = result.data  //result.data 会将返回的json交给data中的json变量
                console.log(result.data)
            })
            .catch((err) =>{{
                console.log(err)
            }}
            )
    }
}
</script>

<style scoped>

</style>

访问页面

http://localhost:8080/

 

目前看起来没什么问题,直接请求地址+json文件返回了信息,但是一遍来说我们的后端程序都不会放到前端节点的相同主机上,需要跨站访问,比如

https://www.runoob.com/try/ajax/json_demo.json

 我们把上面代码中的url地址换成这个再跑下

 vi my-vue-app/src/components/HelloWorld.vue

<template>
    {{json}}
</template>

<script>
import axios from "axios"
export default {
    name: "HelloWorld",
    data(){
        return{
            json: ""   //定义一个空数据,与div交互用
        }
    },
    created() { //created 页面部署时自动执行
        axios.get("https://www.runoob.com/try/ajax/json_demo.json")
            .then((result) => {
                this.json = result.data  //result.data 会将返回的json交给data中的json变量
                console.log(result.data)
            })
            .catch((err) =>{{
                console.log(err)
            }}
            )
    }
}
</script>

<style scoped>

</style>

我们打开页面发现什么信息都没有,按F12打开开发者工具发现下面这么一条报错

已拦截跨源请求:同源策略禁止读取位于 http://localhost:8080/data.json 的远程资源。(原因:CORS 头缺少 'Access-Control-Allow-Origin')。状态码:200。

跨域访问--配置代理

我们在自己独立使用的时候你直接改成127.0.0.1其实也能访问,但不可能所有的接口都在当前本机上,只要跨主机都会报错并且无法获取到数据,所以我们要先做一点改造

my-vue-app/vue.config.js

const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
  transpileDependencies: true,

  devServer: {
    proxy: {
      "/try":{    //try 这个用来和根路径 baseURL 进行匹配  以try开头的请求会转到下面的地址
        target: 'https://www.runoob.com',
        changeOrigin: true,
      }
    }
  }

})

重启服务

ctrl + c  停止

#启动
 npm run serve 

如果要配置多个代理,就把proxy那好行多复制几次

四、POST请求

post请求常用的数据请求格式有三种

1、Content-Type : application/x-www-form-urlencoded。
ajax默认的数据格式。请求体中的数据会以json字符串的形式发送到后端。

2、Content-Type : application/json ; charset=utf-8。
axios默认的数据格式。请求体中的数据会以普通表单形式(键值对)发送到后端。

3、Content-Type : multipart/form-data 。
它会将请求体的数据处理为一条消息,以标签为单元,用分隔符分开。既可以上传键值对,也可以上传文件

1、Content-Type:application/x-www-form-urlencoded  json请求后端

my-vue-app/src/components/HelloWorld.vue

<template>
    <div class="hello">...</div>
</template>

<script>
import axios from "axios";
import qs from 'qs';

export default {
    name: "HelloWorld",
    created() {
        // 对象data的属性名uname和upwd引号可加可不加
        let data = {uname:"dingding",upwd:"123456"};

        axios.post("/data.json",qs.stringify({ data }))
            .then(res=>{
                console.log(res);
            })
    },
};


</script>

因为我这里是post了一个json文件所以会有报错,不过没关系,我们查看一下这条post请求的请求头,发现确实是application/x-www-form-urlencoded,请求参数也可以看到

2 Content-Type: multipart/form-data(常用于表单提交(图片上传、文件上传))

<template>
    <div className="hello">......</div>
</template>

<script>
import axios from "axios";

export default {
    name: "HelloWorld",
    created() {
        let data = {uname: "dingding", upwd: 123456};
        let formData = new FormData();
        for (let key in data) {
            formData.append(key, data[key]);
        }
        console.log(formData);

        axios.post("/date.json", formData).then((res) => {
            console.log(res.data);
        });
    },
};
</script>
<style scoped>
</style>

3、Content-Type: application/json

方式一 、请求别名的使用

axios.post(url[, data[, config]]) 用于发送数据 `data`对象是作为请求主体被发送的数据

 post 无参数请求
<template>
  <div class="hello">......</div>
</template>
 
<script>
import axios from "axios";
export default {
  name: "HelloWorld",
  created() {
    //把get无参请求的get改为post即可
    axios.post("/data.json").then(res=>{
      console.log(res)
    });
  },
};
</script>
 
<style scoped>...</style>
 post 带参数 查询字符串形式
<template>
  <div class="hello">......</div>
</template>
 
<script>
import axios from "axios";
export default {
  name: "HelloWorld",
  created() {
    //发送post请求携带参数,直接使用"uname=dingding&upwd=123456"
    axios.post("/data.json", "uname=dingding&upwd=123456").then(res=>{
      console.log(res)
    });
  },
};
</script>
 
<style scoped>...</style>
 
​
post 带参数 对象形式
<template>
  <div class="hello">......</div>
</template>
 
<script>
import axios from "axios";
export default {
  name: "HelloWorld",
  created() {
    //发送post请求携带参数,直接使用"uname=dingding&upwd=123456"
    axios.post("/data.json", "uname=dingding&upwd=123456").then(res=>{
      console.log(res)
    });
  },
};
</script>
 
<style scoped>...</style>
 
​
方式二:通过向axios传递相关配置来创建请求
<template>
  <div class="hello">......</div>
</template>
 
<script>
import axios from "axios";
export default {
  name: "HelloWorld",
  created() {
     let data = {uname:"dingding",upwd:123456};
     axios({
       method:'post',
       url:'/data.json',
       // 与get请求使用params不同的是,post请求使用data属性
       data:data
     }).then(res=>{
       console.log(res)
    })
  },
};
</script>
 
<style scoped>...</style>

注意:别名方式和data方式的相关请求信息

- 请求地址Request URL: http://localhost:8080/data.json,

- 请求头中Content-Type: application/json

- 参数形式:{uname: "dingding", upwd: 123456}

五、put和patch方法

 put和patch请求与post请求用法一样类似,同样有x-www-form-urlencoded、applicition/json和form-data,只有method不同,其他相同

let data = {uname:"dingding",upwd:123456};
// axios.put(url[, data[, config]]) 用法同post类似,用于修改数据 
axios.put("/data.json", data).then(res=>{
  console.log(res)
});
 
 
let data = {uname:"dingding",upwd:123456};
// axios.patch(url[, data[, config]]) 用法同post类似,用于修改数据 
axios.patch("/data.json", data).then(res=>{
  console.log(res)
});

六、delete方法

axios.delete(url[, config])与axios.get(url[, config])用法基本相似,但是作用不同,它用于删除数据,同get方法一样也可以有几种写法

delete请求有时候需要把参数拼接到URL上,有时候像post请求那样把参数放在请求体里面。至于具体怎么调用,需要和后端商量好

 方式一:get - params

// 使用别名法
 
// 传参的2种形式,同get
 
1、params
axios
  .delete("/data.json", {
    params: {
      id: 12
    }
  })
  .then(res => {
    console.log(res, "delete");
  });
 
2、查询字符串形式,即参数拼接到url里
axios
  .delete("/data.json?id=2", {
    params: {
      id: 12
    }
  })
  .then(res => {
    console.log(res, "delete");
  });
 
  
// 不使用别名法 —————通过向axios传递的相关配置创建请求__axios(config)
let params = {
  id: 5
};
axios({
  method:'delete',
  url:'/data.json',
  params:params
}).then(res=>{
  console.log(res)
})

方式二:post - data

使用类似post请求方式,把axios.delete()中的params改为data,这样请求会把内容放入请求体里面

// 使用别名法
// data
axios
  .delete("/data.json", {
    data: {
      id: 5
    }
  })
  .then(res => {
    console.log(res);
  });
  
// 不使用别名法 ————通过传递相关配置创建请求
let data = {
  id: 5
};
axios({
  method:'delete',
  url:'/data.json',
  data:data
}).then(res=>{
  console.log(res)
})

 注意:delete请求中,get-params方式和post-data方式相关请求信息的区别

- params方式会将请求参数拼接在URL上面,Request URL: http://localhost:8080/data.json?id=5

- 参数形式:id:5

- Content-Type: text/html; charset=utf-8

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

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

相关文章

我的创作纪念日(2周年)

机缘 在进入大学之前&#xff0c;完全没有听说过CSDN&#xff0c;第一次使用CSDN应该是搜C语言如何学&#xff0c;或者是和C语言相关的其他内容 因为我本人是学计算机专业的&#xff0c;大一刚开学因为疫情延迟了开学时间&#xff0c;老师线上教课&#xff0c;但是我之前是完…

[架构之路-260]:目标系统 - 设计方法 - 软件工程 - 软件设计 - 架构设计 - 基于Web的软件架构(REST与RESTful)

目录 一、基于Web的软件架构 1.1 什么是基于Web的软件架构 1.2 基于Web的软件架构的发展历史 1.3 基于Web的软件架构的优点 1.4 基于Web的软件架构的示例 1.5 基于Web的软件架构的协议标准 1.6 基于Web的软件架构 二、REST与RESTful 2.1 概述 2.2 RESTful协议 2.3 R…

自治调优!人大金仓解放DBA双手

数据库系统的性能是确保整个应用系统高效运转的关键因素&#xff0c;因此数据库性能调优工作至关重要。KingbaseES通过将人工调优过程内化为数据库内核&#xff0c;成功实现了自治调优。这种创新的调优方案为DBA提供了更高效且准确的性能调优途径&#xff0c;同时也显著降低了数…

【头歌系统数据库实验】实验5 SQL的多表查询-1

目录 第1关&#xff1a;等值连接&#xff1a;求S表和J表城市相同的等值连接(列顺序还是按照S、J表) 第2关&#xff1a;查询供应情况&#xff0c;并显示供应商、零件和工程三者的名称 第3关&#xff1a;找出上海厂商供应的所有零件号码 第4关&#xff1a;找出使用上海产的零…

ES 如何将国际标准时间格式进行格式化与调整时区

需求&#xff0c;日志收集的时候&#xff0c;时间格式是国际标准时间格式。形如yyyy-MM-ddTHH:mm:ss.SSS。 &#xff08;2023-12-05T02:45:50.282Z&#xff09;这个时区也不对&#xff0c;那如何将此类型的时间&#xff0c;进行格式化呢&#xff1f; 本篇文章体统一个案例&…

基于Python+Django+mysql图书管理系统

基于PythonDjangomysql图书管理系统 一、系统介绍二、功能展示三、其它系统四、获取源码 一、系统介绍 程序开发软件&#xff1a;Pycharm 数据库&#xff1a;mysql 采用技术&#xff1a; Django(一个MVT框架&#xff0c;类似Java的SSM框架) 人生苦短&#xff0c;我用Python&a…

Web服务安全架构——一、Web应用程序基础理论

Web安全架构 一、引言二、Web应用程序的生成过程三、程序员是如何开发Web应用程序的1、Web程序的分层结构2、各司其职的程序员3、研究 Web 应用程序的利器3.1 黑盒测试类工具3.2 白盒测试类工具 四、小结 一、引言 随着互联网的迅速发展&#xff0c;我们越来越多地使用Web应用…

【前端】CSS盒子模型(学习笔记)

一、盒子模型 1、网页布局的本质 先准备好相关的网页元素&#xff0c;网页元素基本都是盒子 Box 。利用 CSS 设置好盒子样式&#xff0c;然后摆放到相应位置。往盒子里面装内容. 网页布局的核心本质&#xff1a; 利用 CSS 摆盒子。 2、盒子模型 盒子模型&#xff1a;就是把 …

LangChain 25: SQL Agent通过自然语言查询数据库sqlite

LangChain系列文章 LangChain 实现给动物取名字&#xff0c;LangChain 2模块化prompt template并用streamlit生成网站 实现给动物取名字LangChain 3使用Agent访问Wikipedia和llm-math计算狗的平均年龄LangChain 4用向量数据库Faiss存储&#xff0c;读取YouTube的视频文本搜索I…

随机分词与tokenizer(BPE->BBPE->Wordpiece->Unigram->sentencepiece->bytepiece)

0 tokenizer综述 根据不同的切分粒度可以把tokenizer分为: 基于词的切分&#xff0c;基于字的切分和基于subword的切分。 基于subword的切分是目前的主流切分方式。subword的切分包括: BPE(/BBPE), WordPiece 和 Unigram三种分词模型。其中WordPiece可以认为是一种特殊的BPE。完…

臻程密封科技(江苏)有限公司携橡胶密封产品亮相2024生物发酵展

臻程密封科技&#xff08;江苏&#xff09;有限公司盛装亮相2024第12届国际生物发酵产品与技术装备展&#xff08;济南&#xff09; 展位号&#xff1a;2号馆H56 臻程密封科技&#xff08;江苏&#xff09;有限公司专注于橡胶密封材料的研发&#xff0c;橡胶密封产品的生产、…

阿里云SLB的使用总结

一、什么是SLB 实现k8s的服务service的一种推荐方式&#xff0c;也是服务上云后&#xff0c;替代LVS的一个必选产品。 那么它有什么作用呢&#xff1f; 1、负载均衡&#xff0c;是它与生俱来的。可以配置多个服务器组&#xff1a;包括虚拟服务器组、默认服务器组、主备服务器…

来自OpenAI的官方解释:ChatGPT中的GPTs与Assistants API的区别是什么?有什么差异?

本文原文来自DataLearnerAI的官方网站&#xff1a; 来自OpenAI的官方解释&#xff1a;ChatGPT中的GPTs与Assistants API的区别是什么&#xff1f;有什么差异&#xff1f; | 数据学习者官方网站(Datalearner)https://www.datalearner.com/blog/1051701996595465 OpenAI发布的产…

大数据技术5:OLAP引擎对比分析

前言&#xff1a;数据仓库建设&#xff0c;初级的理解就是建表&#xff0c;将业务数据、日志数据、消息队列数据等&#xff0c;通过各种调度任务写入到表里供OLAP引擎使用。但要想建好数仓也是一个复杂、庞大的工程&#xff0c;比如要考虑&#xff1a;数据清洗、数据建模&#…

使用Vue3+Typescript手写一个日历签到组件

设计理念 昨天写了个简单美观的日历签到组件&#xff0c;使用的是Vue3TypeScript&#xff0c;大概逻辑是先找到本月份第一天是周几&#xff0c;然后开始填充月份日期&#xff1a;weeksArray:[[]]:之后渲染到表格中&#xff0c;对于签到事件触发则先判断是否是今天且还未没有签…

计算机视觉 基于Open3D了解用于网格和点云邻域分析的KD树和八叉树

一、简述 距离计算和邻域分析是理解网格和点云的形状、结构和特征的重要工具。我们这里要基于一些3D库来提取基于距离的信息并将其可视化。 与深度图或体素相比,点云和网格表示 3D 空间中的非结构化数据。点由它们的 (X, Y, Z) 坐标表示,在 3D 空间中可能彼此靠近的两…

6.3 U-boot 启动流程详解

通过对 uboot 启动流程的梳理&#xff0c;我们就可以掌握一些外设是在哪里被初始化的&#xff0c;这样当我们需要修改这些外设驱动的时候就会心里有数。 一、链接脚本 u-boot.lds 分析 uboot 的启动流程&#xff0c;首先要找到“入口”&#xff0c;找到第一行程序在哪里。程序…

【Delphi】FMX开发 ios 和 android 异同点(踩坑记)

目录 一、前言 二、补充下基础知识 1. APP程序事件&#xff1a;TApplicationEvent 2. APP内置Web服务器或者UDP服务端或者TCP服务端 三、iOS 和 android 平台的不同点 1. TApplicationEvent的不同点&#xff1a;以下不同点&#xff0c;请仔细阅读&#xff01; 2. APP内置…

嵌入式培训-Linux系统及C编程高级-DAY6-linux shell脚本编程

Shell脚本概述 Shell脚本是利用 shell 的功能所写的一个程序。这个程序是使用纯文本文件&#xff0c;将一些 shell 的语法与命令&#xff08;含外部命令&#xff09;写在里面&#xff0c;搭配正则表达式、管道命令与数据流重定向等功能 Shell脚本编写流程 Shell脚本的文件扩展名…

luceda ipkiss教程 45:在版图上加LOGO

**在设计版图时往往需要加上公司或者学校的LOGO,只需要LOGO的图片&#xff0c;通过代码就可以将LOGO加到版图上&#xff0c;比如&#xff1a; ** 通过代码可以得到版图上的LOGO: ![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/8daea33f74f342ed9f506ae5d8cea711.…