Gin框架: HTML模板渲染之配置与语法详解

Gin的HTML模板配置


1 )单一目录的配置

  • 配置模板目录,在与main.go同级下, 新建目录,下面二选一,仅作举例, 这里选择 tpls

    • templates
    • tpls
  • 在 tpls 目录下新建 news.html

    <!-- 最简单的 -->
    <h1>News Page</h1>
    
    <h3>标题:{{.title}}</h3>
    <p>内容:{{.content}}</p>
    
    • 注意,这里加上define和end头尾也可以
      {{ define "news.html" }}
      <h1>News Page</h1>
      	
      <h3>标题:{{.title}}</h3>
      <p>内容:{{.content}}</p>
      {{ end }}
      
  • 应用程序示例中配置

    • r.LoadHTMLGlob("tpls/*") 通配设定
    • r.LoadHTMLFiles("tpls/news.html") 逐个指定,多个在字符串中用,分隔

程序示例

package main

import (
	"net/http"
	"github.com/gin-gonic/gin"
)

var statusOK = http.StatusOK

func main() {
	// 创建一个默认的路由引擎
	r := gin.Default()
	// 配置模板的文件
	r.LoadHTMLGlob("tpls/*")
	// r.LoadHTMLFiles("tpls/news.html") // 逐个指定多个需要使用逗号分隔

	// 根路由
	r.GET("/", func(c *gin.Context) {
		c.String(statusOK, "Welcome to %v", "Home Page")
	})

	r.GET("/news", func(c *gin.Context) {
		c.HTML(statusOK, "news.html", gin.H{
			"title": "新闻标题",
			"content": "这是详细的新闻内容",
		})
	})
	r.Run()
}

2 )多目录配置

  • 配置模板目录,在与main.go同级下, 新建目录 tpls, 在内部再创建两个目录: web, admin

    • tpls/web
    • tpls/admin
  • 新建 tpls/admin/news.html

    {{ define "admin/news.html" }}
    
    <h1>News Page</h1>
    
    <h3>标题:{{.title}}</h3>
    <p>内容:{{.content}}</p>
    
    {{ end }}
    
    • 这里内容和之前保持一致, 但要注意上下的定义
    • 如果不添加,会出现 Error #01: html/template: "admin/news.html" is undefined 的错误
    • 这里的 define 和 end 非常重要
    • define 配置的路径是匹配c.HTML 中的第二个参数
  • 应用程序示例中配置

    • r.LoadHTMLGlob("tpls/**/*") 通配设定
    • r.LoadHTMLFiles("tpls/admin/news.html") 逐个指定,多个在字符串中用,分隔

程序示例

package main

import (
	"net/http"
	"github.com/gin-gonic/gin"
)

var statusOK = http.StatusOK

func main() {
	// 创建一个默认的路由引擎
	r := gin.Default()
	// 配置模板的文件
	r.LoadHTMLGlob("tpls/**/*")
	// r.LoadHTMLFiles("tpls/admin/news.html") // 逐个指定多个需要使用逗号分隔

	// 根路由
	r.GET("/", func(c *gin.Context) {
		c.String(statusOK, "Welcome to %v", "Home Page")
	})

	r.GET("/admin/news", func(c *gin.Context) {
		c.HTML(statusOK, "admin/news.html", gin.H{
			"title": "新闻标题",
			"content": "这是详细的新闻内容",
		})
	})

	r.Run()
}

3 )多层复杂目录配置

  • 首先看下设定的结构

    yourGinProject/ ·······························  根目录
      ├── go.mod ··································  go mod 文件
      ├── go.sum ··································  go sum 文件
      ├── main.go ·································  main 文件
      └── tpls ····································· html模板目录
      		├── a
    	    │   └── b
    	    │  		└── c
    	    │  		    └── d
    	    │  		        └── e
    	    │  		            └── news.html
    	    ├── admin
    	    │   └── news.html
    	    │
    	    └── news.html
    
    • tpls/news.html

      {{ define "news.html" }}
      
      <h1>News Page</h1>
      
      <h3>标题:{{.title}}</h3>
      <p>内容:{{.content}}</p>
      
      {{ end }}
      
    • tpls/admin/news.html

      {{ define "admin/news.html" }}
      
      <h1>News Page</h1>
      
      <h3>标题:{{.title}}</h3>
      <p>内容:{{.content}}</p>
      
      {{ end }}
      
    • tpls/a/b/c/d/e/news.html

      {{ define "a/b/c/d/e/news.html" }}
      
      <h1>News Page</h1>
      
      <h3>标题:{{.title}}</h3>
      <p>内容:{{.content}}</p>
      
      {{ end }}
      
    • 注意各个 news.html 的define设定

