1. 程式人生 > >初步vue.cli 路由+輪播+彈窗小case

初步vue.cli 路由+輪播+彈窗小case

淺談建立

src檔案包含:

Alt

程式碼書寫:

App.vue

<template>
  <div id="app">
    <!-- 最後一步,顯示每一個頁面的容器 -->
    <div style="position:relative;height:100vh;overflow: hidden;">
      <transition :name="howGo">
        <router-view class="page_view"> </router-view>
      </transition>
    </div>
    <footer class="footer_menu">
      <div>
        <!-- router-link  做到區域性跳轉 -->
        <router-link to="/">首頁</router-link>
      </div>
      <div>
        <router-link to="/cate">分類</router-link>
      </div>
      <div>
        <router-link to="/cart">購物車</router-link>
      </div>
      <div>
        <router-link to="/my">我的</router-link>
      </div>
    </footer>
  </div>
</template>
<script>
export default {
  name: 'app',
  data(){
    return{
      howGo:'',
    }
  },
  watch:{
    '$route' (to,from){
      if (from.meta.num > to.meta.num) {
        this.howGo = 'right'
      }else{this.howGo = 'left'}
    }
  }
  // components: {
  //   slider,
  //   // HelloWorld
  // },
//   methods:{
//     getMsg(rtnString){
//       this.msg = rtnString
//     }
//   }
}
</script>
<style>
  @import url('assets/home.css')
</style>

main.js

// 引入依賴
import Vue from 'vue'
import App from './App.vue'
import router from './router/index'
import axios from 'axios'

import iview from 'iview'
import 'iview/dist/styles/iview.css'

Vue.use(iview)

Vue.config.productionTip = false

// axios.default.baseUrl = 'http://localhost/node-vue.cli/first_vue_cli - 副本'
// Vue.prototype.$http = axios

new Vue({
	router,
  render: h => h(App),
}).$mount('#app')

index.js(路由檔案)

import Vue from 'vue'
import Router from 'vue-router'


import home from '../view/home'
import cate from '../view/cate'
import cart from '../view/cart'
import my from '../view/my'
import ginfo from '../view/ginfo'


Vue.use(Router)


let router = new Router({
	routes:[
		{
			path:'/',
			component: home,
			meta:{
				num:1
			}
		},
		{
			path:'/cate',
			component: cate,
			meta:{
				num:2
			} 
		},
		{
			path:'/cart',
			component: cart,
			meta:{
				num:3
			} 
		},
		{
			path:'/my',
			component: my,
			meta:{
				num:4
			}
		},
		{
			path:'/ginfo',
			component: ginfo,
		},
	]
})

//export   相當於renturn

export default router

home.css(樣式檔案)

#app {
    font-family: 'Avenir', Helvetica, Arial, sans-serif;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-align: center;
    color: #2c3e50;
    /*margin-top: 60px;*/
}
a {
    text-decoration: none;
}
.page_view {
    position: absolute;
    width: 100%;
}
.footer_menu {
    background-color: #fff;
    color: #333;
    display: flex;
    position: fixed;
    bottom: 0px;
    width: 100%;
    height: 30px;
    line-height: 30px;
    transform: translateZ(0);
}
.footer_menu>div {
    width: 25%;
    text-align: center;
}
input {
    border: 1px solid #737272
}
img {
    width: 100%;
}
.big_box {
    position: relative;
    width: 100%;
    height: 360px;
    overflow: hidden;
}
.box {
    position: absolute;
    width: 100%;
}
.R_box {
    position: absolute;
    left: 40%;
    bottom: 20px;
    display: flex;
}
.R_box>div {
    width: 10px;
    height: 10px;
    background-color: #eee;
    border-radius: 50%
}
.cur {
    border: 1px solid #ccc;
    background-color: red !important;
}
#i {
    width: 148px;
    margin: 0 auto
}

view(檢視檔案)

home.vue

<template>
	<div style="width:100%;height:100vh;background-color:yellow;#fff">首頁
	<slider :data="first_hdp" />
		<router-link to="/ginfo">商品詳情
		</router-link>
	</div>
</template>

<script >
import slider from '../components/slider.vue'
import glist from '../components/glist.vue'
	export default{
		data(){
   		return{
		first_hdp:['https://i8.mifile.cn/v1/a1/ec370747-6909-b8f8-8da0-dc2fc553eab3!720x360.webp','https://i8.mifile.cn/v1/a1/7c2d766b-ad0b-2f98-4ff6-57a911c81993!720x360.webp','https://i8.mifile.cn/v1/a1/0616543e-25ae-3248-87a4-959119d08897!720x360.webp']
			}		
		},
		created(){
			// this.$http.get('index.php?control=gooos&action=getList')
			// .then((rtnD)=>{

			// })
		},
		components:{
				slider,glist
			}
	}
</script>

my.vue

<template>
	<!-- <div style="width:100%;height:100vh;background-color:green;#fff">個人中心</div> -->

	<div>
		<!-- 登陸後顯示個人中心 -->
		<!-- 沒登陸進入登入 -->
		<div id="i">
		<Form :lable-width="80" onsubmit="return false">
			<Form-item label="使用者名稱:"> 
				<input v-model="uname" type="text">
			</Form-item>
			<Form-item label="密碼:"> 
				<input v-model="upwd" type="passwrod">
			</Form-item>
			<Form-item >
				<Button @click="doLogin" type="primary">登入</Button>
			</Form-item>
		</Form>
		</div>

	</div>
</template>


<script type="text/javascript">
	export default{
		data(){
			return {
				uname: '',
				upwd: '',
			}
		},
		methods:{
			doLogin(){
				this.$http.get('index.php?control=user&action=login',{
					params:{
						uname:this.uname,
						upwd:this.upwd,
					}
				}).
				then((rtnD)=>{

				})
			}
		}
	}

</script>

ginfo.vue

<template>
	<div style="width:100%;height: 100vh">
		<Button type="primary" @click="addCx">促銷</Button>
		<pop v-model="cx_show">
		促銷.....
		</pop>
		<Button type="error" @click="showCart">加入購物車</Button>
		<Button type="error" @click="addCart">加入購物車</Button>
		<pop v-model="gwc_show">
		商品名稱、商品價格
		</pop>
	</div>
</template>
<script type="text/javascript">
import pop from '../components/pop.vue'
	export default{
		data(){
			return{
				info:[],
				cx_show:false,
				gwc_show:false,
			}
		},
		components:{
			pop,
		},
		methods:{
			addCx(){
				this.cx_show = true
			},
			showCart(){
				this.gwc_show = true
			},
			addCart(){
				this.$Message.suceess('加入成功');
				var last_cart = localStorage.getItem('cart')
				if (last_cart) {last_cart = JSON.parse(last_cart)}
				else{last_cart = []} 
				last_cart.push(this.info)
				localStorage.setItem('cart',JSON.stringify(this.info))
				this.gwc_show = false
			}
		}
	}
</script>

cate.vue

<template>
	<div style="width:100%;height:100vh;">
	分類
	</div>
</template>

cart.vue

<template>
	<div style="width:100%;height:100vh;background-color:blue;#fff">
		購物車
	</div>
</template>

元件

slider.vue(輪播元件)

<template>
		<div>
			<!-- 子元件說:
			<input type="text" v-model="msg" @keydown="give_fzj"> -->
			<div class="big_box">
				<div class="box"  @touchstart="tStart" @touchmove="tMove" @touchend="tEnd" v-for="(img,index) in data">
					<transition :name="howGo">
						<img v-show="index == show" :src="img">
				   	</transition>
				   	<div class="R_box">
						<div v-for="(img,index) in data" :class="{cur:index == show}"></div>
					</div>
				</div>
			</div>
		</div>
</template>

