0
点赞
收藏
分享

微信扫一扫

VueCLI实现电商商城项目


bandicam 2020-03-13 17-17-04-444

​​GitHub地址​​.

这个项目用到了,vuecli,vuex,vue-router,
库:MUI,Mint-ui,moment,vue-preview,
开发项目的每一部和每遇到的问题和解决方法都记录在三篇项目纪实里,代码都放在github仓库里,拿下来就可以用,有一些小细节也没有做的精细,这是我第一个vuecli的小项目,做完还是挺高兴的
三篇项目开发纪实
​​day.1​​.
​​day.2​​.
​day.3​​.

学习的视频地址:
​​​https://www.bilibili.com/video/av50680998?p=119​​​.
记录成长加油👍
下面粘贴了项目的代码,github里也都有
main.js

import Vue from 'vue'
import App from './App.vue'
//这是导入全部MintUI,我们只需按需引入即可
import MintUI from 'mint-ui'
import 'mint-ui/lib/style.css' //样式表都得引入
Vue.use(MintUI)
// import { Lazyload } from 'mint-ui';
// Vue.use(Lazyload)//MintUi的懒加载

//初探elementUI
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI);

import $ from 'jquery'
Vue.prototype.$ = $

// import { Header } from 'mint-ui'//引入需要的组件
//按需引入需要对应的loader Babel 两套包来实现
//cnpm i babel-core babel-loader babel-plugin-transform-runtime -D
//cnpm i bable-preset-env babel-preset-stage-0 -D
//Vue.component(Header.name,Header)//对引入的组件进行注册为全局组件

//导入MUI 的样式
import '../src/lib/MUI/css/mui.min.css'
import '../src/lib/MUI/css/icons-extra.css'
import '../src/lib/MUI/fonts/mui-icons-extra.ttf'
//因为picture区需要mui顶部滑块组件,需要引入js文件,再picture.vue中调用并初始化组件

//导入路由
import VueRouter from 'vue-router'
//使用路由
Vue.use(VueRouter);

//导入axios
import axios from 'axios'
// Vue.use(axios);//不对滴,axios不是vue的组件,但是可以把它注册成vue的一个方法来使用
Vue.prototype.axios = axios;

//导入moment日期处理库
import moment from 'moment'
//利用moment做一个全局过滤器
Vue.filter('dateFilter', (dataStr, pattern = "YYYY-MM-DD HH:mm:ss") => {
return moment(dataStr).format(pattern)
})
//导入缩略图插件vue-preview
import VuePreview from 'vue-preview';
Vue.use(VuePreview);

//注册 vuex
import Vuex from 'vuex'
Vue.use(Vuex);

//创建veux实例
//进入时去localStorage中查看是否有数据,如果有则给car
var car = JSON.parse(localStorage.getItem('car')||'[]');
var store = new Vuex.Store({
state:{//this.$store.state.xxx
car:car//加入购物车中的商品的信息
},
mutations:{//this.$store.commit('functionName',args)
addCar(state,information){
//判断新添加的商品与前是否有,如果有在原先商品的数量上加上这次的数量,若没有则直接添加
let flag = false;//如果没有相同id的,如果有再改
state.car.some((item)=>{
if(item.id == information.id){
item.count += parseInt(information.count)
flag = true;//找到相同id后
return true
}
})
if(!flag){
state.car.push(information)
}
//将更新的car数组存储到localStorage中,下次进入购物车信息保留
localStorage.setItem('car',JSON.stringify(state.car))
},
changeNum(state,changeInfo){
state.car.some(item => {
if(item.id == changeInfo.id){
item.count = parseInt(changeInfo.count);
return;
}
})
},
removeGoods(state,index){
state.car.some((item,i) =>{
if(item.id == index){
state.car.splice(i,1);
localStorage.setItem('car',JSON.stringify(state.car));
return;
}
})
},
makeMark(state,info){
state.car.some((item)=>{
if(item.id == info.id){
item.select = info.select
localStorage.setItem('car',JSON.stringify(state.car));
return;
}
})
}
},getters:{//this.$store.gatters.xx
total(state){
let t = 0;
state.car.forEach(item =>{
t += item.count
})
return t;
},
selectNum(state){
let number = 0;
let money = 0;
state.car.forEach(item=>{
if(item.select == 'block'){
number++;
money += item.count * item.price;
}
})

return {number:number,money:money};
}
}
})

//导入tabber对应的4个组件
import HomeComponent from '../src/components/tabbar/HomeComponent.vue'
import MemberComponent from '../src/components/tabbar/MemberComponent.vue'
import ShooppingcarComponent from '../src/components/tabbar/ShooppingcarComponent.vue'
import SearchComponent from '../src/components/tabbar/SearchComponent.vue'
import newsComponent from '../src/components/home/newsComponent.vue'
import newsInfo from '../src/components/home/newsInfo.vue'
import picture from "../src/components/home/picture.vue"
import goods from "../src/components/home/goods.vue"
import goodsInfo from "../src/components/subComponents/goodsinfo.vue"
import aboutUs from "../src/components/subComponents/aboutUs.vue"
import video from "../src/components/subComponents/video.vue"
import debounce from "../src/components/search/debounce.vue"
import scrollbar from "../src/components/search/scrollbarStyle.vue"
import feedback from "../src/components/home/feedback.vue"


