Skip to content

Latest commit

 

History

History
125 lines (88 loc) · 4.11 KB

genera.md

File metadata and controls

125 lines (88 loc) · 4.11 KB

genera

渲染vue的方法有两个方向:

其一和nuxt一样 基于vue官方提供的vuessr虚拟节点的渲染方式, 它支持vue的全特性, 但性能仅能满足不太复杂的网站.

其二就是将vue再编译成更高效的代码运行 也就是传统的基于字符串拼接的模板渲染方式, 这种方式能有效避免节点太多所造成的递归/动态等性能问题.

项目的目标就是高效渲染+优雅的模板语法, 故使用上述第二个方法.

go-vue-ssr命令

使用go-vue-ssr命令可以生成代码

go-vue-ssr -src=./exaple/helloworld -to=./ -pkg=./ -pkg=vuetpl

命令说明

$ go-vue-ssr -h

NAME:
   go-vue-ssr - Vue to Go compiler

USAGE:
   go-vue-ssr [global options] command [command options] [arguments...]

VERSION:
   0.0.12

DESCRIPTION:
   Hey vue go

COMMANDS:
     help, h  Shows a list of commands or help for one command

GLOBAL OPTIONS:
   --src value    The .vue files dir
   --to value     Dist dir (default: "./internal/vuetpl")
   --pkg value    pkg name
   --help, -h     show help
   --watch        watch file and rebuild (default: false)
   --version, -v  print the version

参数说明

  • src: 存放vue文件的文件夹, 支持查找子目录, 但不允许重复的文件名(因为文件名会当做组件名).
  • to: 存放生成代码的目录
  • pkg: go package name
  • watch: 启用文件监听来自动编译vue文件

此命令将在当前目录下生成所有需要的Go代码, 也就是运行时不会依赖github.com/zbysir/go-vue-ssr包.

不过在github.com/zbysir/go-vue-ssr/pkg/ssrtool里有一些处理动态数据(interface{})的工具方法可以使用, 方便你操作interface, 如

a:= map[string]interface{}{
    "info": map[string]interface{}{
        "name": "bysir",
    },
}

// 使用LookInterface方法可以方便的得到a.info.name的值.
rinterface.GetStr(a, "info.name")

编译原理

处理vue模板

vue的模板其实是标准的html.

所以使用golang.org/x/net/html包解析HTML, 得到html节点树之后再根据attr处理vue特殊的指令, 如v-if v-for, 最终得到vue节点.

处理js

在v-if或者{{}}中需要使用一些简单的js表达式, 如 v-if="a!=b && a!=c", 这样的表达式需要翻译成golang才能运行, 翻译成golang需要使用到js的AST,

使用golang的库github.com/robertkrimen/otto实现解析js代码, 没有使用node+web server实现的原因是内联的golang库性能更好, 但缺点是不支持ES6的高级语法, 如{[a]: 1}, 请避免在模板中使用这些高级语法.

指令

内置的指令有v-if, v-else, v-else-if, v-html, v-text, 内置指令又称为编译时指令, 会在编译vue模板是生成不同的go代码, 这部分指令无法再自定义(修改go-vue-ssr源码除外).

另外的指令还有自定义指令, 这是可由用户自定义的指令逻辑, 如elementUI的v-loading.

实际上除了编译时指令也可以写成自定义指令的实现方式, 不过会有部分运行时的性能损耗, 由于内置指令使用频次高, 自定义需求少, 所以还是在编译时处理最好.


和vue不同的部分:

  • <template>上可用自定义指令 与所有内置指令, 包括v-html与v-text.

动态节点 / 静态节点 / 半动态节点

静态节点 静态节点在编译时就会生成静态的字符串.

<span class="m"></span>

在最终生成的代码中是这样:

"<span class=\"m\"></span>"

动态节点 动态节点的生成发生在运行时.

满足以下条件都是动态节点:

  • 拥有指令: 由于指令中可以修改节点的属性, 只能在运行时动态生成html
  • 组件的root节点

动态节点使用方法生成: r.Tag(tagName, options).

拥有指令 或者 是组件的root节点 则统一为动态节点

半动态节点 带有 动态class/style/attr的节点由于需要在运行时确定class/style/attr, 但由于也只需要修改这些属性, 所以最终生成的代码是

<div + mixinClass() + mixinStyle + mixinAttr()>children...</div>

半动态节点相比动态节点少了方法的调用, 性能会更好一些.


回到首页