首先放下作者大大的github地址:https://github.com/Alicecss/vue-news
接下来我们一起来看项目,看下项目的项目效果
接下来我们一起来看项目哇
不同的作者大大我们会发现项目的架构都是不一样的
//index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>news</title>
</head>
<body>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
//main.js
import Vue from 'vue'
import App from './App'
import router from './router'
import store from "./vuex/store"
import axios from "axios"
import lazy from "vue-lazyload"
import "./commons/styl/index.styl"
import videoPlayer from "vue-video-player"
import vueawesomeswiper from "vue-awesome-swiper"
let imgs=require("./commons/imgs/loading.gif")
Vue.use(vueawesomeswiper)
Vue.use(videoPlayer)
Vue.prototype.$axios=axios
Vue.use(lazy,{
error:"",
loading:imgs
})
Vue.config.productionTip = false
new Vue({
el: '#app',
router,
store,
components: { App },
template: '<App/>'
})
router.push("/news")
//app.vue
<template>
<div id="app">
<!--<div class="tab">
<div class="tab-item">
<router-link to="/news">新闻</router-link>
</div>
<div class="tab-item">
<router-link to="/movies">天气</router-link>
</div>
<div class="tab-item">
<router-link to="/Recommend">推荐</router-link>
</div>
<div class="tab-item">
<router-link to="/myself">我的</router-link>
</div>
</div>-->
<router-view ></router-view>
</div>
</template>
<script>
export default {
name: 'App'
}
</script>
<style lang="stylus" scoped>
/* .tab
position absolute
z-index 100
display flex
bottom 0
width 100%
left 0
border-top 1px solid rgba(7,17,27,0.1)
background-color white
.tab-item
flex 1
text-align center
padding 10px 0
& a
text-decoration none
color rgb(7,17,27)
&.router-link-active
color red*/
</style>
//router/index.js
import Vue from 'vue'
import Router from 'vue-router'
import news from "../components/news"
import movies from "../components/weather.vue"
import Recommend from "../components/Recommend.vue"
import myself from "../components/myself"
import newsdetail from "../components/news/newsdetail.vue"
import suitable from "../components/weather/suitable.vue"
import search from "../components/searchs.vue"
Vue.use(Router)
export default new Router({
routes: [
{
path:"/news",
component:news
},
{
path:"/movies",
component:movies
},{
path:"/Recommend",
component:Recommend
},{
path:"/myself",
component:myself
},
{
path:"/newsdetail",
component:newsdetail
},
{
path:"/search",
component:search
},
{
path:"/suitable",
component:suitable
}
]
})
//router.vue
<template>
<div class="router">
<div class="tab">
<div class="tab-item">
<router-link to="/news">新闻</router-link>
</div>
<div class="tab-item">
<router-link to="/movies">天气</router-link>
</div>
<div class="tab-item">
<router-link to="/Recommend">推荐</router-link>
</div>
<div class="tab-item">
<router-link to="/myself">我的<sup v-show="promt!=0">+</sup></router-link>
</div>
</div>
</div>
</template>
<script>
export default {
components: {},
data(){
return{
}
},
computed:{
promt(){
return this.$store.state.follow.length
}
}
}
</script>
<style lang="stylus" scoped>
.tab
position fixed
z-index 100
display flex
bottom 0
width 100%
left 0
border-top 1px solid rgba(7,17,27,0.1)
background-color white
.tab-item
flex 1
text-align center
padding 10px 0
& a
text-decoration none
color rgb(7,17,27)
&.router-link-active
color red
sup
color red
height 10px
</style>
//eleheader.vue
<template>
<div class="eleheader" @click="searchs">
<div class="header">
<input type="text" class="text" placeholder="新闻/推荐">
</div>
</div>
</template>
<script>
export default {
name: "eleheader",
methods: {
searchs(){
this.$router.push("/search")
}
}
}
</script>
<style scoped lang="stylus">
.header
width 100%
height 50px
padding 10px 20px
box-sizing border-box
.text
border-radius 30px
background-color rgba(7, 17, 27, 0.1)
border none
outline none
width 100%
height 30px
text-align center
</style>
//switches.vue
<template>
<div class="switches">
<ul class="tab">
<li class="tab-item"
v-for="item,index in tabs" :key="index"
@click="newslist(index)"
:class="index==list?'active':''">
{{item}}
</li>
</ul>
</div>
</template>
<script>
export default {
name: 'switches',
props: {
tabs: {type: Array, default: null},
list:{type:Number}
},
methods:{
newslist(index){
this.$emit('newschange',index)
}
}
}
</script>
<style lang="stylus" scoped>
.switches
width 100%
.tab
display flex
width 100%
.tab-item
padding 5px 0
text-align center
flex 1
&.active
color red
</style>
//switches.vue
<template>
<div class="switches">
<ul class="tab">
<li class="tab-item"
v-for="item,index in tabs" :key="index"
@click="newslist(index)"
:class="index==list?'active':''">
{{item}}
</li>
</ul>
</div>
</template>
<script>
export default {
name: 'switches',
props: {
tabs: {type: Array, default: null},
list:{type:Number}
},
methods:{
newslist(index){
this.$emit('newschange',index)
}
}
}
</script>
<style lang="stylus" scoped>
.switches
width 100%
.tab
display flex
width 100%
.tab-item
padding 5px 0
text-align center
flex 1
&.active
color red
</style>
//scroll.vue
<template>
<div ref="wrapper" class="wrapper">
<slot></slot>
</div>
</template>
<script>
import BScroll from "better-scroll"
export default {
props: {
probeType: {
type: Number, default: 3
},
click: {
type: Boolean, default: false
},
scrollX: {
probeType: Boolean, default: false
},
beforeScroll: {
type: Boolean, default: false
},
pullup: {
type: Boolean, default: false
},
pulldown: {
type: Boolean, default: false
},
listenScroll: {
type: Boolean, default: false
},
refreshDelay: {
type: Number, default: 20
},
data: {
type: Array, default: null
}
},
methods: {
_initScroll(){
if (!this.$refs.wrapper) {
return
}
this.scroll = new BScroll(this.$refs.wrapper, {
click: this.click,
probeType: this.probeType,
scrollX: this.scrollX
})
if (this.listenScroll){
this.scroll.on('scroll',(pos)=>{
this.$emit('scroll',pos)
})
}
if(this.pullup){
this.scroll.on('scrollEnd',()=>{
if (this.scroll.y<=this.scroll.maxScrollY+50){
this.$emit('scrollToEnd')
}
})
}
if (this.beforeScroll){
this.scroll.on('beforeScroll',()=>{
this.$emit('beforeScroll')
})
}
}
},
mounted(){
setTimeout(()=>{
this._initScroll()
},20)
},
watch:{
data(){
setTimeout(()=>{
this.scroll.refresh()
},20)
}
}
}
</script>
<style lang="stylus" scoped>
.wrapper
width 100%
height 100%
</style>
//newlist.vue
<template>
<div class="newslist">
<ul class="news">
<li class="news-item border-1px"
v-for="item,index in newss"
@click="enterdetail(item)"
style="height: 100px" :key="index">
<div class="lft">
<div class="title">{{item.title}}</div>
<div class="bottom-content">
<span class="name">{{item.author_name}}</span>
<span class="date">{{item.date}}</span>
</div>
</div>
<div class="rig">
<img width="100" v-lazy="item.thumbnail_pic_s" alt="">
</div>
</li>
</ul>
</div>
</template>
<script>
export default {
props: ['types'],
name: "newlist",
data(){
return {
newss: {}
}
},
created(){
this.news()
},
methods: {
// 进入详情页
enterdetail(item){
this.$store.state.newlist=item
console.log('item1111111',item)
/*console.log(this.$store.state.newlist)*/
this.$router.push("/newsdetail")
},
//news列表传值
news(){
let types=String(this.types)
/*let host = '/api/'+'guoji'+'&key=939994f1f415919a9348ba7d7f5b1b93'*/
let host='/api/'+types
this.$axios.get(host).then((res) => {
this.newss = res.data.data.result.data
}).catch((error) => {
console.log(error)
})
}
}
}
</script>
<style scoped lang="stylus">
@import "./../../commons/styl/base.styl"
.newslist
.news
.news-item
display flex
padding 10px 10px
font-size 14px
color rgb(7, 17, 27)
border-1px(rgba(7, 17, 27, 0.2))
.title
font-size 14px
margin-top 10px
.bottom-content
position: absolute
left 10px
bottom 5px
font-size 12px
color rgba(7, 17, 27, 0.5)
.name
display inline-block
margin-right 20px
.lft
flex 7
.rig
flex 3
text-align center
padding-top 10px
img
margin auto auto
</style>
接下来看movies页面
//weather.vue
<template>
<div class="movies">
<routers></routers>
<div class="header" @click="tabss">
<span class="name" >{{weathers.citys}}</span>
<div class="selects" v-show="tabs==false">广州</div>
</div>
<div>
<div class="main" v-if="weathers.realtime">
<div v-if="weathers.realtime.weather">
<div class="info">{{weathers.realtime.weather.info}}</div>
<div class="temperature">{{weathers.realtime.weather.temperature}}</div>
<div class="wind">
<span>{{weathers.realtime.wind.direct}}</span>
<span>{{weathers.realtime.wind.power}}</span>
</div>
<div class="pm25">
<div class="number">{{Number(weathers.pm25.pm25.curPm) +
Number(weathers.pm25.pm25.level) +
Number(weathers.pm25.pm25.pm10) +
Number(weathers.pm25.pm25.pm25)}}
<span>{{weathers.pm25.pm25.quality}}</span>
</div>
</div>
</div>
</div>
<div class="everydate" v-for="item,index in weathers.weather">
<div class="item">{{item.date}}</div>
<div class="item">{{item.info.day[1]}}</div>
<div class="item">{{item.info.dawn[2]}}<sup>。</sup>~ {{item.info.day[2]}}<sup>。</sup></div>
</div>
<div class="suitable" v-if="weathers.life">
<div class="suitable-item" @click="suichange(0)">
<p>穿衣指数</p>
<p>{{weathers.life.info.chuanyi[0]}}</p>
</div>
<div class="suitable-item" @click="suichange(1)">
<p>紫外线指数</p>
<p>{{weathers.life.info.ziwaixian[0]}}</p>
</div>
<div class="suitable-item" @click="suichange(2)">
<p>运动指数</p>
<p>{{weathers.life.info.yundong[0]}}</p>
</div>
<div class="suitable-item" @click="suichange(3)">
<p>洗车指数</p>
<p>{{weathers.life.info.xiche[0]}}</p>
</div>
<div class="suitable-item" @click="suichange(4)">
<p>感冒指数</p>
<p>{{weathers.life.info.ganmao[0]}}</p>
</div>
<div class="suitable-item" @click="suichange(5)">
<p>空调指数</p>
<p>{{weathers.life.info.kongtiao[0]}}</p>
</div>
</div>
</div>
</div>
</template>
<script>
import scroll from "../base/scroll.vue"
import routers from "../base/routers.vue"
export default {
name: "movies",
components: {scroll,routers},
data(){
return {
tabs:true,
playerOptions: {},
weathers: {},
}
},
methods: {
tabss(){
if(this.tabs==true){
this.tabs=false
}else{
this.tabs=true
}
},
// 点击储存数据
suichange(num){
let info = this.weathers.life.info
if (num == 0) {
this.$store.state.suitable= info.chuanyi
this.$store.state.suitable.push('穿衣指数')
} else if (num == 1) {
this.$store.state.suitable = info.ziwaixian
this.$store.state.suitable.push('紫外线指数')
} else if (num == 2) {
this.$store.state.suitable = info.yundong
this.$store.state.suitable.push('运动指数')
} else if (num == 3) {
this.$store.state.suitable = info.xiche
this.$store.state.suitable.push('洗车指数')
} else if (num == 4) {
this.$store.state.suitable = info.ganmao
this.$store.state.suitable.push('感冒指数')
} else if (num == 5) {
this.$store.state.suitable = info.kongtiao
this.$store.state.suitable.push('空调指数')
}
this.$router.push('/suitable')
}
},
created(){
this.$nextTick(() => {
this.$axios.get('/api/shenzhen').then((res) => {
res = res.data
this.weathers = res.data.result
console.log(res.data.result)
}).catch((error) => {
console.log(error)
})
})
}
}
</script>
<style scoped lang="stylus">
.movies
.header
width 100%
padding 5px 10px
height 30px
color blue
position fixed
background white
border 1px solid rgba(7,17,27,0.1)
left 0
top 0
.selects
position absolute
left 0
top 42px
width 100%
height 50px
background white
padding 0 10px
.name
position absolute
left 50%
margin-left -25px
width 50px
font-size 20px
.main
margin-top 60px
margin-bottom 30px
text-align center
color blue
.info
margin 10px 0
font-size 20px
font-weight 700
.temperature
font-size 100px
font-family 'Adobe 黑体 Std R'
font-weight 700
.wind
span:first-child
padding-right 10px
.pm25
margin-top 10px
font-size 15px
line-height 15px
.number
padding 3px 5px
display inline-block
width 60px
border 1px solid blue
border-radius 10px
.everydate
display flex
.item
margin 5px 0
text-align center
flex 1
&:nth-child(2)
color rgba(7.17 .27 .0 .5)
.suitable
margin-bottom 50px
display flex
width 100%
overflow auto
justify-content space-around
flex-wrap wrap
.suitable-item
box-sizing border-box
margin 10px 0
border-radius 5px
height 100px
text-align center
line-height 100px
flex 0 0 30%
background linear-gradient(#00a0e9, blue)
color white
p
height 30%
</style>
//suitable.vue
<template>
<div class="suitable">
<div class="header" @click="backshang">
{{suitables[2]}}
</div>
<div class="main">
<div class="title">{{suitables[0]}}</div>
<div class="wrapper">{{suitables[1]}}</div>
</div>
</div>
</template>
<script>
export default {
components: {},
data(){
return {
}
},
methods:{
backshang(){
this.$router.back(-1)
}
},
computed:{
suitables(){
console.log('this.$store.state.suitable',this.$store.state.suitable)
return this.$store.state.suitable
}
},
created(){
}
}
</script>
<style lang="stylus" scoped>
.suitable
background rgba(7,17,27,0.1)
height 100%
.header
background white
font-size 16px
color rgba(7,17,27,0.8)
padding 10px 10px
.main
margin 20px 10px 20px 10px
background white
padding 10px
.title
color red
font-size 25px
</style>
//Recommend.vue
<template>
<div class="Recommend">
<routers></routers>
<eleheader></eleheader>
<scroll
class="scroll"
:click="true"
:probeType="3">
<div class="newslist">
<div class="banner" >
<banner :imgs="imgs"></banner>
</div>
<newslist :types="'fire'"></newslist>
</div>
</scroll>
</div>
</template>
<script>
import eleheader from "../components/news/eleheader.vue"
import banner from "../base/banner.vue"
import routers from "../base/routers.vue"
import scroll from "./../base/scroll.vue"
import newslist from "./news/newlist.vue"
export default {
components: {newslist, scroll,routers,banner,eleheader},
name: "Recommend",
data(){
return {
imgs:['../../static/imgs/1.jpg','../../static/imgs/2.jpg',
'../../static/imgs/3.jpg','../../static/imgs/4.jpg',
'../../static/imgs/5.jpg']
}
},
computed:{
swiper() {
return this.$refs.mySwiper.swiper
}
},
mounted() {
/*this.swiper.slideTo(1, 1000, false)*/
},
created(){
this.$nextTick(() => {
let host = '/R2/' + '%e5%a5%a5%e5%b7%b4%e9%a9%ac'
this.$axios.get(host).then((res) => {
}).catch((error) => {
console.log(error)
})
})
}
}
</script>
<style scoped lang="stylus">
.Recommend
.header
width 100%
height 50px
padding 10px 20px
box-sizing border-box
.text
border-radius 30px
background-color rgba(7, 17, 27, 0.1)
border none
outline none
width 100%
height 30px
text-align center
.scroll
position absolute
top 50px
bottom 50px
overflow hidden
.newslist
position relative
.banner
width 100%
height 180px
.swiper-wrapper
position: relative
width 100%
</style>
//myself.vue
<template>
<div class="myself">
<routers></routers>
<div class="myself-title">
<img class="img1" src="./../commons/imgs/brand.jpg" alt="">
<img class="img2" src="./../commons/imgs/brand.jpg" alt="">
<div class="myself-bottom">
<div class="tab">
<div class="tab-item">
<p>0</p>
<p>发表</p>
</div>
<div class="tab-item">
<p>{{promt}}</p>
<p>关注</p>
</div>
<div class="tab-item">
<p>0</p>
<p>粉丝</p>
</div>
<div class="tab-item">
<p>0</p>
<p>获赞</p>
</div>
</div>
</div>
</div>
<div class="search">
<ul class="info">
<Li class="info-item border-1px" v-for="item,index in info"
:key="index"
@click="tabs(item,index)"
>
<span>{{item}}</span>
<span class="prompt" v-if="index==1" v-show="promt!=0">+{{promt}}</span>
</Li>
</ul>
</div>
<div class="component" v-show="shows==1">
<follow @shows="showschange"></follow>
</div>
<div class="component" v-show="shows==4">
<mobile @shows="showschange"></mobile>
</div>
<div class="component" v-show="shows==0">
<zip-code @shows="showschange"></zip-code>
</div>
<div class="component" v-show="shows==2">
<loves @shows="showschange" ref="love"></loves>
</div>
<div class="component" v-show="shows==5">
<mobile-location @shows="showschange" ref="love"></mobile-location>
</div>
</div>
</template>
<script>
import follow from "./myself/follow.vue"
import routers from "../base/routers.vue"
import loves from "./myself/loves.vue"
import zipCode from "./myself/zipCode.vue"
import widgets from "./myself/widgets"
import mobile from "./myself/mobile.vue"
import mobileLocation from "./myself/mobileLocation.vue"
export default {
name: "myself",
components: {mobile,zipCode,loves,mobileLocation,routers,follow},
data() {
return {
// 控制收藏小图标
shows: null,
info: ['全国邮编查询', '历史/收藏', '爱情术语', '身份证查询', '号码吉凶', '号码归属地', '汇率']
}
},
computed:{
promt(){
return this.$store.state.follow.length
}
},
methods: {
// 子组件改变shows的值,并返回myself界面
showschange(shows){
this.shows=shows
},
//获取点击对应index
tabs(item, index){
this.shows=index
/*console.log(index)*/
if(index==2){
console.log(index)
if(this.$refs.love.datas){
this.$refs.love.datas()
/*console.log(this.$refs.love)*/
}
}
}
}
}
</script>
<style scoped lang="stylus">
@import "./../commons/styl/base.styl"
.myself
blur 10px
.myself-title
background rgba(173, 176, 170, 0.5)
padding 80px 20px
position relative
.img1
position absolute
left 0
top 0
height 100%
width 100%
opacity 0.3
z-index -1
.img2
height 50px
width 50px
border-radius 50%
.myself-bottom
position absolute
left 0
bottom 0
width 100%
margin 10px 0
.tab
display flex
.tab-item
text-align center
flex 1
p:nth-child(2)
font-size 12px
color rgba(7, 17, 27, 0.5)
.search
.info
background rgba(7, 17, 27, 0.2)
.info-item
padding 15px 20px
background white
border-1px(rgba(7, 17, 27, 0.1))
.prompt
position absolute
right 20px
display inline-block
height 30px
width 30px
line-height 30px
color red
text-align center
background rgba(7,17,27,0.1)
border-radius 20px
&:nth-child(2)
margin-bottom 10px
border none
.component
position fixed
top 0
left 0
background white
width 100%
height 100%
</style>
总的来说,作者大大的项目是非常的轻巧,里面还是有一些很有技术性处理的的呢