Vue.config.productionTip = false

new Vue({
router: new VueRouter({
routes: [{
path: "/",
redirect: '/home'
},
{
path: "/home",
component: HomeComponent
},
{
path: "/mrmber",
component: MemberComponent
},
{
path: "/shoopcar",
component: ShooppingcarComponent
},
{
path: "/search",
component: SearchComponent
},
{
path: "/home/news",
component: newsComponent
},
{
path: "/home/news/newsInfo/:id",
component: newsInfo
}, {
path: "/home/picture",
component: picture
},{
path:"/home/goods",
component:goods
},{
path:"/home/goodsinfo/:id",
component:goodsInfo
},{
path:"/home/about",
component:aboutUs
},{
path:"/home/video",
component:video
},{
path:"/search/debounce",
component:debounce
},{
path:'/search/scrollbar',
component:scrollbar
},{
path:"/home/feedback",
component:feedback
}
],
linkActiveClass: 'mui-active',
//mui-active是tabbar底部图标高亮样式
}),
render: h => h(App),
store
}).$mount('#app')

App.vue

<template>
<div id="app">
<!-- 顶部 Header 区域 - mint UI -->
<mt-header fixed title="Super Market">
<router-link to="#" slot="left">
<mt-button icon="back" v-show="path != '/home'" @click="Back">返回</mt-button>
</router-link>
</mt-header>

<transition>
<router-view></router-view>
</transition>
<!-- 底部 Tabbar 区域 - MUI-->
<nav class="mui-bar mui-bar-tab">
<router-link class="mui-tab-item-hb" to="/home">
<span class="mui-icon mui-icon-home"></span>
<span class="mui-tab-label">首页</span>
</router-link>
<router-link class="mui-tab-item-hb" to="/mrmber">
<span class="mui-icon mui-icon-contact"></span>
<span class="mui-tab-label">会员</span>
</router-link>
<router-link class="mui-tab-item-hb" to="/shoopcar">
<span class="mui-icon mui-icon-extra mui-icon-extra-cart">
<span class="mui-badge" ref="ball"> {{ $store.getters.total }}</span>
</span>
<span class="mui-tab-label">购物车</span>
</router-link>
<router-link class="mui-tab-item-hb" to="/search">
<span class="mui-icon mui-icon-search"></span>
<span class="mui-tab-label">搜索</span>
</router-link>
</nav>
</div>
</template>

<script>
export default {
computed: {
path() {
return this.$route.path
}
},
methods: {
Back() {
this.$router.go(-1);
},
}

}
</script>

<style scoped>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
color: #2c3e50;
margin-top: 60px;
overflow-x: hidden;
}

.v-enter {
opacity: 0;
transform: translateX(100%);
}

.v-leave-to {
opacity: 0;
transform: translateX(-100%);
position: absolute;
}

.v-enter-active,
.v-leave-active {
transition: all 0.5s ease;
}

.mui-bar-tab .mui-tab-item-hb.mui-active {
color: #007aff;
}

.mui-bar-tab .mui-tab-item-hb {
display: table-cell;
overflow: hidden;
width: 1%;
height: 50px;
text-align: center;
vertical-align: middle;
white-space: nowrap;
text-overflow: ellipsis;
color: #929292;
}

.mui-bar-tab .mui-tab-item-hb .mui-icon~.mui-tab-label {
font-size: 11px;
display: block;
overflow: hidden;
text-overflow: ellipsis;
}

.mui-bar-tab .mui-tab-item-hb {
display: table-cell;
overflow: hidden;
width: 1%;
height: 50px;
text-align: center;
vertical-align: middle;
white-space: nowrap;
text-overflow: ellipsis;
color: #929292;
}

.mui-bar .mui-icon {
padding-bottom: 0;
}

.mui-icon .mui-badge {
font-size: 10px;
line-height: 1.4;
position: absolute;
top: 0px;
left: 100%;
margin-left: -10px;
padding: 1px 5px;
color: #fff;
background: red;
}

.mint-header.is-fixed {
top: 0;
right: 0;
left: 0;
position: fixed;
z-index: 5;
overflow: hidden;
}

::-webkit-scrollbar {
width: 4px;
background-color: #9d9d9d;
border-radius: 2px;
/* display: none; */
}

::-webkit-scrollbar-thumb {
/* border: 1px solid #4da650; */
border-radius: 2px;
background: linear-gradient(60deg,yellow,green,red,white);
/* display: none; */
}
</style>

底部tabber区域四个组件
home

<template>
<div class="home">
<mt-swipe :auto="4000">
<mt-swipe-item v-for="(item,index) in list" :key=index>
<a :href="item.url"><img :src="item.src" alt="No"></a>
</mt-swipe-item>
</mt-swipe>