程序示例

package main

import (
	"net/http"
	"github.com/gin-gonic/gin"
)

var statusOK = http.StatusOK

func main() {
	// 创建一个默认的路由引擎
	r := gin.Default()
	// 配置模板的文件
	r.LoadHTMLGlob("tpls/**/**/**/**/**/*")

	// 根路由
	r.GET("/", func(c *gin.Context) {
		c.String(statusOK, "Welcome to %v", "Home Page")
	})

	// 这个配置和紧挨着下面的配置一致,只是路由自己设定了一个简洁版的
	r.GET("/x/news", func(c *gin.Context) {
		c.HTML(statusOK, "a/b/c/d/e/news.html", gin.H{
			"title": "新闻标题",
			"content": "这是详细的新闻内容",
		})
	})
	
	// 多层路由,同上
	r.GET("/a/b/c/d/e/news", func(c *gin.Context) {
		c.HTML(statusOK, "a/b/c/d/e/news.html", gin.H{
			"title": "新闻标题",
			"content": "这是详细的新闻内容",
		})
	})
	
	// 二级
	r.GET("/admin/news", func(c *gin.Context) {
		// r.LoadHTMLGlob("tpls/**/*") // 这里会 panic 报错
		r.LoadHTMLFiles("tpls/admin/news.html") // 这里正常可以访问,权重会大于顶部的全局配置
		c.HTML(statusOK, "admin/news.html", gin.H{
			"title": "新闻标题",
			"content": "这是详细的新闻内容",
		})
	})
	
	// 一级
	r.GET("/news", func(c *gin.Context) {
		// r.LoadHTMLGlob("tpls/*") // 这里会 panic 报错
		r.LoadHTMLFiles("tpls/news.html") // 这里正常可以访问,权重会大于顶部的全局配置
		c.HTML(statusOK, "news.html", gin.H{
			"title": "新闻标题",
			"content": "这是详细的新闻内容",
		})
	})

	r.Run()
}
  • 可以看到,在单个路由中r.LoadHTMLFiles 配置的用处了
  • 所以,以上就比较麻烦,一般而言,在一开始设计模板的时候,就要约定好规则
  • 特殊的设定只能应用于特殊的场景下

Gin的HTML模板语法


1 )基本渲染

主程序

package main

import (
	"net/http"
	"github.com/gin-gonic/gin"
)

var statusOK = http.StatusOK

type User struct {
	Id      int
	Name    string
	Hobby   string
}

func main() {
	// 创建一个默认的路由引擎
	r := gin.Default()
	// 配置模板的文件
	r.LoadHTMLGlob("tpls/*")

	// 根路由
	r.GET("/", func(c *gin.Context) {
		c.String(statusOK, "Welcome to %v", "Home Page")
	})

	r.GET("/user", func(c *gin.Context) {
		c.HTML(statusOK, "user.html", &User{
			Id:      1,
			Name:    " Wang ", // 注意,这里有2个空格
			Hobby:   "swimming",
		})
	})

	r.Run()
}

html模板

{{ define "user.html" }}

<h1>User Page</h1>

<h3>用户Id:{{.Id}}</h3>
<!-- 下面这种也是注释 -->
{{/* 这里是姓名,本身数据存在空格,但是这个去空格的方式无法去除 */}}
<h3>用户姓名:{{- .Name -}}</h3>
<h3>用户爱好:{{.Hobby}}</h3>

{{ $xId := .Id }}

<h3>演示变量:  {{- $xId -}} </h3>

{{ end }}
  • {{ .x }} x是属性,基于这种方式来输出数据
  • {{/* 这里是注释 */}} 注意 /**/ 紧贴着 {{}},可以多行,不可嵌套
  • {{ $xId := .Id }} 单独设定变量, 变量名只能使用一个 $
  • {{- $xId -}} 这种去除空格,只能去除周围的空格,无法去除属性内包含的空格,且-紧贴{{}},同时与模板值之间需要使用空格分隔

效果图

2 ) 比较, 判断, range, with

主程序

package main

