繁体   English   中英

如何使用(vue-server-renderer)在 vue 文件中渲染 vue-component

[英]how to rendering vue-component in vue file with (vue-server-renderer)

我想用 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);

A url: localhost:8080/test works 在此处输入图像描述

我的问题与前面的渲染有关。 我使用 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 } }

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

编辑 1 :更正显示一个简单的字符串或 object 可以 #BACK

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>

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

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> 

我将通过两个简单的步骤将其分解:

第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() function 是一个特殊的 Vue function。 它返回一个 object,其值可用于您的 vue 模板内部以及所有其他 function 中的this 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 {
    // 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>

#正面:

<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> 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM