項目名稱:去哪兒app
時間:2019年3月18日-2019年3月23日
地點:咸陽市秦思科技二樓
作者:賈雄
概述:模擬制作去哪兒app,使用vue-cli腳手架,SPA單頁WEB開發
使用技術:vue
ECMAScript6
css3
Html5
vue-cli腳手架
vue-swiper
axios技術
better-scroll滾動插件
vuex管理庫
本地存儲localStorage
keep-alive
vue-router路由
開發模式:MVVM開發模式
項目環境搭建:
1.安裝node.js和git (官網下載安裝,新版node.js中自帶npm)
yarn的安裝:npm install yarn -g
2.在碼雲或者Github上建立倉庫 wherego(wherego 名字可自取)
3.下載到本地:Git clone "路徑地址"
4.改變路徑到該文件夾下:cd wherego
5.安裝cue-cli腳手架
1)npm i webpack -g 或 yarn add webpack -g
2) npm i vue-cli -g 或 yarn add vue-cli -g
3) vue init webpack projectName (projectName項目名)
4) cd projectName
5)npm i/npm install
6)npm run dev (啟動服務,生成一個端口地址如:8080)
7)打開網頁輸入:localhost:8080
模擬軟件制作步驟:
1.使用Sublime Text軟件或 WebStorm軟件制作靜態頁面
2.靜態頁面數據改變為后台json數據
3.更改配置文件
1)package.json 加入 --host 0.0.0.0
"scripts": {
"dev": "webpack-dev-server --inline --host 0.0.0.0 --progress --config build/webpack.dev.conf.js",
"start": "npm run dev",
"build": "node build/build.js"
},
2)config文件下index.js
build: {
// Template for index.html
index: path.resolve(__dirname, '../dist/index.html'),
// Paths
assetsRoot: path.resolve(__dirname, '../dist'),
assetsSubDirectory: 'static',
assetsPublicPath: './',
//這里將 '/' 變成 './'
4.使用 npm run build 命令自動生成dist文件夾
5.使用HBuilder軟件
1)新建移動端App項目,刪除css。img等文件,只保留manifest.json文件和unpackage文件夾
2)導入構建好的dist文件(導入時要注意勾選相關文件)
3)選擇主項目名稱->右鍵->選擇發行->選擇雲打包-打原生安裝包
4)使用手機助手連接手機,在電腦版手機助手中選擇已安裝軟件,打開,安裝本地app
5)安裝成功后手機打開試用
6)如果要發布到網上,需要在應用寶等軟件商店注冊賬號信息
項目技術使用方式:
1.模塊 xxx.vue文件
1)由三部分組成:template,script,style
2) <template>
<div>
</div>
</template>//此處模塊內必須要一個父級(div或其他標簽)包裹,內容寫在里面
<script>
export default({
data(){
return{
}
},
methods:{
}
})
</script>
<style scoped><syle>
//scoped 如果寫上意味着屬性為局部屬性
3)引入vue模塊: import Div from './pages/div.vue'
4)注冊模塊:
<script>
export default({
components:{
Div:Div // 名稱相同可簡化為一個 Div
},
mothods:{
}
})
</script>
5)在template模塊下的父級盒子中使用:
<template>
<div>
<Div></Div>
</div>
</template>
2.引入全局屬性樣式
1) import './assets/css/reset.css' //全局屬性初始設置
// 引入
2) import FastClick from 'fastclick'
// 使用
FastClick.attach(document.body);
3) import './assets/css/iconfont.css' //字體圖標庫:iconfont
3.文件目錄結構
src -> 放源文件的地方
assets -> css/img
components -> 放組件
router -> 配置路由 router-link => a this.$router.push()/this.$router.replace()/this.$router.go() => location.href = ''
static -> 放靜態資源文件的地方 data / img
App -> 整個項目的入口,也是路由的出口
main.js -> 進行全局配置
4.css變量 stylus
1)官網: https://www.zhangxinxu.com/jq/stylus/
2)安裝: npm i stylus stylus-loader -S
3)使用時相當於less寫法,形成的文件的擴展名為.styl
4)例:
定義:$bgColor = #00bcd4;
使用:<style scoped lang="stylus">
@import '~@/assets/css/css.styl'
.header{
background: $bgColor;
}
</style>
5)@表示的是'src'目錄,如果style中要引入src下面的內容,要在@前加~,其它地方不需要加。
/api為 localhost:8080
5.vue-swiper 輪播圖
1)官網:https://github.com/surmon-china/vue-awesome-swiper
2)安裝: npm install vue-awesome-swiper --save
3)掛載: import VueAwesomeSwiper from 'vue-awesome-swiper'
import 'swiper/dist/css/swiper.css'
Vue.use(VueAwesomeSwiper)
4)布局:
<swiper :options="swiperOption">
<!-- slides -->
<swiper-slide>I'm Slide 1</swiper-slide>
<swiper-slide>I'm Slide 2</swiper-slide>
<swiper-slide>I'm Slide 3</swiper-slide>
<swiper-slide>I'm Slide 4</swiper-slide>
<swiper-slide>I'm Slide 5</swiper-slide>
<swiper-slide>I'm Slide 6</swiper-slide>
<swiper-slide>I'm Slide 7</swiper-slide>
<!-- Optional controls -->
<div class="swiper-pagination" slot="pagination"></div>
<div class="swiper-button-prev" slot="button-prev"></div>
<div class="swiper-button-next" slot="button-next"></div>
<div class="swiper-scrollbar" slot="scrollbar"></div>
</swiper>
5)配置:
<script>
export default {
name: 'carrousel',
props:["swiperList"],
data() {
return {
swiperOption: {
pagination: {
el: '.swiper-pagination'
},
loop:true,
autoplay: {
delay: 2000,
stopOnLastSlide:false,
disableOnInteraction:true
}
},
"swiperList":[
{
url:require("@/assets/img/01.jpg")
},
{
url:require("@/assets/img/02.jpg")
}
]
}
},
methods:{
}
}
</script>
6)"imgUrl":require("@/assets/img/swiper01.jpg") 拿本地圖片時,要用require()
6.掉塊處理:
height: 0;
padding-bottom: 26.67%; /*100px/375px*/
background-color: #ddd;
7.把一維數組拆分成二維數組,主要用於實現分頁
var arr = [1,2,3,4,5,6,7,8,9,10,11,234,546,57,3,34,456,2,12,43];
var newArr =[]
for(var i=0;i<arr.length;i++){
var idx = Math.floor(i/8);
if(!newArr[idx]){
newArr[idx] = [];
}
newArr[idx].push(arr[i]) //newArr[0].push
}
例:
//html
<swiper :options="swiperOption" class="swiper">
<swiper-slide v-for="icons of page" :key="icons.index">
<div v-for="item of icons" :key="item.id" class="icons" >
<div class="img">
<img :src="item.url" alt="">
</div>
<p>{{item.title}}</p>
</div>
</swiper-slide>
<div class="swiper-pagination" slot="pagination"></div>
</swiper>
//script
computed:{
page(){
let pages=[];
this.iconsList.forEach((item,index)=>{
let idx = Math.floor(index/8);
if(!pages[idx]) pages[idx]=[];
pages[idx].push(item);
})
return pages;
}
}
8.文本溢出
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
9.axios的使用
1)安裝: npm i axios -S 或 yarn add axios
2) 引入:
在main.js中添加:
import axios from 'axios'
Vue.prototype.$http = axios //將axios定義到原型方法中
3) 發送請求:
在Home.vue文件的script標簽中添加:
data(){
return{
swiperList:[]
}
},
mounted(){
this.$http.get('http://localhost:8080/static/mock/data/home_data.json').then((res)=>{
console.log(res);
let data = res.data.data[0];
this.swiperList = data.swiperList;
}
}
4)綁定數據到組件上
在Home.vue文件中添加:
<home-swiper :swiperList="swiperList"/>
5)子組件接收傳值
在SwiperList.vue文件中添加:
在script標簽中寫:
props:['swiperList']
注意:圖片地址不能用require,要改成:http://localhost:8080......
10.服務器代理:
定義:代理服務器英文全稱是(Proxy Server),其功能就是代理網絡用戶去取得網絡信息。
在index.js文件中的代碼proxyTable: {}中添加:
proxyTable: {
'/api':{
target:'http://localhost:8080',//代理的IP地址
pathRewrite:{//重寫路徑
'^/api':'/static/mock/'
}
}
}
注意:修改配置文件后一定要重啟服務!!!
11.滾動插件的使用:
1)安裝
yarn add better-scroll
或:npm install better-scroll --save
2)導入
import BScroll from 'better-scroll'
3)修改結構(布局)
在要加滾動條的部分外層套兩層div
html格式:
<div class="home">
<div class="container" ref="container">
<div>
//<Swiper :swiperList="swiperList"></Swiper>
//<Icons :iconsList="iconsList"></Icons>
//<Localtion></Localtion>
//<Hot :hotList="hotList"></Hot>
//<Like :likeList="likeList"></Like>
//<Where :whereList="whereList"></Where>
//<Footer></Footer>
</div>
</div>
</div>
4)在mounted()中添加:
let container = this.$refs['container'];//獲取DOM節點
const scroll = new BScroll(container)
5)寫CSS樣式:
.container{
position: absolute;
left:0;
right:0;
bottom: 0;
top:.88rem;
}
12.vuex 管理庫
1)安裝
yarn add vuex
2)在src目錄中創建目錄store
3)在store目錄中創建index.js文件
4)在main.js中全局引入:
import store from './store'
new Vue({
el: '#app',
router,
store,
components: { App },
template: '<App/>'
});
5)在index.js中添加代碼:
提示:
本地存儲有:localStorage 永久存儲
sessionStorage 臨時存儲
存值:
localStorage.city = cityName;
取值:
let changecityname = localStorage.city;
// let changecityname = sessionStorage.city || "西安"
let changecityname = localStorage.city || "西安"
let state = {
city:changecityname
}
let mutations = {
changeCity(state,cityName){
this.state.city = cityName
// sessionStorage.city = cityName
localStorage.city = cityName
}
}
export default new Vuex.Store({
state,//拋出state的內容
mutations
})
6)組件引用倉庫中的數據
a.引入倉庫
import { mapState } from 'vuex'
b.調用state中的內容
computed:{
...mapState(['city']);
}
c.使用數據
{{ city }}
7)更改 Vuex 的 store 中的狀態的唯一方法是提交 mutation
8)動態改變數據
利用vuex中的mutations來實現。
a.在index.js中添加方法
let mutations = {
changeCity(state,cityName){//這里的changeCity和此文件的事件名不能相同
this.state.city = cityName;
//console.log(this.state.city)
}
};
b.拋出mutations
export default new Vuex.Store({
state,//拋出state的內容
mutations
})
c.在應用數據的組件中引入
import { mapMutations } from 'vuex'
d.在methods中引入方法:
...mapMutations(['changeCity'])
e.調用方法
changecity(name,index){
// console.log(name,index)
this.changeCity(name);//這里的changeCity和此文件的事件名changecity不能相同,單擊事件要傳值@click="changecity(item.name)"
this.$router.push("/")//路由跳轉
}
13.keep-alive
a.keep-alive是Vue提供的一個抽象組件,用來對組件進行緩存,從而節省性能,由於是一個抽象組件,所以在v頁面渲染完畢后不會被渲染成一個DOM元素
b.當組件在keep-alive內被切換時組件的activated、deactivated這兩個生命周期鈎子函數會被執行,被包裹在keep-alive中的組件的狀態將會被保留。
c.在App.vue的router-view標簽的外層套一個keep-alive的抽象組件。
<keep-alive>
<loading></loading>
</keep-laive>
d.當數據發生改變時,頁面並沒有刷新,得重新發請求!下面是解決方案:
操作步驟:
1)定義變量存儲
data(){
return{
changeCity:""
}
}
2)把倉庫中的city拿出來:
import { mapState } from 'vuex'
computed:{
...mapState(['city'])
}
3)遍歷JSON中的數據,找出city值是倉庫中city值的這一組數據,存入對應的組件需求的變量中。
methods:{
getHttp(){
this.$http.get('/api/data/home_data.json').then(res => {
let data = res.data.data;
data.forEach((item, index) => {
if(item.city == this.city){
this.swiperList = item.swiperList;
this.iconsList = item.iconsList;
this.hotImgs = item.hotImgs;
this.likeList = item.likeList;
this.vacationList = item.vacationList;
}
});
})
}
},
mounted(){
this.getHttp();
this.changeCity = this.city;
},
activated(){
if(this.changeCity != this.city){
this.getHttp();
this.changeCity = this.city;
}
}
14.下拉一定位置顯示,返回頂部消失
1)下拉時原來的v-show消失,目標內容v-show顯示
2)返回頂部時原來的v-show顯示,目標內容v-show消失
3)利用opacity
html:
<div :style="Opacity"></div>
sxript:
export default({
data(){
return{
Opacity:{
opacity:0
}
}
},
mounted(){
window.addEventListener('scroll',()=>{
let topH = document.documentElement.scrollTop || document.body.scrollTop;
let topOpacity = topH / 100;
if(topOpacity >6){
topOpacity=1;
}
this.Opacity.opacity=topOpacity;
// console.log(topOpacity)
})
}
}
15.vue-router
1) 在src文件夾下建立文件夾router
2)在router文件夾下建立index.js
3)
import Vue from 'vue'
import Router from 'vue-router'
// import HelloWorld from '@/components/HelloWorld'
import Home from '@/components/home/home'
import City from '@/components/city/city'
import Details from '@/components/details/details'
import Img from '@/components/details/pages/img'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/city',
name: 'City',
component: City
},
{
path: '/Details',
name: 'Details',
component: Details
},
{
path: '/Img',
name: 'Img',
component: Img
}
]
})
4)單擊事件
methods:{
gohome(){
this.$router.push("/") //返回Home文件中
//this.$router.go(-1) //返回上一級
},
goimg(){
this.$router.push("/img") //返回img文件中
}
}
項目解決阻礙方式:百度,論壇,貼吧,朋友,曾經的老師和同學
代碼實現:
碼雲:https://gitee.com/JXBOSS/whereapp