import (
	"net/http"
	"github.com/gin-gonic/gin"
)

type Article struct {
	Title   string
	Content string
}

var statusOK = http.StatusOK

func main() {
	r := gin.Default()
	//加载模板 放在配置路由上面
	r.LoadHTMLGlob("tpls/**/*")

	//前台
	r.GET("/", func(c *gin.Context) {
		c.HTML(statusOK, "web/index.html", gin.H{
			"title": "首页",
			"msg":   " 我是msg",
			"score": 89,
			"hobby": []string{"吃饭", "睡觉", "写代码"},
			"newsList": []interface{}{
				&Article{
					Title:   "新闻标题1",
					Content: "新闻详情1",
				},
				&Article{
					Title:   "新闻标题2",
					Content: "新闻详情2",
				},
			},
			"testSlice": []string{},
			"news": &Article{
				Title:   "新闻标题",
				Content: "新闻内容",
			},
		})
	})
	r.Run()
}

html模板

{{ define "web/index.html" }}

<h2>title变量展示: {{.title}}</h2>

<!-- 定义变量 -->
{{$t := .title}}

<!-- 这里展示 title -->
<h4>
    这里通过变量,再次展现title: {{$t}}
</h4>

<!-- 条件判断 -->
<h4>这里基于判断,展示是否及格</h4>
{{if ge .score 60}}
    <p>及格</p>
{{else}}
    <p>不及格</p>
{{end}}

<h4>这里基于判断,更加细度展示成绩</h4>

{{if gt .score 90}}
    <p>优秀</p>
{{else if gt .score 80}}
    <p>良好</p>
{{else if gt .score 60}}
    <p>及格</p>
{{else}}
    <p>不及格</p>
{{end}}

<!-- 循环遍历数据 -->
<h3>下面用range开始遍历 hobby 数组</h3>
<ul>
    {{range $key,$value:=.hobby}}
    <li>{{$key}}----{{$value}}</li>
    {{end}}
</ul>

<h3>下面用range开始遍历 新闻 数组</h3>
<ul>
    {{range $key,$value:=.newsList}}
        <li>{{$key}}----{{$value.Title}}---{{$value.Content}}</li>
    {{end}}        
</ul>

<h3>下面用range遍历中,空数组场景的展示</h3>
<ul>
    {{range $key,$value:=.testSlice}}
          <li>{{$key}}----{{$value}}</li>
    {{else}}
        <li>数组中没有数据</li>
    {{end}}        
</ul>

<!-- with 解构结构体 -->
<h3>不使用 with 结构属性</h3>
<p>{{.news.Title}}</p>
<p>{{.news.Content}}</p>

<h3>使用 with 结构属性</h3>
{{with .news}}
    <p>{{.Title}}</p>
    <p>{{.Content}}</p>
{{end}}

{{ end }}
  • 关于比较函数中的一些注意事项
    • eq 如果 arg1 == arg2 则返回真
    • ne 如果 arg1 != arg2 则返回真
    • lt 如果 arg1 < arg2 则返回真
    • le 如果 arg1 <= arg2 则返回真
    • gt 如果 arg1 > arg2 则返回真
    • ge 如果 arg1 >= arg2 则返回真

效果图

3 )高阶用法:预定义函数,自定义模板函数,嵌套模板

  • 首先看下设定的结构
    yourGinProject/ ·······························  根目录
      ├── go.mod ··································  go mod 文件
      ├── go.sum ··································  go sum 文件
      ├── main.go ·································  main 文件
      └── tpls ····································· html模板目录
    	    ├── web
    	    │     └── index.html
    	    └── common
    	          └── page_header.html
    	          └── page_footer.html
    

主程序

package main

import (
	"html/template"
	"net/http"
	"time"
	"github.com/gin-gonic/gin"
)

type Article struct {
	Title   string
	Content string
}

var statusOK = http.StatusOK

//时间戳转换成日期
func UnixToTime(timestamp int) string {
	t := time.Unix(int64(timestamp), 0)
	return t.Format("2006-01-02 15:04:05") // 这个是按照这个时间来进行格式化, 必须是这个时间点, 据说是go诞生之日
}

func Println(str1 string, str2 string) string {
	return str1 + "----" + str2
}

