【问题标题】:how to rendering vue-component in vue file with (vue-server-renderer)如何使用 (vue-server-renderer) 在 vue 文件中渲染 vue-component
【发布时间】:2021-04-24 02:22:54
【问题描述】:

我想用 vuejs 开始渲染组件

我有一个简单的节点服务器

   const Vue = require('vue');
const server = require('express')();
const template = require('fs').readFileSync('index.template.html', 'utf-8');
const renderer = require('vue-server-renderer')
    .createRenderer({
        template
    })
const context = {
    title: 'vue ssr',
    meta: `
        <meta name="keyword" content="vue,ssr">
        <meta name="description" content="vue srr demo">
    `,
};
server.get('/test2', (req, res) => {
    res.end("test");
});

server.get('/test', (req, res) => {
    const app = new Vue({
        data: {
            url: req.url
        },
        template: `<div>The visited URL is: {{ url }}</div>`,
    });
    renderer
        .renderToString(app, context,(err, html) => {
            //console.log('app', app )
            if (err) {
                res.status(500).end('Internal Server Error')
                return;
            }
            res.end(html);
        });
})

server.listen(8080);

网址:localhost:8080/test 有效

我的问题与前面的渲染有关。 我使用 nuxt.js,并用一个简单的页面进行测试 路径:project/pages/test.vue

//// 文件 test.vue 显示渲染

<template>
  <div>
    test
  </div>
</template>
<script>
  export default {
    async asyncData({ params }) {
      try {
        let result = await fetch(`http://localhost:8080/test`)
          .then(res => res.json())
          .then(data => data);
        console.log('result', result)
        return `<span> test </span>`;
      } catch (e) {
        console.error("SOMETHING WENT WRONG :" + e);
        return `<span> error </span>`;
      }
    },
  }
</script>

调用结果:

{
  size: 0,
  timeout: 0,
  [Symbol(Body internals)]:
   { body:
      PassThrough {
        _readableState: [ReadableState],
        readable: true,
        domain: null,
        _events: [Object],
        _eventsCount: 2,
        _maxListeners: undefined,
        _writableState: [WritableState],
        writable: false,
        allowHalfOpen: true,
        _transformState: [Object] },
     disturbed: false,
     error: null },
  [Symbol(Response internals)]:
   { url: 'http://localhost:8080/test',
     status: 200,
     statusText: 'OK',
     headers: Headers { [Symbol(map)]: [Object] },
     counter: 0 } }

我的问题是如何在我的视图中显示通话内容。我没有找到回应的元素。 谢谢

Edit 1 : 更正显示一个简单的字符串或对象就可以了 #返回

server.get('/test/string', (req, res) => {
    res.json('simple chaine ')
})
server.get('/test/object', (req, res) => {
    res.json({ id: 1, name: 'un object' })
})

#前面

<template>
  <div class="container">
    <p v-if="data_error">{{ data_error }}</p>

    <h2>ASYNC Test sur une chaine de caractère</h2>
    <div><p>Display example string: {{ data_string }}</p></div>

    <h2>ASYNC Test sur un object</h2>
    <div><pre>{{ data_object }}</pre></div>
  </div>
</template>
<script>
  export default {
    async asyncData() {
      try {
        const responseString = await fetch('http://localhost:8080/test/string');
        const string = await responseString.json();

        const responseObject = await fetch('http://localhost:8080/test/object');
        const object = await responseObject.json();

        return {
          data_string: JSON.parse(JSON.stringify(string)),
          data_object: JSON.parse(JSON.stringify(object)),
          data_error: null,
        }
      } catch (e) {
        return { data_error: e }
      }
    },
  }
</script>

但是如果我想显示一个组件,我有一个问题 #返回

server.get('/test/count', (req, res) => {
    const app = new Vue({
        data: {
            count: 0
        },
        methods: {
            counter() {
                this.count++
            }
        },
        template: `<div>
            <button v-on:click="counter">click</button>
            The visited URL is: {{ count }}
        </div>`,
    });

    renderer.renderToString(app).then(html => {
        console.log(html)
        res.json(html);
    }).catch(err => {
        res.status(500).end('Internal Server Error')
        console.error(err)
    })
})

#FRONT(不工作,我只有html,没有事件,我不知道是否可能)

<template>
  <div v-html="data_compCount"></div>
</template>
<script>
  export default {
    async asyncData({ params }) {
      try {
        const responseCounter = await fetch('http://localhost:8080/test/count');
        const compCount = await responseCounter.json();
        return {
          data_compCount: JSON.parse(JSON.stringify(compCount)),
          data_error: null,
        }
      } catch (e) {
        console.error("SOMETHING WENT WRONG :" + e);
        return `<span> error </span>`;
      }
    },
  }
