vue服务端渲染axios预取数据
首先是要参考vue服务端渲染教程:https://ssr.vuejs.org/zh/data.html。
本文主要代码均参考教程得来。基本原理如下,拷贝的原文教程。
为了解决这个问题,获取的数据需要位于视图组件之外,即放置在专门的数据预取存储容器(data store)或"状态容器(state container))"中。首先,在服务器端,我们可以在渲染之前预取数据,并将数据填充到 store 中。此外,我们将在 HTML 中序列化(serialize)和内联预置(inline)状态。这样,在挂载(mount)到客户端应用程序之前,可以直接从 store 获取到内联预置(inline)状态。
依据这段话,需要使用vuex;使用vuex的代码如下:
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
// 假定我们有一个可以返回 Promise 的
// 通用 API(请忽略此 API 具体实现细节)
import { fetchItem } from '../api'
export function createStore () {
return new Vuex.Store({
state: {
items: {}
},
actions: {
fetchItem ({ commit }, id) {
// `store.dispatch()` 会返回 Promise,
// 以便我们能够知道数据在何时更新
return fetchItem(id).then(item => { commit('setItem', { id, item })
})
}
},
mutations: {
setItem (state, { id, item }) {
Vue.set(state.items, id, item)
}
}
})
}
上面的api中代码:
import api from "create-api"
export function fetchItem(id) { return new Promise(function(resolve, reject) {
api.get("http://www.youxuewang.com.cn/shouji/home/LoadProducts", {
pageno: ,
pagesize: ,
condstr: '社会大课堂:0'
}).then(function(res) {
resolve({ text: JSON.stringify(res)}); }).catch(function() {
console.log();
});
}) //return Promise.resolve(obj)
}
create-api是webpack的别名也就是alias配置,实际是两个文件,服务端文件如下
const isProd = process.env.NODE_ENV === 'production';
const axios = require('axios');
let host = isProd ? 'http://www.youxuewang.com.cn/shouji/home/LoadProducts' : 'http://www.youxuewang.com.cn/shouji/home/LoadProducts';
let cook = process.__COOKIE__ || '';
let api;
axios.defaults.baseURL = host;
axios.defaults.timeout = ;
axios.interceptors.response.use((res) => {
if (res.status >= && res.status < ) {
console.log(,res.status );
return res;
}
return Promise.reject(res);
}, (error) => {
// 网络异常
return Promise.reject({message: '网络异常,请刷新重试', err: error, type: });
});
if (process.__API__) {
api = process.__API__;
} else {
api = {
get: function(target, options = {}) {
return new Promise((resolve, reject) => {
axios.request({
url: target,
method: 'get',
headers: {
'Cookie': cook
},
params: options
}).then(res => {
resolve(res.data);
}).catch((error) => {
reject(error);
});
});
},
post: function(target, options = {}) {
return new Promise((resolve, reject) => {
axios.request({
url: target,
method: 'post',
headers: {
'Cookie': cook
},
params: options
}).then(res => {
resolve(res.data);
}).catch((error) => {
reject(error);
});
});
}
};
}
module.exports = api;
客户端用代码如下
const axios = require('axios');
let api;
axios.defaults.timeout = ;
//拦截器,使用拦截器提前对axios操控,before they are handled by then or catch.
axios.interceptors.response.use((res) => {
if (res.status >= && res.status < ) {
console.log(,res.status );
return res;
}
return Promise.reject(res);
}, (error) => {
// 网络异常
return Promise.reject({message: '网络异常,请刷新重试', err: error});
});
if (process.__API__) {
api = process.__API__;
} else {
api = {
get: function(target, params = {}) {
const suffix = Object.keys(params).map(name => {
return `${name}=${JSON.stringify(params[name])}`;
}).join('&');
const urls = `${target}?${suffix}`;
return new Promise((resolve, reject) => {
axios.get(urls, params).then(res => {
resolve(res.data);
}).catch((error) => {
reject(error);
});
});
},
post: function(target, options = {}) {
return new Promise((resolve, reject) => {
axios.post(target, options).then(res => {
resolve(res.data);
}).catch((error) => {
reject(error);
});
});
}
};
}
module.exports = api;
那么,我们在哪里放置「dispatch 数据预取 action」的代码?
我们需要通过访问路由,来决定获取哪部分数据 - 这也决定了哪些组件需要渲染。事实上,给定路由所需的数据,也是在该路由上渲染组件时所需的数据。所以在路由组件中放置数据预取逻辑,是很自然的事情。
我们将在路由组件上暴露出一个自定义静态函数 asyncData。注意,由于此函数会在组件实例化之前调用,所以它无法访问 this。需要将 store 和路由信息作为参数传递进去。
上面这句话,诞生了服务端渲染数据的路由组件有一个asyncData方法,代码如下
<template>
<div>{{ item.text }}---{{fooCount}}</div>
</template>
<script>
// 在这里导入模块,而不是在 `store/index.js` 中
import fooStoreModule from '../store/modules/foo'
export default {
asyncData ({ store,route}) {
store.registerModule('foo', fooStoreModule)
//return store.dispatch('foo/inc')
return Promise.all([
store.dispatch("fetchItem",route.params.id),
store.dispatch('foo/inc')
])
},
// 重要信息:当多次访问路由时,
// 避免在客户端重复注册模块。
destroyed () {
this.$store.unregisterModule('foo')
},
computed: {
fooCount () {
return this.$store.state.foo.count
},item () {
return this.$store.state.items[this.$route.params.id]
}
}
}
</script>
主要代码介绍如上,完成代码github链接:https://github.com/mstzhen/vue-ssr-axios。
预取数据演示访问地址:http://localhost:8080/item/22;
本文结束。
vue服务端渲染axios预取数据的更多相关文章
- [vue] vue服务端渲染nuxt.js
初始化 使用脚手架工具 create-nuxt-app 快速创建 npx create-nuxt-app <项目名> npx create-nuxt-app 执行一些选择 在集成的服务器端 ...
- Egg + Vue 服务端渲染工程化实现
在实现 egg + vue 服务端渲染工程化实现之前,我们先来看看前面两篇关于Webpack构建和Egg的文章: 在 Webpack工程化解决方案easywebpack 文章中我们提到了基于 Vue ...
- vue服务端渲染简单入门实例
想到要学习vue-ssr的同学,自不必多说,一定是熟悉了vue,并且多多少少做过几个项目.然后学习vue服务端渲染无非解决首屏渲染的白屏问题以及SEO友好. 话不多说,笔者也是研究多日才搞明白这个服务 ...
- 解析Nuxt.js Vue服务端渲染摸索
本篇文章主要介绍了详解Nuxt.js Vue服务端渲染摸索,写的十分的全面细致,具有一定的参考价值,对此有需要的朋友可以参考学习下.如有不足之处,欢迎批评指正. Nuxt.js 十分简单易用.一个简单 ...
- vue服务端渲染之nuxtjs
前言 本篇主要针对nuxtjs中的一些重要概念整理和代码实现! 在学习vue服务端渲染之前,先搞清楚几个概念: 什么是客户端渲染(CSR) 什么是服务端渲染(SSR) CSR和SSR有什么异同 客户端 ...
- vue服务端渲染提取css
vue服务端渲染,提取css单独打包的好处就不说了,在这里主要说的是抽取css的方法 要从 *.vue 文件中提取 CSS,可以使用 vue-loader 的 extractCSS 选项(需要 vue ...
- Nuxt.js vue服务端渲染
一.为什么要用Nuxt.js 原因其实不用多说,就是利用Nuxt.js的服务端渲染能力来解决Vue项目的SEO问题. 二.Nuxt.js和纯Vue项目的简单对比 1. build后目标产物不同 vue ...
- 实例PK(Vue服务端渲染 VS Vue浏览器端渲染)
Vue 2.0 开始支持服务端渲染的功能,所以本文章也是基于vue 2.0以上版本.网上对于服务端渲染的资料还是比较少,最经典的莫过于Vue作者尤雨溪大神的 vue-hacker-news.本人在公司 ...
- Vue服务端渲染和Vue浏览器端渲染的性能对比
Vue 2.0 开始支持服务端渲染的功能,所以本文章也是基于vue 2.0以上版本.网上对于服务端渲染的资料还是比较少,最经典的莫过于Vue作者尤雨溪大神的 vue-hacker-news.本人在公司 ...
随机推荐
- Spark 加载数据库mysql表中数据进行分析
1.工程maven依赖包 <properties> <spark_version>2.3.1</spark_version> <!-- elasticsear ...
- java的值传递机制
一.练习:编写Java程序,将二维数组中的行列互调显示出来. 代码1为自己编写: package com.xxgpra.CH6; public class Hangliehudiao_pra4 { p ...
- 为什么我要放弃javaScript数据结构与算法(第六章)—— 集合
前面已经学习了数组(列表).栈.队列和链表等顺序数据结构.这一章,我们要学习集合,这是一种不允许值重复的顺序数据结构. 本章可以学习到,如何添加和移除值,如何搜索值是否存在,也可以学习如何进行并集.交 ...
- day 4 __all__ 包 __init__.py
1.__all__的作用 如果一个文件中有__all__变量,那么也就意味着这个变量中的元素,不会被from xxx import *时导入 __all__ = ["test1", ...
- CF 914 D. Bash and a Tough Math Puzzle
D. Bash and a Tough Math Puzzle http://codeforces.com/contest/914/problem/D 题意: 单点修改,每次询问一段l~r区间能否去掉 ...
- mysql 题目练习
1 新建一个测试数据库: create database test1 charset utf8; 2 进入数据库 use test1; 3 新建一个sql 文件 ,将下面内容复制进sql 文件 /* ...
- mysql int类型的长度值
整数类型的存储和范围(来自mysql手册) 类型 字节 最小值 最大值 (带符号的/无符号的) (带符号的/无符号的) TINYINT 1 -128 127 0 255 SMALLIN ...
- php webservice 可能存在的坑
场景: 今天在生产机器上调用webservice失败 报 ...failed to load external entity... wget一下地址发现报500错误 把wsdl去掉再wget 发现就 ...
- Ruby 基础教程1-6
1.循环实现方法 循环语句 (while;for; loop,until) 循环方法(times,each) 2.for for 变量 in 对象 主体 ...
- VS Help Viewer 显示内容为HTML源码的问题
万恶的IE10 为了学习,安装了一套Windows Server 2012+SQL 2012+VS 2012的环境,整体感觉还不错,只是在使用Help Viewer查看帮助的时候,发现显示内容居然为H ...