<ul class="mui-table-view mui-grid-view mui-grid-9">
<li class="mui-table-view-cell mui-media mui-col-xs-4 mui-col-sm-4">
<router-link to="/home/news">
<img src="../../images/news.png" alt="">
<div class="mui-media-body">新闻资讯</div>
</router-link>
</li>
<li class="mui-table-view-cell mui-media mui-col-xs-4 mui-col-sm-4">
<router-link to="/home/picture">
<img src="../../images/share.gif" alt="">
<div class="mui-media-body">图片分享</div>
</router-link>
</li>
<li class="mui-table-view-cell mui-media mui-col-xs-4 mui-col-sm-4">
<router-link to="/home/goods">
<img src="../../images/buy.gif" alt="">
<div class="mui-media-body">商品购买</div>
</router-link>
</li>
<li class="mui-table-view-cell mui-media mui-col-xs-4 mui-col-sm-4">
<router-link to="/home/feedback">
<img src="../../images/feedback.gif" alt="">
<div class="mui-media-body">留言反馈</div>
</router-link>
</li>
<li class="mui-table-view-cell mui-media mui-col-xs-4 mui-col-sm-4">
<router-link to="/home/video">
<img src="../../images/video.gif" alt="">
<div class="mui-media-body">视频专区</div>
</router-link>
</li>
<li class="mui-table-view-cell mui-media mui-col-xs-4 mui-col-sm-4">
<router-link to="/home/about">
<img src="../../images/about.gif" alt="">
<div class="mui-media-body">关于我们</div>
</router-link>
</li>
</ul>
</div>
</template>

<script>
export default {
data() {
return {
"Json": "/static/json/swipe.json", //static文件放置静态文件,别的不好使
list: [], //放请求到的数据
}
},
mounted() {
this.getSwipe()
this.$parent.$data.isActive = "none"
},
methods: {
getSwipe() {
this.axios.get(this.Json)
.then(res => {
this.list = res.data
})
.catch(err => {
console.log(err);
})
},
back() {
this.$parent.$data.isActive = "block"
}
}
}
</script>


<style scoped>
.mint-swipe {
height: 200px;
}

.mint-swipe-item:nth-child(1) {
background-color: #5193e2;
}

.mint-swipe-item:nth-child(2) {
background-color: #34153a;
}

.mint-swipe-item:nth-child(3) {
background-color: #9cbf4e;
}

.mint-swipe-item img {
width: 100%;
height: 100%;
}

.mui-table-view {
background-color: #ffffff;
}

.mui-grid-view.mui-grid-9 .mui-table-view-cell {
border: none;
}

.mui-grid-view.mui-grid-9 .mui-table-view-cell img {
width: 50%;
height: 50%;
}
</style>

shopcar

<template>
<div class="shoppingcar" style="overflow-y: hidden;">
<div class="mui-card" v-for="(item,index) in list" :key=index>
<div class="mui-card-content">
<div class="mui-card-content-inner">
<div class="checkBox" @click="settlement(index,item)">
<img :src=mark ref='mark' :style="{display:item.select}">
</div>
<img class="goodsPicture" :src=item.url>
<div class="inner">
<p class="goodsTitle">{{ item.title }}</p>
<span class="goodsPrice">¥{{ item.price}}</span>
<div class="numbox">
<button class="ins" @click="ins(index,item.id)">-</button>
<input class="ipt" type="text" ref='ipt' :value=item.count>
<button class="add" @click="add(index,item.id)">+</button>
</div>
<a href="#" class="remove" @click.prevent="removeGoods(item.id)">删除</a>
</div>
</div>
</div>
</div>
<footer class="footer" ref='panel'>
<span class="pu">总计(不含运费)</span><span @click="down" ref='upordown' class="arrow">></span><br>
<br>
<span class="acc">共选中了<span class="red">{{ $store.getters.selectNum.number }}</span>件,共<span class="red">¥{{ $store.getters.selectNum.money }}</span>元</span>
<button class="account">去结算</button>
</footer>
</div>
</template>

<script>
export default {
data() {
return {
list: [],
mark: 'Checkmark.png',
}
},
mounted() {
this.getGoods()
},
methods: {
down(){
if(this.$refs.upordown.innerText == '<'){
this.$refs.panel.style.bottom = '54px';
this.$refs.panel.style.transition = 'all 1s ease';
setTimeout(()=>{this.$refs.upordown.innerHTML = '>';},1000)
}else{
this.$refs.panel.style.bottom = '0px';
this.$refs.panel.style.transition = 'all 1s ease';
setTimeout(()=>{this.$refs.upordown.innerHTML = '<';},1000)
}
},
getGoods() {
this.list = this.$store.state.car;
},
ins(index, id) {
if (this.$refs.ipt[index].value <= 1) {
this.$refs.ipt[index].value = 1;
} else {
this.$refs.ipt[index].value--;
}
this.$store.commit('changeNum', {
id: id,
count: this.$refs.ipt[index].value
});
},
add(index, id) {
if (this.$refs.ipt[index].value >= 9) {
this.$refs.ipt[index].value = 9;
} else {
this.$refs.ipt[index].value++;
}
let count = this.$refs.ipt[index].value;
this.$store.commit('changeNum', {
id: id,
count: count
})
},
removeGoods(index) {
this.$store.commit('removeGoods', index)
},
settlement(index, item) {
if (this.$refs.mark[index].style.display == 'block') {
this.$refs.mark[index].style.display = 'none';
this.$store.commit('makeMark', {
id: item.id,
select: this.$refs.mark[index].style.display
})
} else {
this.$refs.mark[index].style.display = 'block';
this.$store.commit('makeMark', {
id: item.id,
select: this.$refs.mark[index].style.display
})
}

}
}

}
</script>


