Skip to content

A precompilation template engine for go, template syntax like vue.

Notifications You must be signed in to change notification settings

zbysir/go-vue-ssr

Folders and files

NameName
Last commit message
Last commit date
May 30, 2020
May 25, 2020
Jun 19, 2020
Aug 24, 2020
Nov 21, 2019
Oct 31, 2020
Jun 19, 2020
May 18, 2020
Feb 23, 2023
Feb 23, 2023
Apr 9, 2020

Repository files navigation

Go-vue-ssr

GoDoc Go ReportCard

A precompilation template engine for go, template syntax like vue. https://zbysir.github.io/go-vue-ssr

Hey vue go

Related

Cause

服务端渲染相较于前端渲染有以下好处:

  • 利于内容型网站的SEO.
  • 在性能更差的手机端浏览体验更佳.

而服务端渲染又有两个方向:

  • 现代js框架vue/react所出的服务端渲染方案
  • 传统的模板引擎, 如raymond

各有优缺点

  • js框架性能不好(这是后话了)
  • 传统模板引擎在代码复杂的情况下并不美观, 在处理class/style方面也没有现代js框架方便.

由于代码洁癖与对于未知事物的好奇, 我初期还是选用的nuxt, 但后来发现它并不是银弹:

  • 前后端同构需要客户端激活步骤, 也就是在前端重新渲染一遍页面, 如果你的网站大多是静态的内容那么这一步就会造成很大的性能浪费(请不要小看客户端激活所带来的性能消耗).
  • 由于不是专职note语言, 所以在面临高级问题上(如并发/缓存)举步维艰, 对利于后期扩展.

关于vuessr性能问题可以查阅这两篇文章:

为了解决性能与美观的问题, 不得不重新思考, 这就是这个项目诞生的原因.

它将尽力保留vue的特性, 如组件化, Custom Directives, Class and Style Bindings, 相信这些现代特性对于编写html代码是有利的.

Who need Go-vue-ssr

项目的目的是高效渲染+优雅的模板语法, 并没有实现vue的js部分的特性, 所以它更适用于如官网/活动页等功能不强的页面, 而不适用于如后台管理系统这样功能性强的系统.

Feature

基于字符串拼接 而不是 虚拟节点来渲染vue组件, 当然这样做有好有坏.

优点是性能至少能提升1个数量级, 缺点是舍去虚拟节点也就无法实现vue的数据绑定特性.

Example & Usage

完整代码在这

编写vue组件代码如下: (仅支持template块)

<!--info.vue-->
<template>
  <div style="text-align: center">
    <p v-text="slogan" style="padding: 10px 0"></p>
    <img height="50px" alt="todo logo" :src="logo">
  </div>
</template>

执行go-vue-ssr来编译vue模板

go-vue-ssr -src=./vue -to=./ -pkg=main

tips: 你可以使用 -watch参数来启用监听文件变化自动编译.

生成的代码会存放在当前目录下, 内容如下:

// Code generated by go-vue-ssr: https://github.com/zbysir/go-vue-ssr

package main

func NewRender() *Render{
    r:=&Render{}
    r.components = map[string]ComponentFunc{"component": r.Component_component,"info": r.Component_info,"slot": r.Component_slot,}
    return r
}

func (r *Render) Component_info(options *Options) string {
	this := extendMap(r.Prototype, options.Props)
	_ = this
	return r.Tag("div", true, &Options{Style: map[string]string{"text-align": "center"},
		StyleKeys: []string{"text-align"},
		Slot: map[string]namedSlotFunc{"default": func(props map[string]interface{}) string {
			return "<p style=\"padding: 10px 0; \">" + interfaceToStr(lookInterface(this, "slogan"), true) + "</p><img" + mixinAttr(nil, map[string]string{"alt": "todo logo", "height": "50px"}, map[string]interface{}{"src": lookInterface(this, "logo")}) + "></img>"
		}},
		P: options,
	})
}

再编写一个main方法来调用代码

package main

func main()  {
    r := NewRender()
    htmlStr := r.Component_page(&Options{
    	Props: map[string]interface{}{
    		"slogan": "Hey vue go",
    		"logo":   "https://avatars2.githubusercontent.com/u/13434040?s=88&v=4",
    	},
    })
    print(htmlStr)
}

Supported Vue Template Syntax


完整文档请看 https://zbysir.github.io/go-vue-ssr