按照國際慣例先放效果圖 項目結構搭建 首先修改app.vue <template> <div id="app"> <router-view/> </div> </template> <script> export default { name: 'App' } </script> <style> * ...
按照國際慣例先放效果圖
項目結構搭建
首先修改app.vue
<template> <div id="app"> <router-view/> </div> </template> <script> export default { name: 'App' } </script> <style> *{ margin:0; padding: 0; list-style:none; } </style>
修改main.js,引入rem公式文件
// The Vue build version to load with the `import` command // (runtime-only or standalone) has been set in webpack.base.conf with an alias. import Vue from 'vue' import App from './App' import router from './router' import './config/rem' Vue.config.productionTip = false /* eslint-disable no-new */ new Vue({ el: '#app', router, components: { App }, template: '<App/>' })
在src文件夾下,創建文件夾config,新建文件rem.js
(function(){function a(){var b=document.documentElement.clientWidth;b=b>750?750:b;var c=b/750*100;document.getElementsByTagName("html")[0].style.fontSize=c+"px"}a();window.onresize=a})();
這個代碼可以去網上找,有很多,效果都一樣,實現方法也差不太多
修改router/index.js 路由文件
瀏覽器訪問:
移動端項目配置:
在根目錄下的index.html中添加移動端meta頭
安裝px移動轉換為rem單位的插件
cnpm install px2rem-loader --save-dev
(安裝依賴,最好是加上--save-dev,否則重啟的時候需要再次安裝)
在build文件夾下的utils.js中配置:
remUnit設置原理:
如果設計稿給的是375,就在調試工具375頁面下查看html元素的font-size
顯示是50,那麼就設置50
如果給的設計稿是750,那麼就調到750尺寸下,查看html的font-size,來設置remUnit
然後重啟項目即可生效
在detail.vue中設置寬度單位為px作為測試
瀏覽器里觀察到單位自動轉換為了rem
不想要轉為rem單位的,就在後面加上/*no*/
效果
sketch設計稿介紹:
佈局一般都是有設計稿的,mac推薦sketch
windows就pxcook或者photoshop,如果想體驗sketch,可以在windows上裝mac虛擬機(這個我晚上研究研究再發一篇博)
修改項目總體樣式 app.vue
<template> <div id="app"> <router-view/> </div> </template> <script> export default { name: 'App' } </script> <style> *{ margin:0; padding: 0; list-style:none; } a{ text-decoration: none; color:#333; } </style>
components組件:
共用的組件一般都作為組件來實現
頭部組件
創建header文件夾下的index.vue,放代碼
<template> <div class="c-header"> <ul class="header-ul"> <li>推薦</li> <li>課程</li> <li>實戰</li> <li>職業路線</li> <li class="class-search"><img src="../../assets/search.png"></li> <li class="class-history"><img src="../../assets/history.png"></li> </ul> </div> </template> // scoped表示樣式只在該組件中生效,不會影響其他頁面 <style scoped> .c-header{ position:fixed; width:375px; top:0; background:#fff; box-shadow:0 2px 4px 0 rgba(0,0,0,.1); } .header-ul{ font-size:0; } .header-ul li{ display: inline-block; padding-left:20px; font-size:16px; color:#71777d; height:44px; line-height:44px; } .header-ul img{ width:18px; } .header-ul .class-search{ padding-left:60px; } </style>
創建列表組件
list文件夾下的index.vue
<template> <ul class="c-course"> <router-link to="/detail"> <li v-for="item in courseList"> <img :src="item.imgUrl"> <h1>{{item.title}}</h1> <p>{{item.msg}}</p> </li> </router-link> </ul> </template> <script> export default { props:{//過濾器 courseList:Array } } </script> <style scoped> .c-course{ padding:24px 0; background:#fff; } .c-course li{ position: relative; width:335px; height:72px; margin:0 auto 24px; } .c-course li img{ position:absolute; width:108px; border-radius:5px; } .c-course li h1{ font-size:15px; padding-left:124px; } .c-course li p{ font-size:14px; padding-left:124px; } </style>
底部組件
創建footer目錄下的index.vue
<template> <div class="footer"> <ul class="footer-ul"> <li> <img src="../../assets/home.png" alt=""> <span>首頁</span> </li> <li> <img src="../../assets/sea.png" alt=""> <span>發現</span> </li> <li> <img src="../../assets/download.png" alt=""> <span>下載</span> </li> <li> <img src="../../assets/me.png" alt=""> <span>我的</span> </li> </ul> </div> </template> <style scoped> .footer{ position:fixed; z-index:3; width:375px; background:#fff; border-top:1px solid #f3f5f7; bottom:0; } .footer-ul{ display:flex; } .footer-ul li{ display:flex; height:50px; flex:1; flex-direction: column; justify-content: center; align-items: center; font-size:10px; } .footer-ul li img{ width:24px; } </style>
首頁文件home.vue
<template> <div class="home"> <v-header></v-header> <ul class="nav"> <li v-for="item in webList"> <img :src="item.imgUrl"><!-- 冒號用來接收變數 --> <span>{{item.name}}</span> </li> </ul> <v-list :courseList="courses"></v-list> <v-footer></v-footer> </div> </template> <script> //導入組件 import Header from '@/components/header/' import List from '@/components/list/' import Footer from '@/components/footer/' // 圖片必須通過import來導入 import webImg from '@/assets/web.png' import webserviceImg from '@/assets/webservice.png' import moveImg from '@/assets/move.png' import dataImg from '@/assets/data.png' import bigdataImg from '@/assets/bigdata.png' import course1 from '@/assets/course1.jpg' import course2 from '@/assets/course2.jpg' import course3 from '@/assets/course3.jpg' import course4 from '@/assets/course4.jpg' import course5 from '@/assets/course5.jpg' export default { data(){ return{ webList:[], courses:[] } }, mounted(){ //值的初始化 this.webList=[{ imgUrl:webImg, name:"前端開發" }, { imgUrl:webserviceImg, name:"後端開發" }, { imgUrl:moveImg, name:"移動開發" }, { imgUrl:dataImg, name:"資料庫" }, { imgUrl:bigdataImg, name:"雲計算" }]; this.courses=[{ imgUrl:course1, title:'實例秒解sed和ak的秘密', msg:'中級,330人在學' }, { imgUrl:course2, title:'實例秒解sed和ak的秘密', msg:'中級,330人在學' }, { imgUrl:course3, title:'實例秒解sed和ak的秘密', msg:'中級,330人在學' }, { imgUrl:course4, title:'實例秒解sed和ak的秘密', msg:'中級,330人在學' }, { imgUrl:course5, title:'實例秒解sed和ak的秘密', msg:'中級,330人在學' },{ imgUrl:course1, title:'實例秒解sed和ak的秘密', msg:'中級,330人在學' }, { imgUrl:course2, title:'實例秒解sed和ak的秘密', msg:'中級,330人在學' }, { imgUrl:course3, title:'實例秒解sed和ak的秘密', msg:'中級,330人在學' }] }, components:{//註冊組件 'v-header':Header, 'v-list':List, 'v-footer':Footer } } </script> <style scoped> .home .nav{ height:100px; padding-top:44px; background:#f3f5f7; overflow-x:scroll; white-space: nowrap; font-size:0; } .nav li{ width:88px; display:inline-block; text-align: center; font-size:14px; } .nav li img{ display:block; width:32px; margin:20px auto 12px; } </style>
詳情頁文件 detail.vue
<template> <div class="detail"> <div class="video"> <video src="http://v3.mukewang.com/shizhan/59f8498ae420e5be578b459b/H.mp4" controls="controls"></video> <router-link to="/"> <div class="video-back"><</div> </router-link> </div> <ul class="nav"> <li v-for="item in navArr">{{item}}</li> </ul> <div class="title"> <h1>{{title}}</h1> <p>{{des}}</p> </div> <ul class="question"> <li v-for="(item,index) in questionArr"> <h1>{{arrTitle[index]}}</h1> <p v-html="item"></p><!-- 由於讀取的數據中存在html結構<br>,因此必須使用v-html --> </li> </ul> </div> </template> <style scoped> .detail{ position: relative; height:3.82rem; } .video video{ width:100%; height:100%; } .video-back{ position:absolute; top:21px; left:16px; text-align: center; color:#fff; font-size:18px; line-height:32px; border-radius: 3px; width:32px; height:32px; background:rgba(0,0,0,.5); } .nav{ position: relative; z-index:1; display:flex; box-shadow:0 2px 4px 0 rgba(0,0,0,0.1); } .nav li{ flex:1; text-align:center; line-height:44px; height:44px; background:#fff; font-size:14px; } .title{ padding: 24px 0 0 20px; margin-bottom: 8px; } .title h1{ font-size: 16px; color: #2B333B ; } .title p{ font-size: 14px; color: #71777D; padding : 16px 0 34px; width: 335px; } .question{ padding: 20px; background: #fff; } .question li h1{ font-size: 14px; color: #2B333B; } .question li p{ padding:12px 0 0 30px; font-size: 14px; color: #71777D ; } .question li:nth-child(1){ padding-bottom: 24px; } </style> <script> export default { data(){ return{ navArr:[], title:"", des:"", questionArr:[], arrTitle:["課程須知","老師告訴你能學到什麼?"] } }, mounted(){ //真實開發中,這些數據需要通過後臺讀取 this.navArr=["章節","詳情","評論","問答","記"]; this.title = "iOS基礎教程之-Camera攝像頭"; this.des = "從實例出發介紹我們的Camera,可以實現Camera屬性檢測,照片拍攝,視頻錄製,圖片展示,錄製視頻"; this.questionArr=[ "本課程適合客戶端產品經理,研發人員以及對iOS新特性感興趣的人群", ` (1)數位相機相關的所有API<br/> (2)利用Camera實現相機的各種屬性檢測<br/> (3)利用Camera拍照、保存、遍歷相冊等功能<br/> (4)利用Camera拍攝視頻、視頻剪切功能 ` ] } } </script>