<style scoped>
.arrow{
display: block;
width: 30px;
height: 40px;
background-color: #ccc;
text-align: center;
line-height: 40px;
font-size: 25px;
transform: rotate(90deg) translateY(-20px) scale(.5,1) translateX(4px);
margin: -15px auto;
}
.shoppingcar[data-v-2cb56695] {
margin-bottom: 146px;
}

.mui-card {
animation: carcard 1s linear normal;
}

@keyframes carcard {
from {
transform: translateY(800px);
}

to {
transform: translateY(0)
}
}

.account {
float: right;
width: 150px;
background-color: #900a73;
font-weight: bold;
color: #ffffff;
transform: translate(-5px, -15px);

}

.account:hover {
background-color: #ff0000;
}

.red {
color: #f00;
}

.pu {
position: absolute;
font-size: 0.7rem;
color: #CCCCCC;
margin-left: 5px;
}

.acc {
font-size: 0.8123rem;
color: #828282;
margin-left: 5px;
}

.footer {
background-color: white;
border: 1px solid #ccc;
position: fixed;
margin-left: 3px;
border-radius: 5px;
min-height: 80px;
box-shadow: 0 0 5px #ccc;
width: 98%;
bottom: 54px;
z-index: 10;
animation: foot 1s linear normal;
}

@keyframes foot {
0% {
opacity: 0;
bottom: 0;
}

60% {
opacity: 0;
}

100% {
opacity: 1;
bottom: 54px;
}
}

.checkBox {
width: 20px;
height: 20px;
border: #000000 1px solid;
border-radius: 50%;
display: inline-block;
transform: translateY(-10px);
}

.checkBox img {
width: 110%;
height: 100%;
display: none;
}

.numbox {
display: inline-block;
margin: 0 2px 0 2px;
transform: scale(0.8, 0.7);
}

.ins {
background-color: #ccc;
max-height: 30px;
border-top-right-radius: 0px;
border-right-bottom-radius: 0px;
z-index: 1;
font-size: 25px;
font-weight: bold;
line-height: 20px;
border: 1px solid #333;
}

.add {
border: 1px solid #333;
background-color: #ccc;
max-height: 30px;
width: 35px;
border-top-left-radius: 0px;
border-left-bottom-radius: 0px;
margin-left: -10px;
line-height: 20px;
font-size: 20px;
font-weight: bold;
}

.ipt {
text-indent: .2em;
transform: translateX(-10px);
border-radius: 0px;
width: 45px;
text-align: left;
height: 30px;
border: 1px solid #ccc;
}

.shoppingcar {
margin-bottom: 70px;
}

.goodsPicture {
margin-left: 20px;
width: 60px;
height: 60px;
transform: translateY(5px);
}

.inner {
display: inline-block;
max-width: 210px;
margin-left: 5px;
}

.goodsTitle {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
width: 190px;
font-weight: bold;
color: #333333;
text-indent: .5em;
}

.goodsPrice {
color: #f00;
}

.mui-numbox {
width: 100px;
height: 25px;
margin-left: 5px;
margin-right: 5px;
}

.remove {
font-size: 12px;
}


.container-border {
list-style-type: none;
}
</style>

member组件

<template>
<div class="member">
<form class="mui-input-group" style="width: 95%;border: 1px solid #ccc;">
<div class="mui-input-row">
<label>用户名</label>
<input type="text" class="mui-input-clear" placeholder="请输入用户名">
</div>
<div class="mui-input-row">
<label>密码</label>
<input type="password" class="mui-input-password" placeholder="请输入密码">
</div>
</form>

</div>
</template>

<script>
export default {
mounted() {
}

}
</script>


<style scoped>
.mui-input-group {
position: absolute;
border-radius: 5px;
margin: 200px 0 0 9px;
box-shadow: 0 0 5px #ccc;
z-index: 10;
}
.member img{
width: 100%;
height: 650px;
}
</style>

search组件

<template>
<div class="search">
<div class="mui-input-row mui-search">
<input style="width: 98%;margin-left: 3px;" type="search" class="mui-input-clear" placeholder="serach">
<div class="debounce">
<router-link to="/search/debounce">
<img src="../../images/js_icon.jpg">
<span>函数防抖实现淘宝侧边导航栏</span>
</router-link>
</div>
<div class="debounce">
<router-link to="/search/scrollbar">
<img src="../../images/js_icon02.jpg">
<span>浏览器自带滚动条样式</span>
</router-link>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'search',
data() {
return {
}
},

}
</script>


<style scoped>
.debounce{
width: 250px;
height: 200px;
border: #ccc;
margin: 0 auto;
}
.debounce img{
width: 100%;
height: 150px;
}
</style>

商品区

<template>
<div class="goods">
<div class="con" v-for="(item,index) in list" :key=index @click="jump(index)">
<img :src=item.url class="good">
<p class="name">{{item.title}}</p>
<div class="foot">
<p class="price">${{ item.price }}</p>
<p class="state">{{ item.state }}</p>
<p class="state1" v-if="index % 3 == 0">自营</p>
<p class="state2" v-if="index % 4 == 0">宏斌推荐</p>
</div>
</div>
<mt-button plain size="large" type="danger" @click="load">加载更多</mt-button>
</div>
</template>