func main() {
	// 创建一个默认的路由引擎
	r := gin.Default()

	//自定义模板函数, 注意要把这个函数放在加载模板前
	r.SetFuncMap(template.FuncMap{
		"UnixToTime": UnixToTime,
		"Println":    Println,
	})

	//加载模板 放在配置路由上面
	r.LoadHTMLGlob("tpls/**/*")

	// 前台
	r.GET("/", func(c *gin.Context) {
		c.HTML(statusOK, "web/index.html", gin.H{
			"title": "首页",
			"titleEn": "homePage",
			"msg": "demo",
			"date": 1708344953,
		})
	})

	r.Run()
}

web/index.html模板

{{ define "web/index.html" }}

  <!-- 这里定义通用头部 -->
  {{template "common/page_header.html" .}}

  <h3>下面演示: 预定义函数</h3>
  <!-- 预定义函数 -->

  {{ len .title }}
  <br />
  {{ len .titleEn }}

  <!-- 自定义模板函数 -->
  <h3>下面演示: 自定义模板函数</h3>
  {{.date}}
  <br />
  <br />
  {{UnixToTime .date}}
  <br>
  <br>
  {{Println .title .msg}}

  <!-- 这里定义通用尾部 -->
  {{template "common/page_footer.html" .}}

{{ end }}

common/page_header.html模板

{{ define "common/page_header.html" }}
    <h3>
        我是一个公共的标题---{{.title}}
    </h3>
{{end}}

common/page_footer.html模板

{{ define "common/page_footer.html" }}
    <h3>
        我是一个公共的底部
    </h3>
{{end}}
  • 在 预定义函数 中,执行模板时,函数从两个函数字典中查找

    • 首先是模板函数字典,然后是全局函数字典。
    • 一般不在模板内定义函数,而是使用 Funcs 方法添加函数到模板里
  • 预定义的全局函数如下

    • and
      • 函数返回它的第一个 empty 参数或者最后一个参数
      • 就是说"and x y"等价于"if x then y else x";所有参数都会执行
    • or
      • 返回第一个非 empty 参数或者最后一个参数
      • 亦即"or x y"等价于"if x then x else y";所有参数都会执行
    • not
      • 返回它的单个参数的布尔值的否定
    • len
      • 返回它的参数的整数类型长度
    • index
      • 执行结果为第一个参数以剩下的参数为索引/键指向的值
      • 如"index x 1 2 3"返回 x[1][2][3]的值;每个被索引的主体必须是数组、切片或者字典
    • print
      • 即 fmt.Sprint
    • printf
      • 即 fmt.Sprintf
    • println
      • 即 fmt.Sprintln
    • html
      • 返回与其参数的文本表示形式等效的转义 HTML
      • 这个函数在 html/template 中不可用
    • urlquery
      • 以适合嵌入到网址查询中的形式返回其参数的文本表示的转义值
      • 这个函数在 html/template 中不可用
    • js
      • 返回与其参数的文本表示形式等效的转义 JavaScript
    • call
      • 执行结果是调用第一个参数的返回值,该参数必须是函数类型,其余参数作为调用该函
        数的参数
      • 如"call .X.Y 1 2"等价于 go 语言里的 dot.X.Y(1, 2)
      • 其中 Y 是函数类型的字段或者字典的值,或者其他类似情况
      • call 的第一个参数的执行结果必须是函数类型的值(和预定义函数如 print 明显不同)
      • 该函数类型值必须有 1 到 2 个返回值,如果有 2 个则后一个必须是 error 接口类型
      • 如果有 2 个返回值的方法返回的 error 非 nil,模板执行会中断并返回给调用模板执行者该错误
  • 在自定义模板函数中,比如定义了 formatDate 方法,有两种用法

    • {{.now | formatDate}}
    • {{formatDate .now }}
  • 在嵌套 template中,注意最后的点(.)

效果图

静态文件服务器的配置


这块比较简单

主程序

package main

import (
	"net/http"
	"github.com/gin-gonic/gin"
)

var statusOK = http.StatusOK

func main() {
	// 创建一个默认的路由引擎
	r := gin.Default()

	//配置静态web目录 第一个参数表示路由, 第二个参数表示映射的目录
	r.Static("/static", "./static")

	// 前台
	r.GET("/", func(c *gin.Context) {
		c.String(statusOK, "Welcome to %v", "Home Page")
	})

	r.Run()
}
  • 这样就设定好了,在与 main.go 同级新建 static/images 目录,添加 mysql-logo.svg 图片
  • 访问该图片: http://localhost:8080/static/images/mysql-logo.svg
  • 其他的,如:css, js 这类也同样适用
  • 这时候,静态文件服务器就搭建好了

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

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