<script>
	export default {
		data(){
			return {
				msg:'',
				show:0,
				
				howGo:null,
			}
		},
		props:{
			data:{
				type:Array,
				startX: 0,
				default:'' // 設定預設值
			}
		},
		created(){

			// var that = this
			// setInterval(function(){
			// 	that.tStart()
			// },2000)
		},
		methods:{
			give_fzj(){
				this.$emit('get',this.msg)
				console.log(this.msg)
			},
			
			tStart(e){
					
					this.startX = e.touches[0].clientX
					// e.removeEventListener("touches","",false)
			},
			tMove(e){
				// console.log(e.touches[0].clientX)
				// this.moveX = e.touches[0].clientX
				// console.log(this.moveX)
				// e.path[1].style.transform= "translateX("+this.moveX+"px)"
				// console.log(e.path[0].style)
				
			},
			tEnd(e){
	
				// let endX = e.changedTouches[0].clientX
				// if (endX > this.startX) {
				// 	this.howGo = 'right'
				// 	console.log('right')
				// 	if (this.show==0) {

				// 	this.show=0
				// }else{
					
				// 	--this.show

				// }
				// }else{
				// 	this.howGo = 'left'
				// 	console.log('left')
				// 	if (this.show==this.data.length-1) {
				// 	this.show=this.data.length-1
				// }else{
				// 	++this.show
				// }
			 //  }
			 //  
			 //三元運演算法
			 let endX = e.changedTouches[0].clientX
			 if (endX > this.startX) {
			 	this.howGo = 'right'
			 	--this.show
			 	this.show = this.show<=0?0:this.show
			 }else{
			 	this.howGo = 'left'
			 	++this.show
			 	this.show = this.show>=this.data.length-1?this.data.length-1:this.show

			 }
			
			// console.log(this.show)
			// console.log(e)
			
			},
		
		}

	}

</script>
<style type="text/css" scoped>
	/*進來前*/

/*.left-leave-to,*/
.left-enter,
.right-leave-to {
    transform: translate(100%, 0);
}

/*進來後*/
.left-enter-active,
.left-leave-active,
.right-enter-active,
.right-leave-active {
    transition: all 0.5s;

}

/*leave是給當前要走的圖片家樣式*/
/*.left-leave-active{
	transition:all 2s;
}*/
.left-leave-to,
.right-enter {
    transform: translate(-100%, 0);
}

/*向右*/
/*.rig-enter{
	transform: translate(100%,0);
}*/
/*進來後*/
/*.rig-enter-active,.rig-leave-active{
	transition:all 2s;
	
}
*/
/*.rig-leave-to{
	transform: translate(-100%,0);
}*/

</style>

glist.vue(列表元件)

<template>
	<div>
		<div v-for="goods in goods_list">
			<img :src="goods.thumb">
			<p>{{goods.g_name}}</p>
			<p>{{goods.g_price}}</p>
		</div>
	</div>
</template>
<script type="text/javascript">
	
	export default{
		props:{
			goods_list:{
				type:Array
			}
		}
	}
</script>

pop.vue(彈窗元件)

<template>
    <div>
        <div>
            商品詳情
        </div>
        <div class="yy_box" @click="hide" v-show="this.value"></div>
        <transition name="upDownSlider">
            <div class="nr_box" v-show="this.value">
                <div class="colose"></div>
                <div class="content"></div>
            </div>
        </transition>
    </div>
</template>
<script>
export default {
    props: {
        value: {
            type: Boolean,
            default: false,
        }
    },
    data() {
        return {
            pop_show: this.value
        }
    },
    watch:{
        value() {
            this.pop_show = this.value

        }
    },
    methods: {
        hide() {
            this.is_show = false
            // 子元件告訴父元件
            this.$emit('input', false)

            
        }
    }
}
</script>
<style scoped>
.yy_box {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100vh;
    background-color: #333;
    opacity: .5;
}

.upDownSlider-enter {
    transform: translate(0, 100%)
}
.upDownSlider-leave-to {
    transform: translate(0, 100%)
}
.upDownSlider-enter-active,.upDownSlider-leave-active {
    transition: all 1s
}



.nr_box {
    background-color: red;
    width: 100%;
    height: 300px;
    position: fixed;
    bottom: 0;
}
</style>
  • 解決問題

    1. position:fixed; 抖動問題 -> 加上transform:translateZ(0)
    2. 輪播效果 :
      ?-enter (進入過渡的開始狀態)
      ?-enter-active(進入過渡生效時的狀態)
      ?–leave-active(離開過渡生效時的狀態)
      ?–leave-to(離開過渡的結束狀態)
    3. 彈窗
  • 未解決問題

    1. axios請求