<script>
// //创建一个新vue实例用来进行商品和商品信息的传递
// var dus = new vue();

import {
Toast
} from 'mint-ui';
export default{
data(){
return{
list:[],
id:0,
information:[],
}
},
mounted() {
this.getGoods();
},
methods:{
getGoods(){
this.axios.get("/static/json/goods/goods"+this.id+".json")
.then(res=>{
this.list = this.list.concat(res.data);
})
.catch(err=>{
console.log(err)
})
},
load(){
Toast({
message: 'Loading...',
position: 'middle',
duration: 1500,
iconClass: 'mui-spinner'
});
setTimeout(() => {
this.id++
if(this.id>1){
this.id=0
}
Toast({
message: '加载成功',
position: 'middle',
duration: 1000,
});
this.getGoods()
}, 1600)
},
jump(index){
this.$router.push("/home/goodsinfo/"+index);
}
}
}
</script>

<style scoped>
*{
padding: 0;
margin: 0;
}
.goods{
display: flex;
flex-flow: row wrap;
margin: 0 auto;
margin-bottom: 60px;
}
.con{
display: flex;
flex-direction: column;
justify-content: space-between;
width: 150px;
border: 1px solid #ccc;
margin: 1%;
flex-grow: 1;
box-shadow: 0 0 2px #ccc;
min-height: 250px;
}
.goods .con .good{
width: 100%;
}
.goods .con .name{
font-size: 15px;
font-weight: 600;
font-family: "bookshelf symbol 7";
color:black;
word-break:break-all;
padding: 0 2px;
}
.goods .con .price{
font-weight: bold;
color:black;
font-weight: 600;
}
.goods .con .state{
color: #ffffff;
display: inline-block;
border-radius: 5px;
background-color: #f00;
font-size: 12px;
margin-right: 5px;
height: 18px;
line-height: 18px;
}
.goods .con .state1{
color: #0000FF;
display: inline-block;
border-radius: 5px;
border: 1px solid #00f;
font-size: 12px;
margin-right: 5px;
box-sizing: border-box;
height: 18px;
line-height: 18px;
}.goods .con .state2{
color: #ff0000;
display: inline-block;
border-radius: 5px;
border: 1px solid #f00;
font-size: 12px;
margin-right: 5px;
box-sizing: border-box;
height: 18px;
line-height: 18px;
}
.foot{
background-color: #ccc;
}
</style>

新闻区

<template>
<div id="news">
<ul class="mui-table-view" @click="getNews">
<li class="mui-table-view-cell mui-media" v-for="(item,index) in list" :key=index>
<router-link :to=" '/home/news/newsInfo/'+item.id ">
<img class="mui-media-object mui-pull-right" :src=item.src>
<div class="mui-media-body">
{{ item.name }}
<p class='mui-ellipsis'>{{ item.msg }}</p>
<span class="time"><span>发布时间:{{ new Date() | dateFilter("YYYY-MM-DD") }}</span><span>点击数:0</span></span>
</div>
</router-link>
</li>
</ul>
</div>
</template>

<script>
export default {
data() {
return {
name: "news",
list: [],
Json: '/static/json/news.json'
}
},
mounted() {
this.getNews()
},
methods: {
getNews() {
this.axios.get(this.Json)
.then(res => {
this.list = res.data
})
.catch(err => {
console.log(err);
})
}
}

}
</script>

<style scoped>
#news {
margin-top: -15px;
margin-bottom: 40px;
color: #ff5500;
}

.mui-table-view {}

#news span {
color: #6fbcff;
font-size: 12px;
}

.time {
display: flex;
justify-content: space-between;
}

.mui-table-view .mui-media-object {
max-width: 60px;
}
</style>

新闻详情组件

<template>
<div id="newsInfo">
<h4 class="tit">{{ title }}</h4>
<p class="p">
<span>{{ time | dateFilter("YYYY-MM-DD") }}</span>
<span>点击数:{{ id }}</span>
</p>
<hr>
<div class="content" v-html="content"></div>
<comment :conid="id"></comment>
</div>
</template>

<script>
//引入评论子组件
import comment from '../subComponents/commont.vue'
//在使用的组件中注册组件

export default {
data() {
return {
name: "newsInfo",
id: this.$route.params.id,
title: "",
// time: new Date(),
time:'',
content: "",
json:'/static/json/newsContent.json'
}
},
mounted() {
this.getNewsContent()
},
methods: {
getNewsContent() {
this.axios.get(this.json)
.then(res => {
this.title = res.data[this.id - 1].title;
this.content = res.data[this.id - 1].content;
this.time = res.data[this.id - 1].time;
})
.catch(err => {
console.log(err)
})
}
},
components:{
comment
}
}
</script>

<style>
#newsInfo .tit {
color: #ff0000;
text-align: center;

}
#newsInfo .p {
display: flex;
justify-content: space-between;
}

#newsInfo span {
font-size: 11px;
padding: 2px 5px;
}

#newsInfo hr {
border: 0;
height: 1px;
background-color: #ccc;
}

#newsInfo .content {
padding: 2px 5px;
margin-bottom: 15px;
}