</script> 

【问题讨论】:

    标签: javascript node.js vue.js nuxt.js vue-server-renderer


    【解决方案1】:

    我将分为两个简单的步骤:

    第一步:在vue组件中显示一个值(任意值):

    <template>
      <div>
        Display example string: {{ example_string }}
        Another way to display a string: 
        <span v-text="example_string"></span>
    
        A way to display an object (for debugging purposes mostly):
        <pre>{{example_data}}</pre>
      </div>
    </template>
    <script>
    export default {
       data() {
           return {
              example_string: 'This is an example string',
              example_data: { id: 1, name: 'Example' }
           }
       }
    }
    </script>
    

    第 2 步:从服务器获取响应并使用数据:

    <script>
    export default {
        data() { 
            return {
                // we will fetch data from server and store them
                // in example_data. 
                example_data: null
            }
        },
    
        // To ensure the data gets loaded on page start/component initialisation:
        mounted() {
            this.loadData();
            // or: this.loadData2();
        },
    
        methods: { 
           // async await example:
           async loadData() {
              var data = await (fetch(url).then(response => response.json());
    
              this.example_data = data;
           },
    
           // without async/await:
           loadData2() {
              fetch(url).then(response => response.json()).then(data => {
                 this.example_data = data;
              });
           }
        },
    
    }
    </script>
    

    编辑:
    data() 函数是一个特殊的 Vue 函数。它返回一个对象,其值可用于您的 vue 模板内部和所有其他函数中的 this 对象。您创建的返回值的函数应该像这样重写。请注意,我无法针对任何后端进行测试,因此请将这些代码示例解释为示例:

    #返回:

    <template>
      <div class="container">
        <p v-if="data_error">{{ data_error }}</p>
    
        <h2>ASYNC Test sur une chaine de caractère</h2>
        <div><p>Display example string: {{ data_string }}</p></div>
    
        <h2>ASYNC Test sur un object</h2>
        <div><pre>{{ data_object }}</pre></div>
      </div>
    </template>
    <script>
      export default {
        // Vue's special data function
        data() {
           return {
               data_string: null,
               data_object: null,
               data_error: null
           }
        },
        // Vue's special 'mounted' (initialisation function)
        mounted() {
            // We want to load data when the page loads.
            this.asyncData();
        },
    
        methods: { 
          // Always write your function inside this methods object.
          async asyncData() {
            try {
              const responseString = await fetch('http://localhost:8080/test/string');
              const string = await responseString.json();
    
              const responseObject = await fetch('http://localhost:8080/test/object');
              const object = await responseObject.json();
    
              this.data_string = string;
              this.data_object = object;
              this.data_error = null;
            } catch (e) {
              console.error("SOMETHING WENT WRONG :" + e);
              this.data_error = e;
            }
          }
        }
      }
    </script>
    

    #FRONT:

    <template>
      <div v-html="data_compCount"></div>
    </template>
    <script>
      export default {
        // Vue data function.
        data() {
           return {
               data_compCount: null
           }
        },
        // Vue mounted function
        mounted() {
           this.asyncData();
        },
        methods: { 
          async asyncData({ params }) {
            try {
              const responseCounter = await fetch('http://localhost:8080/test/count');
              const compCount = await responseCounter.json();
    
              this.data_compCount = compCount;
              this.data_error = null;
            } catch (e) {
              console.error("SOMETHING WENT WRONG :" + e);
              this.data_error = e;
            }
          }
        }
      }
    </script> 
    

    【讨论】:

    • 1) 您是否有后端示例,因为您的异步方法与我的数据不对应。 2)你渲染了一个简单的数据或简单的字符串,但是如果你渲染一个组件,你怎么办?因为以我的后端为例,它不起作用。谢谢
    • 很高兴看到您取得了一些进展。我已经更新了答案以反映您所做的一些更改。我看到您还想使用服务器端渲染来做一些事情,并且对 Vue 来说还很陌生。我建议您首先专注于创建一个有效的 vue 前端应用程序,这样您就了解了基础知识,然后如果您觉得足够舒服,请决定为您的应用程序添加服务器端渲染功能。祝你好运!
    猜你喜欢
    • 2020-12-10
    • 1970-01-01
    • 2018-09-23
    • 2017-11-20
    • 2020-06-06
    • 2021-05-10
    • 1970-01-01
    • 1970-01-01
    • 2019-10-08
    相关资源
    最近更新 更多