接着store下的js文件会被转化生状态树指向的子模块,继续说。
例,index.vue:
fetch方法中触发异步提交状态事件
<script>
import A from '~/components/ab/list'
import B from '~/components/ab/banner'
export default {
components: {
A,
B,
},
async asyncData({ app }){
//获取文章列表数据
let article = await app.$axios.get(`http://localhost:3000/ab/list?pageNum=1&pageSize=5`)
return {articleList: article.data.data}
},
async fetch({ store }) {
return Promise.all([
store.dispatch('common/fetchTitle'),
store.dispatch('common/fetchLabel')
])
},
computed: {
},
methods: {
}
}
</script>
对应组件中通过computed 方法获取状态数据
computed: {
labelList(){
return this.$store.state.common.label
}
},
nuxt错误页面和个性meta设置
layouts/error.vue,错误页面
<template>
<div>
<h2 v-if="error.statusCode==404">404页面不存在</h2>
<h2 v-else>500服务器错误</h2>
<ul>
<li><nuxt-link to="/">HOME</nuxt-link></li>
</ul>
</div>
</template>
<script>
export default {
props:['error'],
}
</script>
v-if进行判断错误类型,注意的是这个错误是需要在里script进行声明的,如果不声明程序是找不到error.statusCode的。
Meta对于SEO的设置非常重要,比如我们现在要把New这个页面设置成个性的meta和title。
pages/news/index.vue页面的链接进行修改一下,传入一个title,目的是为了在页面进行接收title,形成文章的标题。
/pages/news/index.vue
<li><nuxt-link :to="{name:'news-id',params:{id:123,title:'nuxt.com'}}">News-1</nuxt-link></li>
我们修改/pages/news/_id.vue,让它根据传递值变成独特的meta和title标签。
<template>
<div>
<h2>News-Content [{{$route.params.id}}]</h2>
<ul>
<li><a href="/">Home</a></li>
</ul>
</div>
</template>
<script>
export default {
validate ({ params }) {
// Must be a number
return /^\d+$/.test(params.id)
},
data(){
return{
title:this.$route.params.title,
}
},
//独立设置head信息
head(){
return{
title:this.title,
meta:[
{hid:'description',name:'news',content:'This is news page'}
]
}
}
}
</script>
避免子组件中的meta标签不能正确覆盖父组件中相同的标签而产生重复的现象,建议利用 hid 键为meta标签配一个唯一的标识编号。
asyncData方法获取数据
——三种方式
安装axios——npm install axios --save
1.promise
export default {
asyncData ({ params }) {
return axios.get(`https://api/post/${params.id}`)
.then((res) => {
return { title: res.data.title }
})
}
}
在pages中创建asyncData.vue,如下
<script>
import axios from 'axios'
export default {
data(){
return {
name:'hello World',
}
},
asyncData(){
return axios.get('接口')
.then((res)=>{
console.log(res)
return {info:res.data}
})
}
}
</script>
asyncData把值返回到data中,是组件渲染之前的动作,所以不能用this.info。
一定要return出去获取到的对象,这样就可以在组件中使用,这里返回的数据会和组件中data合并。
——并发
其实正常的业务中,按理来说 是一个按钮控制一个请求,处理一项业务。
但有的时候还是会出现 一个按钮控制多个并发请求的业务,这几个请求之间还没有关联。
但问题是,你得知道所有的请求处理完成之后,要给用户一个反馈的。
这个时候 如果使用传统的ajax请求的话,好像我们不知道啥时候 所有的并发请求都处理完了,或者是 那个请求出了问题 然后报出对应的错误。
其实通过一个系统的设计还是能用es5的方式处理这些并发请求的
但今天就讲解下 promise.all的用法,让你快速实现呢,promise这个东西出来也好几年了,建议能用新的语法还是用新的语法,毕竟下一代标准呢,大不了用babel转下,问题不大。
Promise.all() 方法接收一个promise的iterable类型(注:Array,Map,Set都属于ES6的iterable类型)的输入,
也不一定非得是数组, 可能es5写习惯的程序员还是比较喜欢用数组的方式
奈何这个 api实际业务中用的也比较少 ,
var promiseAll = new Set();
function s1() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('1111')
}, 1000)
})
}
function s2() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('22222222')
}, 2000)
})
}
function s3() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('333')
}, 3000)
})
}
promiseAll.add(s3());
promiseAll.add(s2());
promiseAll.add(s1());
Promise.all(promiseAll).then(res => {
// 输出结果 [ '333', '22222222', '1111' ]
console.log(res);
}).catch((err) => {
console.log(err);
})
声明一个可迭代的对象,然后promise对象推入进去,不要只是把函数名字推进去,是promise对象,也就是你函数的执行结果,要不你就直接放入一个promise对象。
Promise.all 当且仅当传入的可迭代对象为空时为同步。
但是执行成功的还是成功执行的,只是失败的那个失败,而且整个promise状态也变成失败,会被catch捕获到。
promise使用延伸:
先来个动脑题目,输出结果是什么?
let promise = new Promise(function (resolve,reject) {
console.log('Hello');
resolve();
});
promise.then(function () {
console.log('World!');
});
console.log('the');
结果:Hello ,the,World
<html>
<script>
function getData(str) {
return new Promise((resolve, reaject) => {
setTimeout(() => resolve(str), Math.random()*3000);
})
}
function getAllData() {
var all_str = '';
getData('事').then(res => all_str += res);
getData('事').then(res => all_str += res);
getData('顺').then(res => all_str += res);
getData('利').then(res => all_str += res);
setTimeout(() => {
document.getElementById('tripe').innerHTML = all_str;
}, 3000)
}
</script>
<body>
<button onclick="getAllData()">获取数据</button>
<div>
<h1>内容都显示在这里</h1>
<div id="tripe"></div>
</div>
</body>
</html>
组成“事事顺利”四字成语,但是由于设置的存储时间是随机的,导致每次生成的数据顺序都是打乱的,怎么解决这个问题呢?
setTimeout(() => resolve(str), Math.random()*3000),改成setTimeout(() => resolve(str), 0)。
用promise实现顺序请求
<html>
<script>
function getData(str) {
return new Promise((resolve, reaject) => {
setTimeout(() => resolve(str), 0);
})
}
function getAllData() {
var all_str = '';
getData('望').then(res => all_str += res);
var promise = new Promise(function (resolve,reject) {
getData('子').then(res => all_str += res);
resolve();
});
promise.then(function () {
getData('龙').then(res => all_str += res);
});
getData('成').then(res => all_str += res);
setTimeout(() => {
document.getElementById('tripe').innerHTML = all_str;
}, 3000)
}
</script>
<body>
<button onclick="getAllData()">获取数据</button>
<div>
<h1>内容都显示在这里</h1>
<div id="tripe"></div>
</div>
</body>
</html>
2.async/await
上面的有点过时,用async/await修改:
export default {
async asyncData ({ params }) {
const { data } = await axios.get(`https://api/post/${params.id}`)
return { title: data.title }
}
}
<script>
import axios from 'axios'
export default {
data(){
return {
name:'hello World',
}
},
async asyncData(){
let {data}=await axios.get('接口')
return {info: data}
}
}
</script>
3.回调
export default {
asyncData ({ params }, callback) {
axios.get(`https://api/post/${params.id}`)
.then((res) => {
callback(null, { title: res.data.title })
})
}
}
——