#newsInfo .content img {
width: 100%;
/* 这要让width生效,就要将style标签的 scoped属性去掉,不到为啥,这么干就对了,为例防止这,没了scoped属性,造成环境污染,每一个样式写的都严谨点,防止别处的样式重名干扰*/
}
</style>

照片分享区

<template>
<div class="picture">
<div id="slider" class="mui-slider">
<div id="sliderSegmentedControl" class="mui-scroll-wrapper mui-slider-indicator mui-segmented-control mui-segmented-control-inverted">
<div class="mui-scroll">
<a class="mui-control-item" v-for="(item,index) in list" :key="index" :class="[item.id==0?'mui-active':'']" @click=getPicture(index)>
{{ item.title }}
</a>
</div>
</div>
</div>
<!-- 缩略图 -->
<ul class="pic">
<li v-for="(item,index) in thumbsList" :key=index>
<div class="thumbs">
<vue-preview :slides=item class="imgPrev"></vue-preview>
</div>
</li>
</ul>
</div>
</template>

<script>
//MUI的js文件,解决顶部滑块无法滑动问题
import mui from '../../lib/MUI/js/mui.min.js'
//初始化要在dom渲染后初始化

export default {
data() {
return {
list: [],
pictureItem: [],
thumbsList: []
}
},
mounted() {
//初始化初始化scroll控件,在mounted时初始化控件,因为要等dom元素加载完毕后再能初始化组件
mui('.mui-scroll-wrapper').scroll({
deceleration: 0.0005 //flick 减速系数,系数越大,滚动速度越慢,滚动距离越小,默认值0.0006
});
this.getTitle();
this.getPicture(0);
},
methods: {
getTitle() {
this.axios.get("/static/json/picturetab.json")
.then(res => {
this.list = res.data
})
.catch(err => {
console.log(err)
})
},
getPicture(id) {
this.thumbsList = [];
this.axios.get("/static/json/pictureitem" + id + ".json")
.then(res => {
res.data.forEach((item) => {
item.w = 600,
item.h = 400,
item.src = item.url,
item.msrc = item.url
})
this.thumbsList.push(res.data);

})
.catch(err => {
console.log(err)
})
}
}
}
</script>

<style>
* {
touch-action: pan-y;
/* 顶部滑动时会报错,原因如下: */
/* 值为none,表示什么不做 */
/* y轴启用单指垂直滑动 */
/* 谷歌浏览器为例提高滑动流畅度弄出的一个东西,某个区域用户可操作,如何让操作*/
}

.pic {
list-style: none;
margin: 0;
padding-inline-start: 0px;
margin-bottom: 50px;
margin-top: 20px;
}

.pic li div img {
width: 100%;
margin-bottom: 5px;
vertical-align: middle;
box-shadow: 0 0 3px #001227;
}

/* 懒加载已经去掉了,纪念下吧 */
/* .pic li img[lazy=loading] {
width: 40px;
height: 300px;
margin: auto;
} */
</style>

全局的评论组件都共用一个

<template>
<div class="com">
<h4>评论区</h4>
<hr>
<textarea class="inner" v-model="content">
</textarea>
<mt-button size="large" type="primary" @click="send">发送评论</mt-button>
<ul class="con" v-for="(item,index) in list" :key=index>
<li><span>{{ index+1 }}楼 匿名用户</span><span>2020-01-05</span></li>
<p class="text">{{ item.content }}</p>
</ul>
<mt-button plain size="large" type="danger" @click="load">加载更多。。。</mt-button>
</div>
</template>

<script>
import {
Toast
} from 'mint-ui';

export default {
data() {
return {
list: [],
content: '',
newContent: [],

}
},
props: ['conid'],
mounted() {
if (this.conid == undefined) {
return
} else {
this.getComment();
}
},
methods: {
send() {
if (this.conid == undefined) {
let common = {
"content": this.content
};
this.list.unshift(common);
this.content = '';
} else {
let user = 'content_' + this.conid;
let common = {
"content": this.content
};
let newContent = JSON.parse(localStorage.getItem(user));
newContent.unshift(common);
localStorage.setItem(user, JSON.stringify(newContent));
this.list = newContent;
this.content = '';
}
},
getComment() {
if (JSON.parse(localStorage.getItem('content_' + this.conid)) == null) {
this.axios.get('/static/json/comment' + this.conid + '.json')
.then(res => {
this.list = res.data;
localStorage.setItem('content_' + this.conid, JSON.stringify(res.data));
})
.catch(err => {
console.log(err)
})
} else {
this.list = JSON.parse(localStorage.getItem('content_' + this.conid));
}
},
load() {
Toast({
message: 'Loading...',
position: 'middle',
duration: 2000,
iconClass: 'mui-spinner'
});
setTimeout(() => {
Toast({
message: '暂时没有更多',
position: 'middle',
duration: 1000,
});
}, 2000)

}
}
}
</script>

<style scoped>
.com {
margin-bottom: 55px;
}

.com .inner {
width: 98%;
height: 100px;
margin: 0 3px;
}

.com .con {
padding: 0;
list-style: none;
margin: 5px 2px;
}

.com .con li {
border: 1px solid #cccccc;
display: flex;
justify-content: space-between;
background-color: #ccc;
border-radius: 5px;
}

