视图
View()
采用SSR服务端渲染技术可以直接将 .html
或 .vue
或 .tsx
文件渲染成网页,使开发服务端渲染页面更加简单。不过目前还是实验阶段,某些三方库和组件库并不支持,后续会对这里进行优化或重构,但任然会保持目前的调用形式。有感兴趣的小伙伴也可以联系我,参与解决目前存在的问题。
- @param
url
视图路径 后缀可带可不带 - @param
data
视图的数据 - @param
type
模板引擎的类型,默认是vue, 可以指定为react或layui
默认
(
url: string,
data: Object = {},
type: TMPType = 'vue'
)
(
url: string,
data: Object = {},
type: TMPType = 'vue'
)
示例1 (推荐,Layui模板引擎的方式,简单稳定)
控制器调用渲染并传入数据
import { Controller, View } from 'think-ts-lib'
export default class HelloController extends Controller {
// 用于演示Layui视图界面
showLayuiIndex() {
return View('index', {
count: 9863763,
title: 'ThinkTS',
subtitle: '欢迎使用ThinkTS框架'
})
}
}
import { Controller, View } from 'think-ts-lib'
export default class HelloController extends Controller {
// 用于演示Layui视图界面
showLayuiIndex() {
return View('index', {
count: 9863763,
title: 'ThinkTS',
subtitle: '欢迎使用ThinkTS框架'
})
}
}
views/index.html
文件中遵循固定格式, 在三大标签中写 <template>
<script>
<style>
Layui文档:https://layui.dev
<template>
<div id="layui-app"></div>
<script id="template" type="text/html">
<div class="page">
<div class="expression">:)</div>
<h1>{{ d.title }}</h1>
<h2>{{ d.subtitle }}</h2>
<div class="linkBox">
<a href="https://www.thinkts.com">完全开发手册</a>
<a href="https://github.com/zy598586050/think-ts-lib">GitHub源码</a>
<a @click="clickLike" id="like">点击喜欢:{{ d.count }}</a>
</div>
</div>
<footer class="footer">
<div class="container">
<p>© 2023 ThinkTS. All Rights Reserved.</p>
<p>备案号:冀ICP备20015584号-2</p>
</div>
</footer>
</script>
</template>
<script>
layui.use('laytpl', () => {
const laytpl = layui.laytpl
const tpl = document.getElementById('template').innerHTML
const data = JSON.parse('<!--ssr-data-->')
const layuiApp = document.getElementById('layui-app')
// 提取渲染模板的函数
const renderTemplate = () => {
const template = laytpl(tpl).render(data)
layuiApp.innerHTML = template
// 重新绑定点击事件
const likeButton = document.getElementById('like')
if (likeButton) {
likeButton.addEventListener('click', () => {
data.count++
renderTemplate()
})
}
};
// 初始渲染
renderTemplate()
})
</script>
<style>...</style>
<template>
<div id="layui-app"></div>
<script id="template" type="text/html">
<div class="page">
<div class="expression">:)</div>
<h1>{{ d.title }}</h1>
<h2>{{ d.subtitle }}</h2>
<div class="linkBox">
<a href="https://www.thinkts.com">完全开发手册</a>
<a href="https://github.com/zy598586050/think-ts-lib">GitHub源码</a>
<a @click="clickLike" id="like">点击喜欢:{{ d.count }}</a>
</div>
</div>
<footer class="footer">
<div class="container">
<p>© 2023 ThinkTS. All Rights Reserved.</p>
<p>备案号:冀ICP备20015584号-2</p>
</div>
</footer>
</script>
</template>
<script>
layui.use('laytpl', () => {
const laytpl = layui.laytpl
const tpl = document.getElementById('template').innerHTML
const data = JSON.parse('<!--ssr-data-->')
const layuiApp = document.getElementById('layui-app')
// 提取渲染模板的函数
const renderTemplate = () => {
const template = laytpl(tpl).render(data)
layuiApp.innerHTML = template
// 重新绑定点击事件
const likeButton = document.getElementById('like')
if (likeButton) {
likeButton.addEventListener('click', () => {
data.count++
renderTemplate()
})
}
};
// 初始渲染
renderTemplate()
})
</script>
<style>...</style>
示例2
控制器调用渲染并传入数据
import { Controller, View } from 'think-ts-lib'
export default class HelloController extends Controller {
// 用于演示视图界面
showIndex() {
return View('index', {
count: 9863763,
title: 'ThinkTS',
subtitle: '欢迎使用ThinkTS框架'
})
}
}
import { Controller, View } from 'think-ts-lib'
export default class HelloController extends Controller {
// 用于演示视图界面
showIndex() {
return View('index', {
count: 9863763,
title: 'ThinkTS',
subtitle: '欢迎使用ThinkTS框架'
})
}
}
由于SSR是需要同构水合的,所以还需要在build目录下创建和页面名称相同的模块目录,以index为例,你可以复制这个文件夹,并对其中的内容进行修改
index.html文件
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>ThinkTS For Vue SSR</title>
</head>
<body>
<!-- 关键是这里,指定了构建时的入口文件 -->
<script type="module" src="./index.ts"></script>
</body>
</html>
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>ThinkTS For Vue SSR</title>
</head>
<body>
<!-- 关键是这里,指定了构建时的入口文件 -->
<script type="module" src="./index.ts"></script>
</body>
</html>
index.ts文件(index的构建入口文件)
import { createApp } from 'vue'
import App from '../../app/views/index.vue'
// 这里传入的参数,一定要和控制器里View中传入的一致才可以水合,否则会报错
createApp(App, { ssrData: {
count: 9863763,
title: 'ThinkTS',
subtitle: '欢迎使用ThinkTS框架'
} }).mount('#app')
import { createApp } from 'vue'
import App from '../../app/views/index.vue'
// 这里传入的参数,一定要和控制器里View中传入的一致才可以水合,否则会报错
createApp(App, { ssrData: {
count: 9863763,
title: 'ThinkTS',
subtitle: '欢迎使用ThinkTS框架'
} }).mount('#app')
index.vue文件
<template>
<div class="page">
<div class="expression">:)</div>
<h1>{{ ssrData.title }}</h1>
<h2>{{ ssrData.subtitle }}</h2>
<div class="linkBox">
<a href="https://www.thinkts.com">完全开发手册</a>
<a href="https://github.com/zy598586050/think-ts-lib">GitHub源码</a>
<a @click="clickLike">点击喜欢:{{ localCount }}</a>
</div>
<Footer />
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import Footer from './footer.vue'
const props = defineProps(['ssrData'])
const localCount = ref(props.ssrData.count)
const clickLike = () => {
localCount.value++
}
</script>
<style>
* {
padding: 0;
margin: 0;
}
</style>
<style lang="scss">...</style>
<template>
<div class="page">
<div class="expression">:)</div>
<h1>{{ ssrData.title }}</h1>
<h2>{{ ssrData.subtitle }}</h2>
<div class="linkBox">
<a href="https://www.thinkts.com">完全开发手册</a>
<a href="https://github.com/zy598586050/think-ts-lib">GitHub源码</a>
<a @click="clickLike">点击喜欢:{{ localCount }}</a>
</div>
<Footer />
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import Footer from './footer.vue'
const props = defineProps(['ssrData'])
const localCount = ref(props.ssrData.count)
const clickLike = () => {
localCount.value++
}
</script>
<style>
* {
padding: 0;
margin: 0;
}
</style>
<style lang="scss">...</style>
构建
最后需要执行 npm run build:vue
去构建vue,之后才可以正常通过路由访问页面。
注意
vue
目前只支持使用Options API
的形式public/index.html
为根页面模板, 可自定义修改script
标签里不可以使用导入,所以这里子组件直接指定的是文件路径react
待完善暂不可用