接上篇《17.Vue实现动态路由传值》
上一篇我们讲解了如何通过类似Get请求传值的方式,给路由传递参数,本篇我们来根据上两篇学习的知识,来编写一个真正的新闻查看模块。
本系列博文使用的Vue版本:2.6.11
一、需要调用的API
这里使用“PhoneGap中文网”提供的免费app的API进行测试。
1、新闻列表API
url:http://www.phonegap100.com/appapi.php?a=getPortalList&catid=20&page=1 其中a指定接口的名字,这里接口名为“getPortalList”。catid为新闻每页的加载量,page为新闻页数。
效果(工具为PostMan):
用浏览器直接访问会出现类似“\u3010\u56fd”的16进制Unicode码,可以转义成中文:
2、新闻详情API
url:http://www.phonegap100.com/appapi.php?a=getPortalArticle&aid=497 其中a指定接口的名字,这里接口名为“getPortalArticle”。aid为新闻的id。通过该链接可以跳转至新闻的详情页面。
效果(工具为PostMan):
用浏览器直接访问会出现类似“\u3010\u56fd”的16进制Unicode码,可以转义成中文:
其中类似“\u3010\u56fd”的是16进制的Unicode码,可以转义成中文。
准备好API后,我们开始编写新闻页面。
二、编写新闻列表页
1、配置Vue路由
路由的基础配置这里就不详细说了,和之前的一样,步骤为:
(1)安装并引入vue-router
(2)配置路由(创建组件并引入组件、定义路由、创建和挂载根实例)
(3)引用并访问路由内容(路径访问、超链接挂载)
具体可查看之前的博文《【Vue学习总结】16.Vue中的路由以及默认路由跳转》第2段。
这里记得把原来News新闻的路由,由带参(aid)修改为不带参数,一是因为编写的样例不需要再区分新闻类型,二是方便我们编写本节样例:
//2、定义路由
const routes = [
{path:'/helloWorld',component: HelloWorld},
{path:'/news',component: News}, //{path:'/news/:aid',component: News},
{path:'/content/:cid',component: Content},
{path:'/',component: HelloWorld}
]
2、请求网络数据的准备
因为我们需要请求网络数据,需要类似ajax的请求,这里我们还是使用之前用的vue-resource(vue-resource是Vue.js的一款插件,它可以通过XMLHttpRequest或JSONP发起请求并处理响应),使用方法和ajax类似,之前也说过,这里不再展开,具体可以查看之前的博文《【Vue学习总结】12.使用vue-resource请求网络数据》。
3、请求新闻列表并展示
首先清空原来的News.vue新闻页面,准备编写代码:
<template>
<div class="News">
<h1>新闻组件</h1>
<ul>
<li></li>
</ul>
</div>
</template>
<script>
export default {
name: 'News',
data () {
return {
title:'新闻列表',
list:[]
}
},
methods:{
}
}
</script>
<style scoped>
</style>
首先我们在methods中添加请求网络数据的代码,获取API中的新闻列表:
<script>
export default {
name: 'News',
data () {
return {
title:'新闻列表',
list:[]
}
},
methods:{
requestData(){
var api_url="http://www.phonegap100.com/appapi.php?a=getPortalList&catid=20&page=1";
this.$http.jsonp(api_url).then(
function(response){
console.log(response);
},function(err){
console.log(err);
}
);
}
},
mounted(){
this.requestData();
}
}
</script>
此时先打印请求到的数据信息,看看对不对:
发现可以请求到数据,然后我们根据API结果的格式得出,response.body.result是我们需要的列表数据集(其中title是新闻标题),我们把该数据集给list数组,然后在<template>中遍历该数组,完整代码:
<template>
<div class="News">
<h1>新闻组件</h1>
<ul>
<li v-for="item in list" :key="item.aid">
<router-link :to="'/content/'+item.aid">{{item.aid}}--{{item.title}}</router-link>
</li>
</ul>
</div>
</template>
<script>
export default {
name: 'News',
data () {
return {
title:'新闻列表',
list:[]
}
},
methods:{
requestData(){
var api_url="http://www.phonegap100.com/appapi.php?a=getPortalList&catid=20&page=1";
var that = this;//这里重新指定this 是因为在 then的内部不能使用Vue的实例化的this, 因为在内部 this 没有被绑定。
//jsonp支持跨域请求,后台api接口也需要支持
this.$http.jsonp(api_url).then(
function(response){
console.log(response);
that.list=response.body.result;
},function(err){
console.log(err);
}
);
}
},
mounted(){
this.requestData();
}
}
</script>
<style scoped>
</style>
此时我们就实现了新闻列表的效果,结果:
三、为新闻添加跳转详情
上面实现了新闻的列表展示功能,但是点击超链接还跳不到新闻的详情页,我们来添加一下。
这里我们每个新闻链接的是原来的“/content/:cid”路由,其中的cid就是新闻的id:
<router-link :to="'/content/'+item.aid">{{item.aid}}--{{item.title}}</router-link>
我们来到Content页面,将原来的静态数据清空,使用第二个API来获取新闻的详情信息,并反馈到页面。
这里我们先访问其中一个新闻,观察其json结构,可以看到response.body.result[0]下面是我们需要的数据,title是新闻名,content是新闻内容:
那我们就根据这个结构,解析详情请求结果,并展示在页面上。
完整代码:
<template>
<div class="Content">
<h1>{{title}}</h1>
<!-- 直接写{{content}}会显示html代码,需要通过v-html转义 -->
<div v-html="content"></div>
</div>
</template>
<script>
export default {
name: 'Content',
data () {
return {
title:'暂无标题',
content:'暂无内容',
cid:0
}
},
mounted(){
//获取动态路由传递的参数
this.cid = this.$route.params.cid;
this.requestData();
},
methods:{
requestData(){
var api_url="http://www.phonegap100.com/appapi.php?a=getPortalArticle&aid="+this.cid;
var that = this;//这里重新指定this 是因为在 then的内部不能使用Vue的实例化的this, 因为在内部 this 没有被绑定。
//jsonp支持跨域请求,后台api接口也需要支持
this.$http.jsonp(api_url).then(
function(response){
console.log(response);
that.title=response.body.result[0].title;
that.content=response.body.result[0].content;
},function(err){
console.log(err);
}
);
}
}
}
</script>
<style scoped>
</style>
效果:
四、添加样式
写完的页面效果不好看,我们可以编写css样式,来使页面更加的好看。我们在工程的assets文件夹下创建一个css文件夹,创建一个basic.css,用来存放公共样式:
在basic.css中编写一些基础样式:
@charset "utf-8";
body, div, ul, li, ol, h1, h2, h3, h4, h5, h6, input, textarea, select, p, dl, dt, dd, a, img, button, form, table, th, tr, td, tbody, article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section {
margin: 0;
padding: 0;
}
html{
font-size: 62.5%;
}
body {
font: 12px/1.5 'Microsoft YaHei','宋体', Tahoma, Arial, sans-serif;
color: #555;
background-color: #F7F7F7;
}
em, i {
font-style: normal;
}
ul,li{
list-style-type: none;
}
strong {
font-weight: normal;
}
.clearfix:after {
content: "";
display: block;
visibility: hidden;
height: 0;
clear: both;
}
然后在main.js中引入该公共css:
import './assets/css/basic.css';
然后我们使用谷歌浏览器,切换到手机的查看窗口,可以看到样式已经变的好看一些了:
我们再给根组件App.vue加一些内部样式,顺便把首页和新闻的超链接加上:
<template>
<div id="app">
<h2>{{msg}}</h2>
<div class="header-css">
<router-link to="/helloWorld">首页</router-link>
<router-link to="/news">新闻</router-link>
</div>
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'app',
data () {
return {
msg: '你好,vue'
}
}
}
</script>
<style>
.header-css{
height: 4.4rem;
background: black;
color: white;
line-height: 4.4rem;
text-align: center;
}
.header-css a{
color: white;
padding: 0 2rem;
}
</style>
效果:
此时观察我们的详情页,发现内容展示宽度太大:
这时我们需要把它缩到一个手机屏幕的宽度,所以需要修改一下Content页面的样式:
<template>
<div class="Content">
<h1>{{title}}</h1>
<!-- 直接写{{content}}会显示html代码,需要通过v-html转义 -->
<div class= "con" v-html="content"></div>
</div>
</template>
<script>
//...此处代码省略
</script>
<style>
/* 设置内容演示的内边距和行高 */
.con{
padding: 1rem;
line-height: 2;
}
/* 图片的宽度设为最大为屏幕的100% */
.con img{
max-width: 100%;
}
</style>
效果(图片和屏幕同宽):
至此,我们的新闻模块样例编写完成。
参考:
《IT营:itying.com-2018年Vue2.x 5小时入门视频教程》