.com .con p {
margin: 0;
text-indent: 2em;
color: #555500;
border-bottom: 1px solid #000000;
}

.mint-button--large {
max-width: 99%;
margin: 0 2px;
}
</style>

关于我们页面

<template>
<div>
<div class="mui-card">
<div class="mui-card-header mui-card-media">
<img src="../../assets/logo.png" />
<div class="mui-media-body">
Hongbin
<p>发表于 2020-03-12 16:19</p>
</div>
</div>
<div class="mui-card-content">
<img src="../../images/about.gif" alt="" width="100%" />
</div>
<div class="mui-card-footer">
<a class="mui-card-link">Like</a>
<a class="mui-card-link">Comment</a>
<a class="mui-card-link">Read more</a>
</div>
</div>
</div>
</template>

<script>
export default {

}
</script>

<style scoped>

</style>

购物车组件

<template>
<div class="goodsinfo">
<ul class="con" v-for="(item,index) in information" :key=index>
<div class="wrap">
<img ref='goodsPicture' :src=item.url>
</div>
<div class="mui-card-header">{{ item.title }}</div>
<div class="mui-card-footer">价格:¥{{item.price}}</div>
</ul>
<div class="bottomborder">
<span class="buysum">购买数量:</span>
<div class="mui-numbox" data-numbox-min='1' data-numbox-max='9'>
<button class="mui-btn mui-btn-numbox-minus" type="button">-</button>
<input id="test" class="mui-input-numbox" type="number" value="1" ref="num" @change="numberchange" />
<button class="mui-btn mui-btn-numbox-plus" type="button">+</button>
</div>
<div class="mui-card-content">
<transition
@before-enter="beforeEnter"
@enter="enter"
@after-enter="afterEnter"
>
<span class="ball" v-show="isActive" ref="littleRedball"></span>
</transition>
<mt-button type="danger" class="addcar" @click="addCar">加入购物车</mt-button>
<mt-button type="primary" class="buy">购买</mt-button>
</div>
</div>
<comment :id="'NULL'"></comment>
</div>
</template>

<script>
import comment from '../subComponents/commont.vue'
import mui from '../../lib/MUI/js/mui.min.js'

export default {
data() {
return {
information: [],
id: 0,
isActive:false,
scrolltop:198,
selectNumber:1,
}
},
mounted() {
mui(".mui-numbox").numbox();
this.getId();
},
methods: {
getId() {
this.axios.get("/static/json/goods/goods" + this.id + ".json")
.then(res => {
if (this.$route.params.id > res.data.length - 1) {
this.id = 1;
this.axios.get("/static/json/goods/goods" + this.id + ".json")
.then(res => {
this.information.push(res.data[this.$route.params.id - res.data.length]);
})
} else {
this.information.push(res.data[this.$route.params.id]);
}
})
.catch(err => {
console.log(err)
})

},
addCar(){
this.isActive = true;
//点击将商品信息添加至购物车,将购物车中所需信息整理为一个对象即可
let goodsInfo = {
count:parseInt(this.selectNumber),//选择的数量
id:this.$route.params.id,//选择商品的id
url:this.information[0].url,
price:this.information[0].price,//选中商品的单价
title:this.information[0].title,
select:'none'//在购物车中是否选中:选中时计算价格
}
//将信息添加到vuex state中的car中接收
this.$store.commit("addCar",goodsInfo);
},
numberchange(){
this.selectNumber = this.$refs.num.value;
},
beforeEnter(el){
el.style.transform = "translate(0,0)";
},
enter(el,done){
el.offsetWidth;
//getBoundingClientRect()返回一个矩形对象,有对应的x,y,width,height,top,left,right,bottom点的坐标,良心方法
let littleRedball = this.$refs.littleRedball.getBoundingClientRect();//小球触发的点
let ball = this.$parent.$refs.ball.getBoundingClientRect();//购物车上小球的点
let disX = ball.x-littleRedball.x;
let disY = ball.y-littleRedball.y;
el.style.transform = `translate(${disX}px,${disY}px)`;
el.style.transition = "all .6s cubic-bezier(.4,-0.3,1,.68)";
done();
},
afterEnter(){
this.isActive = false;
},
},
components: {
comment
}
}
</script>

<style scoped>
.con {
padding: 5px;
margin: 0;
}

.wrap {
max-height: 240px;
border: 1px solid #ccc;
overflow: hidden;
box-shadow: 0 0 2px #ccc;

}

.wrap img {
transform: translateX(40px);
height: 240px;
}

.addcar {
margin: 5px 23px 10px 20px;
}

.buy {
margin-top: 5px;
}

.buysum {
color: #6d6d72;
margin-left: 20px;
margin-right: 5px;
}

.mui-card-footer{
padding: 0 0 0 20px;

}
.bottomborder{
border: 1px solid #ccc;
transform: translateY(-40px);
border-top: none;
width: 97%;
margin-left: 5px;
padding-top: 30px;
box-shadow: 0 0 5px #ccc;
}
.ball{
display: inline-block;
width: 15px;
height: 15px;
border-radius: 50%;
background-color: #FF0000;
position: absolute;
left: 150px;
top: -25px;
z-index: 99999;
}
</style>

视频区

