【別貪心】vue-news
阿新 • • 發佈:2020-07-30
首先放下作者大大的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>
總的來說,作者大大的專案是非常的輕巧,裡面還是有一些很有技術性處理的的呢