Skip to content

视图


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 待完善暂不可用

备案号:冀ICP备20015584号-2