<template>
<div class="video">
<a href="https://www.bilibili.com/video/av92525472?from=search&seid=10319623390351842138"><img class="v" title="点击前往观看" src="https://i2.hdslb.com/bfs/archive/5c391705c62074a0702540bddd3c0fea1b611f58.jpg@400w_250h.webp" /></a>

<a href="https://www.bilibili.com/video/av95216236"><img class="v" src="https://i2.hdslb.com/bfs/archive/c5b7ba9752e6e5811bc5bde1ecbe5b60bec09dbf.jpg@160w_100h_100Q_1c.webp" alt=""></a>
<!-- <div class="v"></div> -->
</div>
</template>

<script>
export default{
data(){
return{

}
},
mounted() {
console.log("welcome")
}
}
</script>

<style scoped>
.v1{
width: 350px;
height: 400px;
margin-left: 10px;
}
.v{
width: 350px;
height: 200px;
margin-left: 10px;
background-color: #000000;
}
</style>

搜索区组件

<template>
<div class="throttle">
<h5>target:鼠标移入侧边栏,出现对应二级菜单,迅速移到另外一个菜单栏,中间路过的侧边栏不动 函数防抖</h5>
<hr>
<ul>
<li @mouseenter="enter" @mouseleave="leave" v-for="(item,index) in list" :key=index>{{item}}</li>
</ul>
<div class="panel">0</div>
</div>
</template>

<script>
export default {
data() {
return {
list:[1,2,3,4,5,6,7,8]
}
},
mounted() {
//var time;
//let $ = this.$

// $("ul li").hover(a, function() {
// console.log(this)
// $(this).css({
// backgroundColor: 'white'
// })
// });

// function a(e) {
// clearTimeout(time);
// time = setTimeout(() => {
// e.target.style.backgroundColor = 'pink';
// document.querySelector('.panel').innerHTML = e.target.innerHTML
// }, 300)
// }
},
methods: {
enter(e){
var time;
clearTimeout(time);
time = setTimeout(() => {
e.target.style.backgroundColor = 'pink';
document.querySelector('.panel').innerHTML = e.target.innerHTML
}, 300)

},
leave(){
let $ = this.$
$(this).css({
backgroundColor: 'white'
})
}
}
}
</script>

<style scoped>
* {
padding: 0;
margin: 0;
}

ul {
display: inline-block;
}

li {
list-style: none;
text-align: center;
cursor: pointer;
border-bottom: 1px solid #333;
width: 100px;
padding: 10px 0 10px 10px;
}

.panel {
display: inline-block;
width: 200px;
height: 330px;
border: 50px solid #333;
box-sizing: border-box;
border-image: linear-gradient(red, pink, blue) 30 30 stretch;
position: absolute;
top: 90px;
text-align: center;
font-size: 120px;
line-height: 250px;
}
</style>

<template>
<div class="scrollbar">
<div class="scroll">
Chrome<hr>
<span>
1. ::-webkit-scrollbar 滚动条整体部分,其中的属性: width,height,background,border等。
2. ::-webkit-scrollbar-button 滚动条两端的按钮,可以用display:none让其不显示,也可以添加背景图片,颜色改变显示效果。
3. ::-webkit-scrollbar-track 外层轨道。可以用display:none让其不显示,也可以添加背景图片,颜色改变显示效果。
4. ::-webkit-scrollbar-track-piece 内层滚动槽/轨道,需要注意的就是它会覆盖第三个属性的样式。
5. ::-webkit-scrollbar-thumb 滚动的滑块
6. ::-webkit-scrollbar-corner 边角,两个滚动条交汇处
7. ::-webkit-resizer 定义右下角拖动块的样式/两个滚动条交汇处用于拖动调整元素大小的小控件(基本用不上)</span><br>
IE8<hr>
IE8设置滚动条
scrollbar-arrow-color: color; /*三角箭头的颜色*/
scrollbar-face-color: color; /*立体滚动条的颜色(包括箭头部分的背景色)*/
scrollbar-3dlight-color: color; /*立体滚动条亮边的颜色*/
scrollbar-highlight-color: color; /*滚动条的高亮颜色(左阴影?)*/
scrollbar-shadow-color: color; /*立体滚动条阴影的颜色*/
scrollbar-darkshadow-color: color; /*立体滚动条外阴影的颜色*/
scrollbar-track-color: color; /*立体滚动条背景颜色*/
scrollbar-base-color:color; /*滚动条的基色*/

</div>
</div>
</template>

<script>
</script>

<style scode>
.scrollbar {
margin: 0 auto;
width: 95%;
height: 600px;
border: 1px solid #333333;
}

.scroll {
margin: 0 auto;
width: 90%;
height: 800px;
background: #ccc;
}


::-webkit-scrollbar {
width: 20px;
background-color: #9d9d9d;
border-radius: 2px;
/* display: none;*/
}

::-webkit-scrollbar-thumb {
/* border: 1px solid #4da650; */
border-radius: 2px;
background: linear-gradient(60deg,yellow,green,red,white);
/* display: none; */
}
</style>

index.hrml

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body style="background-color: #ffffff;">
<div id="app"></div>
</body>
</html>

数组是手写的都写在json中,github仓库中都有


举报

相关推荐

0 条评论