1、移動端項目的創建
新建一個項目---->在src/components目錄路徑下新建一個common文件夾 用於存放屢次複用的組件 再新建一個page文件夾 用於存放頁面組件----->在page文件夾中新建home.vue---->在router/index.js中寫path路徑讓「/」時切換到home頁面
在src下新建一個style文件夾用於存放css 引用這個css的方法是:在CMD中按裝 cnpm i node-sass sass-loader --save-dev (很是容易丟包 形成不能在style中用@import方法引入 因此須要在script中用import 「路徑」的方法映入css文件 在style中直接定義變量並使用),注意用rem作單位
2、 sass與scss的區別:
scss是sass的升級版 可使用花括號{ }進行嵌套,還新增了簡單的計算功能等。。。。。
在home.vue中引用css
<style lang="scss"> // 在scss中是$定義變量 lang=「scss」 用於識別scss語法
$c:red
div{
color:$c
}
</style>
在scss中倒入樣式文件 @import(空格)"文件路徑" 不特指css文件 也能夠倒入scss文件
在style中新建reset.css 用於設置公共樣式 並利用@import將其引入home.vue
在style中新建var.css 用於經過變量設置樣式 並利用@import將其引入home.vue 這樣就能夠在引用變量設置樣式 $sc:25
在index.html中的script中設置根元素的font-size
index.html
<script>
document.documentElement.style.fontSize = document.documentElement.clientWidth/15+'px'; //documentElement 表明的是dom元素也就是根元素
</script>
375/15=25 因此設置$sc爲25
在home.vue中的template中寫<header> <footer> <rooter-view/>------->在style中寫scss樣式 ----->在page文件夾中新建home.vue中包含的各類組件----->在router/index.js中引入須要的組件 而且設定路由
3、引入iconfont的方法:
iconfont 官網 搜索須要的icon ----->加入購物車---->添加到對應的項目----->複製對應的鏈接在index.html中用外鏈的方式引入(每次引入新的icon須要更新鏈接)----->在對應的<i>標籤中加入icon碼。
<i class='iconfont logo'></i>
完整代碼 11.30隨堂總結/p3
index.html
<link rel="stylesheet" type="text/css" href="//at.alicdn.com/t/font_944598_oozhva7wh9.css"/> <!--引入iconfont-->
<script>
document.documentElement.style.fontSize = document.documentElement.clientWidth/15 + 'px'; //設置dom的字體大小
</script>
main.js
import Vue from 'vue'
import App from './App'
import router from './router'
import VueJsonp from 'vue-jsonp'
import MintUI from 'mint-ui'
import 'mint-ui/lib/style.css'
Vue.use(MintUI)
Vue.use(VueJsonp)
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
components: { App },
template: '<App/>'
})
components/page/home.vue
<template>
<div>
<header>
<i class='iconfont left'></i>
<router-link to="/search"><i class='iconfont right'></i></router-link>
<div id="nav" class="nav"> <!--導航欄 -->
<div id="leftnav" class="leftnav">
<div class="swiper-container2 " >
<div class="swiper-wrapper w">
<div class="swiper-slide" v-for="(item,index) in title"v-bind:class="{'active':curIndex===index}">
{{item.text}} <!--循環標題遍歷導航欄-->
</div>
</div>
</div>
</div>
<div><i class="iconfont t"></i></div>
</div>
</header>
<router-view class="content"/><!--這裏面裝的是子組件,經過router-link改變子組件變換中間部分的內容-->
<footer>
<ul>
<li><router-link to="/home/index"><i class='iconfont logo'></i>首頁</router-link></li>
<li><router-link to="/home/video"><i class='iconfont logo'></i>視頻</router-link></li>
<li><router-link to="/home/subscribe"><i class='iconfont logo'></i>訂閱</router-link></li>
<li><router-link to="/users"><i class='iconfont logo'></i>我的</router-link></li>
</ul>
</footer>
</div>
</template>
<script>
import '@/style/reset.css'
import axios from 'axios'
import Swiper from 'swiper'
import '../../../node_modules/swiper/dist/css/swiper.css'
export default{
data(){
return{
news:[],//這是從接口中請求的全部數據都存放在這裏面
curIndex:0,
title:[
{
text:'頭條',
type:'index'
},
{
text:'娛樂',
type:'pcent'
},
{
text:'科技',
type:'pctech'
},
{
text:'體育',
type:'yl'
},
{
text:'財經',
type:'yl'
},
{
text:'軍事',
type:'yl'
},
{
text:'音樂',
type:'yl'
},
{
text:'熱點',
type:'yl'
},
{
text:'視頻',
type:'yl'
},
{
text:'奇趣',
type:'yl'
},
{
text:'圖片',
type:'yl'
},
{
text:'電影',
type:'yl'
},
{
text:'歷史',
type:'yl'
},
{
text:'內地',
type:'yl'
},
{
text:'國際',
type:'yl'
}
]
}
},
mounted(){
var vm = this //1)爲當前的this是swiper對象 因此要指定一個vm來初始化this
new Swiper(".swiper-container2",{ //導航欄實例化swiper 讓導航欄能夠滑動
freeMode:true,
slidesPerView:"auto",
on:{ //on是事件處理函數
click(){
//alert(this.clickedIndex) //swiper上的屬性能夠看到當前點擊的下標
//console.log(this) //是Swiper對象,裏面包含了許多屬性
//console.log(this.wrapperEl.clientWidth) //這樣能夠獲取到包裹全部元素的那個容器的寬度
vm.curIndex=this.clickedIndex // 2)
var el = this.slides[this.clickedIndex] //獲取當前點擊的那個元素
var elpos=el.offsetLeft+el.clientWidth/2 ; //當前點擊元素的位置 el.clientWidth/2 是當前元素的中心點
var swiperwrapperWidth=this.wrapperEl.clientWidth //導航欄包裹部分的寬度
var maxDis=this.maxTranslate() //滾動的最大距離
var maxPos=-maxDis+swiperwrapperWidth/2 ;//最大的中心位置
//console.log(maxDis,swiperwrapper,elpos)
if(elpos<swiperwrapperWidth/2){ //若是元素當前位置小於容器寬度的一半那麼就讓它迴歸到0
this.setTranslate(0)
}else if(elpos>maxPos){
this.setTranslate(maxDis)
}else{
this.setTranslate(swiperwrapperWidth/2-elpos)
}
this.setTransition(500) //設置滑動時間
if(vm.curIndex===0){
vm.$router.push({'name':'index'})
}else{
vm.$router.push('/home/'+vm.title[vm.curIndex].type)
}
}
}
})
},
}
</script>
<style lang="scss" >
$sc:25;
header{
width:100%;
height:75/$sc+rem;
background: #fff;
position: fixed;
top:0;
left:0;
.left{
float:left;
margin-left: 10/$sc+rem;
margin-top: 10/$sc+rem;
}
.right{
float:right;
margin-right: 20/$sc+rem;
margin-top: 10/$sc+rem;
}
}
#nav{
display:flex;
width: 100%;
height:37.5/$sc+rem;
line-height:37.5/$sc+rem;
}
.leftnav{
width:90%;
overflow: hidden;
}
.t{
margin-left: 5/$sc+rem;
font-size:17/$sc+rem
}
.w div{
width:50/$sc+rem;
text-align: center;
font-size:17/$sc+rem
}
.active{
color:yellowgreen;
border-bottom: 6/$sc+rem solid yellowgreen;
}
.content{
position:absolute;
top:75/$sc+rem;
left: 0;
bottom: 49/$sc+rem;
right: 0;
background:#fff;
overflow-y: auto;
}
footer{
width: 100%;
background:#fff;
position:absolute;
bottom: 0;
left: 0;
ul{
display: flex;
li{
flex: 1;
text-align: center;
height:49/$sc+rem;
a{
color: #000;
display:inline-block ;
margin-top:0.4rem ;
font-size:14/$sc+rem;
.logo{
display: block;
font-size:14/$sc+rem;
}
}
}
}
}
</style>
src/style/reset.css
body,ol,ul,h1,h2,h3,h4,h5,h6,p,th,td,dl,dd,form,fieldset,legend,input,textarea,select{margin:0;padding:0}
body{font:12px "宋體","Arial Narrow",HELVETICA;background:#fff;}
a{text-decoration:none}
a:hover{text-decoration:underline}
em{font-style:normal}
li{list-style:none}
img{border:0;vertical-align:middle}
table{border-collapse:collapse;border-spacing:0}
p{word-wrap:break-word}
.noborder{border:0;}
.left{float:left;}
.right{float:right;}
congif/index.js
module.exports = {
dev: {
// Paths
assetsSubDirectory: 'static',
assetsPublicPath: '/',
proxyTable: {
"/wz":{
target:"http://cre.mix.sina.com.cn",
changeOrigin:true,
pathRewrite:{
"^/wz":"/"
}
}
},
router/index.js
import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
import Home from '@/components/page/Home'
import Index from '@/components/page/index'
import Video from '@/components/page/video'
import Subscribe from '@/components/page/subscribe'
import Users from '@/components/page/users'
import Search from '@/components/page/search'
import Typenews from '@/components/page/typenews'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/',
redirect:{name:'home'}
},
{
path:'/home',
name:'home',
component:Home,
redirect:{name:'index'},
children:[
{
path:'/home/index',
name:'index',
component:Index,
},
{
path:'/home/video',
name:'video',
component:Video
},
{
path:'/home/subscribe',
name:'subscribe',
component:Subscribe
},
{
path:'/home/:type',
name:'typenews',
component:Typenews
},
]
},
{
path:'/users',
name:'users',
component:Users
},
{
path:'/search',
name:'search',
component:Search
}
]
})
components/page/subscribe
<template>
<div>這裏是訂閱頁面</div>
</template>
<script>
</script>
<style>
</style>
components/page/video
<template>
<div>這裏是視頻頁面</div>
</template>
<script>
</script>
<style scoped>
.content{
background:#fa34c5
}
</style>
components/page/video
<template>
<div>這裏是我的中心
<footer>
<ul>
<li><router-link to="/home/index"><i class='iconfont logo'></i>首頁</router-link></li>
<li><router-link to="/home/video"><i class='iconfont logo'></i>視頻</router-link></li>
<li><router-link to="/home/subscribe"><i class='iconfont logo'></i>訂閱</router-link></li>
<li><router-link to="/users"><i class='iconfont logo'></i>我的</router-link></li>
</ul>
</footer>
</div>
</template>
<script>
</script>
<style lang="scss"scoped>
$sc:25;
footer{
width: 100%;
background:#ddcc88;
position:absolute;
bottom: 0;
left: 0;
ul{
display: flex;
li{
flex: 1;
text-align: center;
height:49/$sc+rem;
a{
color: #777;
display:inline-block ;
margin-top:0.4rem ;
.logo{
display: block;
}
}
}
}
}
</style>
components/page/search
<template>
<div>
<header>
<router-link to="/home/index"><i class='iconfont left'></i></router-link>
<div class="searchpart"><input type="text" id="txt" class="blur" placeholder="搜索文章、視頻、訂閱號"></div>
<router-link to="/home/index" class="right1">取消</router-link>
</header>
</div>
</template>
<script>
</script>
<style lang='scss' scoped>
$sc:25;
header{
width:100%;
height:44/$sc+rem;
background: #aa3344;
position: fixed;
top:0;
left:0;
.left{
float:left;
margin-left: 10/$sc+rem;
margin-top: 10/$sc+rem;
}
.right1{
position: absolute;
top:10/$sc+rem;
right: 10/$sc+rem;
font-size: 16/$sc+rem;
}
.searchpart{
width:253/$sc+rem;
height:23/$sc+rem;
border:1px solid #333;
border-radius:0.6rem;
position: relative;
margin:10/$sc+rem auto;
#txt{
position: absolute;
top: 0.16rem;
left: 0.4rem;
font-size: 0.5rem;
width:8.4rem;
outline: none;
border: none;
}
}
}
</style>
components/page/index.vue 這是首頁上的輪播圖和數據
<template>
<div>
<div class="swiper-container"> <!--輪播圖-->
<div class="swiper-wrapper">
<div class="swiper-slide" v-for="item in news">
<img v-bind:src='item.thumb'>
</div>
</div>
<!--新聞列表-->
<ul v-infinite-scroll="loadMore"
infinite-scroll-disabled="loading"
infinite-scroll-distance="10"> <!--當與下方距離10之內的時候觸發loadmore 第二個是無限滾動是否關閉,靠布爾值決定-->
<li v-for="item in list" class="newspart">
<div>
<h3>{{item.title}}</h3>
<p class="sor">{{item.source}}</p>
</div>
<div>
<img v-bind:src="item.picInfo[0].url">
</div>
</li>
</ul>
</div>
</div>
</template>
<script>
import { Toast } from 'mint-ui';
import axios from 'axios'
import Swiper from 'swiper'
import '../../../node_modules/swiper/dist/css/swiper.css'
export default{
data(){
return{
news:[],//這是從接口中請求的全部數據都存放在這裏面
list:[],
start:0,
end:9,
arr:['A','B01','B02','B03','B04','B05','B10'],
page:0,
loading:false //false能夠發請求,true不能發請求
}
},
created(){ //從接口中請求數據
axios.get("/wz/api/v3/get?_=1543659415163").then((res)=>{
this.news=res.data.data.filter((item,index)=>{
return index<4 //返回前四條數據
})
})
/*this.$jsonp("http://temp.163.com/special/00804KV1/post1603_api_all.js?_=1543659415162",{
callbackName:"callback"
}).then((res)=>{ //這是一次性將全部的數據都請求到
this.list=res.data.filter((item,index)=>{
return index<10 && item.pic[0]
})
console.log(res)
})*/
this.getData()
},
methods:{
loadMore(){ //發送繼續加載數據的請求
this.getData()
console.log("loadMore")
},
getData(){
if(this.page===this.arr.length-1){
Toast({
message: '正在加載', //彈框中的內容
position: 'bottom',
duration: 1500
});
return
}
this.loading=true //別的請求沒法發送,保證同一時刻只能發一個請求
/* var tk = Toast({
iconClass:'fa fa-spinner fa-pulse', //這是iconawesome圖標庫中的動態圖標
position:'middle',
duration:-1
})*/
this.$jsonp(`http://3g.163.com/touch/jsonp/sy/recommend/${this.start}-${this.end}.html`
,{ //數據不能寫死因此須要用字符串拼接
miss:"00",
refresh:this.arr[this.page]
}).then((res)=>{ //這是一次性將全部的數據都請求到
this.list=this.list.concat(res.list.filter((item)=>{
return item.picInfo[0] && !item.adddata
}))
console.log(res)
this.loading=false;
this.page++;
this.start=this.start+10;
this.end=this.start+9;
/*tk.close() //把loading框關閉*/
})
}
},
watch:{
news(){
this.$nextTick(()=>{
var mySwiper = new Swiper ('.swiper-container', {
loop: true, // 循環模式選項
// 若是須要分頁器
pagination: {
el: '.swiper-pagination',
},
autoplay: {
delay: 3000,
stopOnLastSlide: false,
disableOnInteraction: true,
}
})
})
}
}
}
</script>
<style lang='scss'>
$sc:25;
.swiper-container img{
width:100%;
height: 175/$sc+rem;
.swiper-pagination{
text-align: right;
z-index: 1;
}
}
.newspart{
display: flex;
height: 70/$sc+rem;
margin:5/$sc+rem;
img{
width: 110/$sc+rem;
height: 70/$sc+rem;
padding-right:22/$sc+rem;
}
.sor{
margin-top: 15/$sc+rem;
}
}
</style>
components/page/typenews 這是導航欄對應的數據
<template>
<div>
<!--新聞列表-->
<ul>
<li v-for="item in news" class="newspart">
<div>
<h3>{{item.mtitle}}</h3>
<p class="sor">{{item.media}}</p>
</div>
<div>
<img v-bind:src="item.thumb">
</div>
</li>
</ul>
</div>
</template>
<script>
import axios from 'axios'
import Swiper from 'swiper'
import '../../../node_modules/swiper/dist/css/swiper.css'
export default{
data(){
return{
news:[],//這是從接口中請求的全部數據都存放在這裏面
type:''
}
},
created(){ //從接口中請求數據
},
watch:{
$route:{
handler(n){
this.type=n.params.type;
this.getData()
},
immediate:true
}
},
methods:{
getData(){
this.$jsonp(`http://cre.mix.sina.com.cn/api/v3/get?cateid=1&cre=tianyi&mod=${this.type}&merge=3&statics=1&length=20&up=2&down=0&fields=media&_=1543849575332`
).then((res)=>{
this.news=res.data.filter((item,index)=>{
return index<40 &&item.mtitle
})
console.log(this.news)
})
}
}
}
</script>
<style lang='scss'>
$sc:25;
.swiper-container img{
width:100%;
height: 175/$sc+rem;
.swiper-pagination{
text-align: right;
z-index: 1;
}
}
.newspart{
display: flex;
height: 70/$sc+rem;
margin:5/$sc+rem;
justify-content: space-between;
img{
width: 110/$sc+rem;
height: 70/$sc+rem;
padding-right:22/$sc+rem;
}
.sor{
margin-top: 20/$sc+rem;
}
}
</style>