相关文章

爬虫之正则表达式

个人主页&#xff1a;Lei宝啊 愿所有美好如期而遇 概念&#xff1a; 正则表达式(regular expression)描述了一种字符串匹配的模式&#xff08;pattern&#xff09;&#xff0c;正则匹配是一个模糊的匹配(不是精确匹配) 如下四个方法经常使用&#xff1a; match()search()f…

AutoMQ 社区双周精选第七期(2024.01.29~2024.02.09)

本期概要 过去的两周里&#xff0c;社区贡献者lifepuzzlefun 为 AutoMQ 的 RocketMQ 项目优化了 LogCache 的二分查找性能&#xff0c;消除了不必要的List拷贝。 同时&#xff0c;AutoMQ 的主干动态展示了持续的性能优化和功能增强。在 Kafka 项目中&#xff0c;团队设计了新…

【Postgres】11、PROCEDURE 存储过程、FUNCTION 函数、使用方式和区别

文章目录 一、PROCEDURE1.1 语法1.2 描述1.3 参数1.4 示例 二、FUNCTION2.1 语法2.2 重载2.3 示例2.4 兼容性2.5 示例2.5.1 declare variable 定义变量2.5.2 declare、ARRAY、ANY2.5.2.1 ARRAY 和 ANY 三、其他3.1 PL/pgSQL 在PostgreSQL中&#xff0c;存储过程&#xff08;Pro…

家中R4S软路由iStoreOS配置内网穿透服务实现远程访问公司电脑桌面

文章目录 简介一、配置远程桌面公网地址二、家中使用永久固定地址 访问公司电脑**具体操作方法是&#xff1a;** 简介 软路由是PC的硬件加上路由系统来实现路由器的功能&#xff0c;也可以说是使用软件达成路由功能的路由器。 使用软路由控制局域网内计算机的好处&#xff1a…

【Jvm】性能调优(上)线上问题排查工具汇总

文章目录 一.互联网概念1.产品闭环和业务闭环2.软件设计中的上游和下游3.JDK运行时常量池 二.CPU相关概念1.查询CPU信息2.CPU利用率&#xff08;CPU utilization&#xff09;和 CPU负载&#xff08;CPU load&#xff09;2.1.如何理解CPU负载2.2.top命令查看CPU负载均值2.3.CPU负…

更改WordPress作者存档链接author和Slug插件Edit Author Slug

WordPress默认所有用户的存档永久链接都是/author/username/&#xff0c;不管是管理员还是订阅者或贡献者或作者或编辑。如果你想要自定义用户存档链接&#xff0c;比如根据角色不同使用不一样的author&#xff0c;或者自定义作者链接中的用户名Slug&#xff0c;那么建议考虑使…

如何使用Docker部署Drupal并结合cpolar实现固定公网地址访问

文章目录 前言1. Docker安装Drupal2. 本地局域网访问3 . Linux 安装cpolar4. 配置Drupal公网访问地址5. 公网远程访问Drupal6. 固定Drupal 公网地址 前言 Dupal是一个强大的CMS&#xff0c;适用于各种不同的网站项目&#xff0c;从小型个人博客到大型企业级门户网站。它的学习…

选择结构switch

一、执行流程 所有case都和表达式的值不匹配&#xff0c;就会执行default语句体部分 从被匹配的位置开始执行&#xff0c;如果遇到break&#xff0c;那么退出选择结构 二、注意事项 1、case后面的【常量值】不能重复&#xff0c;不然编译器会报错 2、switch后面的小括号只…

MoonBit新增functional for loop控制流支持

1. 增加functional for loop控制流支持 与传统的命令式for loop 不同&#xff0c;循环变量是不可变的。这样的设计将来也容易抽取出来做形式化验证&#xff1a; fn init {for i 0; i < 5; i i 1 {debug(i)// i i 4 error: The variable i is not mutable.} }输出&am…

一文概括|CSC访问学者/博士后/联培申请及派出流程详解

为帮助申请者了解国家留学基金委&#xff08;CSC&#xff09;的政策&#xff0c;以及申报及派出的全过程&#xff0c;知识人网小编利用本文简略介绍并提出规划建议。 公派留学包括国家、地方&#xff08;含省市、行业、学校医院等单位&#xff09;资助派出。而国家公派则由留学…

