1.1.数据接口
聚合数据:https://www.juhe.cn/ 申请 “新闻头条” 数据接口:https://www.juhe.cn/docs/api/id/235 (不可直接跨域访问)
注意:按照聚合数据网站的规定,进行注册以及实名认证,然后申请 “新闻头条” 数据接口。
1.2.工程目录结构
1.3.package.json文件
{"name": "topnews","version": "0.1.0","private": true,"scripts": {"serve": "vue-cli-service serve","build": "vue-cli-service build"},"dependencies": {"axios": "^0.19.2","core-js": "^3.6.5","vue": "^2.6.11","vue-router": "^3.2.0"},"devDependencies": {"@vue/cli-plugin-babel": "^4.4.0","@vue/cli-plugin-router": "^4.4.0","@vue/cli-service": "^4.4.0","vue-template-compiler": "^2.6.11"},"browserslist": ["> 1%","last 2 versions","not dead"]}
1.4.vue.config.js而文件
module.exports = {devServer:{port:8080,proxy: {'/juheNews':{target:'http://v.juhe.cn/', //需要跨域的urlws:true, //代理webSocketchangeOrigin:true, //允许跨域pathRewrite:{'^/juheNews':'' //重写路径}}}}}
1.5.main.js文件
import Vue from 'vue'import App from './App.vue'import router from './router'import axios from 'axios'Vue.prototype.$axios = axios;Vue.config.productionTip = falsenew Vue({router,render: h => h(App)}).$mount('#app')
1.6.路由配置文件
import Vue from 'vue'import VueRouter from 'vue-router'import TopNews from '../views/TopNews.vue'import TypeNews from '../views/TypeNews.vue'Vue.use(VueRouter)const routes = [{path: '/',name: 'Home',component: TopNews},{path: '/topNews',name: 'TopNews',component: TopNews},{path: '/typeNews',name: 'TypeNews',component: TypeNews}]const router = new VueRouter({routes})export default router
1.7.App.vue文件
<template><div id="app"><header>新闻头条</header><nav><ul><li :class="{navinit:isActive=='topNews'}" @click="changeNav('topNews')">头条新闻</li><li :class="{navinit:isActive=='typeNews'}" @click="changeNav('typeNews')">分类新闻</li></ul></nav><router-view /></div></template><script>export default{data(){return {isActive:'typeNews'}},created() {let path = location.href;this.isActive = path.substring(path.lastIndexOf('/')+1);},methods:{changeNav(param){this.isActive = param;if(param=='topNews'){this.$router.push('/topNews');}else if(param=='typeNews'){this.$router.push('/typeNews');}}}}</script><style>/******************** css reset ********************/html,body,div,header,nav,h1,h2,h3,h4,h5,h6,ul,li{margin: 0;padding: 0;font-family: "微软雅黑";}ul{list-style: none;}a{text-decoration: none;}header{width: 100%;height: 48px;background-color: #E03D3E;display: flex;justify-content: center;align-items: center;font-size: 20px;color: #fff;/*设置字间距*/letter-spacing: 4px;}nav{width: 100%;height: 56px;display: flex;justify-content: center;align-items: center;}nav ul{width: 160px;height: 26px;display: flex;justify-content: space-between;}nav ul li{width: 70px;height: 26px;display: flex;justify-content: center;align-items: center;}.navinit{color: #E03D3E;border-bottom: solid 2px #E03D3E;}</style>
1.8.NewsList.vue共通组件
<template>
<div>
<ul>
<li v-for="item in data" @click="toNews(item.url)">
<div class="img-box">
<img :src="item.thumbnail_pic_s">
</div>
<div class="text-box">
<h3>{{item.title | titleFilter}}</h3>
<p>{{item.author_name}} {{item.date}}</p>
</div>
</li>
</ul>
</div>
</template>
<script>
export default{
props:['data'],
methods:{
toNews(url){
location.href = url;
}
},
filters:{
titleFilter(value){
if(value.length>24){
value=value.substr(0,24)+'...';
}
return value;
}
}
}
</script>
<style scoped>
ul{
width: 100%;
}
ul li{
box-sizing: border-box;
padding: 6px;
width: 100%;
height: 93px;
display: flex;
border-bottom: dashed 1px #AAA;
user-select: none;
cursor: pointer;
}
ul li .img-box{
flex: 0 0 100px;
height: 80px;
}
ul li .img-box img{
width: 100px;
height: 80px;
}
ul li .text-box{
flex: 1;
box-sizing: border-box;
padding-left: 10px;
}
ul li .text-box h3{
font-size: 16px;
font-weight: 300;
}
ul li .text-box p{
font-size: 14px;
text-align: right;
}
</style>
1.9.TopNews.vue组件
<template>
<div>
<img src="../assets/logo.png">
<NewsList :data="newsList"></NewsList>
</div>
</template>
<script>
import NewsList from '../components/NewsList'
export default{
data(){
return {
newsList:[]
}
},
created() {
this.$axios.get('/juheNews/toutiao/index',{
params:{
type:'top',
key:'自己的key'
}
}).then(response=> {
this.newsList = response.data.result.data;
})
.catch(error=> {
console.log(error);
});
},
components:{
NewsList
}
}
</script>
<style scoped>
img{
width: 100%;
height: 100px;
display: block;
}
</style>
1.10.TypeNews组件
<template>
<div>
<div class="news-img">
<a :href="news.url">
<img :src="news.thumbnail_pic_s">
</a>
</div>
<div class="type-news">
<ul>
<li v-for="item in typeList" :class="{typeinit:isAlive==item.id}" @click="change(item.id)">
{{item.name}}
</li>
</ul>
</div>
<NewsList :data="newsList"></NewsList>
</div>
</template>
<script>
import NewsList from '../components/NewsList';
export default{
data(){
return {
typeList:[
{id:'shehui',name:'社会'},
{id:'guonei',name:'国内'},
{id:'guoji',name:'国际'},
{id:'yule',name:'娱乐'},
{id:'tiyu',name:'体育'},
{id:'junshi',name:'军事'},
{id:'keji',name:'科技'},
{id:'caijing',name:'财经'},
{id:'shishang',name:'时尚'}
],
isAlive:'shehui',
newsList:[],
news:{}
}
},
created() {
this.getNews('shehui');
},
methods:{
getNews(type){
this.$axios.get('/juheNews/toutiao/index',{
params:{
type:type,
key:'自己的key'
}
}).then(response=> {
this.newsList = response.data.result.data;
this.news = this.newsList[Math.floor(Math.random()*this.newsList.length)];
})
.catch(error=> {
console.log(error);
});
},
change(id){
this.isAlive = id;
this.getNews(id);
}
},
components:{
NewsList
}
}
</script>
<style scoped>
.news-img img{
width: 100%;
height: 200px;
display: block;
}
.type-news{
width: 100%;
margin-top: 8px;
}
.type-news ul{
width: 100%;
display: flex;
justify-content: center;
flex-wrap: wrap;
}
.type-news ul li{
box-sizing: border-box;
width: 48px;
height: 22px;
border: solid 1px #E03D3E;
border-radius: 11px;
margin: 5px 10px;
font-size: 14px;
color: #E03D3E;
display: flex;
justify-content: center;
align-items: center;
}
.typeinit{
background-color: #E03D3E;
color: #fff !important; /*!important:将优先级提升最高*/
}
</style>
[