十字星K线(Doji)含义,fpmarkets澳福一分钟讲解

许多新手交易者遇到过这种奇怪的烛台&#xff0c;看起来就像一个十字架&#xff0c;没有主体上下有长长的影子&#xff0c;fpmarkets澳福肯定的告诉各位投资者&#xff0c;这种就是十字星K线(用Doji表示)&#xff0c;开盘价与收盘价一致&#xff0c;价格运动已经停止时出现在烛…

洛谷C++简单题小练习day15—计算阶乘小程序(不用循环)

day15--计算阶乘小程序--2.19 习题概述 题目描述 求 n!&#xff0c;也就是 123⋯n。 挑战&#xff1a;尝试不使用循环语句&#xff08;for、while&#xff09;完成这个任务。 输入格式 第一行输入一个正整数 n。 输出格式 输出一个正整数&#xff0c;表示 n! 代码部分 …

从零开始的 dbt 入门教程 (dbt core 开发进阶篇)

引 在上一篇文章中&#xff0c;我们花了专门的篇幅介绍了 dbt 更多实用的命令&#xff0c;那么我们继续按照之前的约定来聊 dbt 中你可能会遇到的疑惑以及有用的概念&#xff0c;如果你是 dbt 初学者&#xff0c;我相信如下知识点一定会对你有极大的帮助&#xff1a; 了解 db…

简单贪吃蛇模拟(C语言版本·)

简单贪吃蛇模拟&#xff08;C语言版本&#xff09; 一、所需win32 API知识二、游戏逻辑实现 一、所需win32 API知识 1.在这儿&#xff0c;直接弱化概念&#xff0c;把在贪吃蛇中用到的API知识说一下&#xff01;  1.1用cmd命令来设置控制台窗口的长宽   1.2.用title 指令…

python入门----基础

这里写目录标题 重点虚拟环境/与//的区别/// 关于print字符串可以用号拼接单双引号转义符换行三引号 变量变量的定义变量名的命名 API库导库以及使用 注释单行注释多行注释 数据类型strboolNoneTypetype函数 交互模式介绍开启 input作用延伸 if-else条件嵌套语句逻辑运算符内容…

世界顶级名校计算机专业,都在用哪些书当教材?

前言 在当今信息化、数字化时代&#xff0c;计算机科学已成为全球最为热门和重要的学科之一。世界顶级名校的计算机专业&#xff0c;更是培养未来行业领袖和创新人才的重要基地。那么&#xff0c;这些名校的计算机专业究竟使用哪些教材呢&#xff1f;这些教材又具有哪些特色和…

11. Springboot集成Dubbo3(二)示例demo

目录 1、前言 2、注册中心 3、快速开始 3.1、添加dubbo3依赖 3.2、dubbo3-api ​编辑 3.3、dubbo3-server 3.3.1、添加依赖 3.3.2、实现IUserService 3.3.3、添加配置文件application.properties 3.3.4、修改Application启动类 3.3.5、出错解决 3.4、dubbo3-porta…

Golang 更严格的代码格式化工具 gofumpt

一、前言 gofmt 是 golang 自带的代码自动格式化工具&#xff0c;是保证 Go 代码风格一致的大杀器。我们这次要推荐的 gofumpt 在 gofmt 的基础上添加了一系列更加严格的格式化规则&#xff0c;并保证了对 gofmt 的兼容。 二、gofumpt 简介 gofumpt(https://github.com/mvda…

职业性格在求职应聘和跳槽中的作用

性格测试对跳槽者的影响大不大&#xff1f;首先我们要弄清楚两个问题&#xff0c;性格对我们的职业生涯又没有影响&#xff0c;性格测试是什么&#xff0c;职场中有哪些应用&#xff1f;性格可以说从生下来就有了&#xff0c;随着我们的成长&#xff0c;我们的性格也越来越根深…

2024开工大吉,便宜寄快递该怎么选呢?

随着春节的结束&#xff0c;大部分人回到了工作的岗位&#xff0c;相信许多人还沉浸在过年的喜悦的氛围中呢&#xff0c;但是我们可以期盼下一个春节的到来了&#xff0c;言归正传&#xff0c;工作中总会收发快递了&#xff0c;尤其是最近&#xff0c;需要联络客户的感情了&…