【vue】imitate-beautiful-thing

我从未见过这么美妙的项目,当然与我接触的项目少有关,但是这个项目满满的艺术气息,让人沉醉,让人忍不住的去研究代码。
先放项目地址:https://github.com/eidonlon/imitate-beautiful-thing
再来看一下项目的效果
1037363-20190709193328932-1048806095.gif
接下来我们来研究代码吧~
我们先来看项目的入口文件main.js
main.js作为入口引入App.vue

<template>
  <div id="app">
        <router-view></router-view>
  </div>
</template>

<script>
export default {
  name: 'App'
};
</script>

我们来分析main.js里面的内容,逐条分析
关于引入的路由

import Vue from 'vue'
import Router from 'vue-router'
// 这种也好玩,引入组件,再在router中注册
import pageView from '@/pages/pageView'
import Home from '@/pages/home'
import Things from '@/pages/things'
import Designer from '@/pages/designer'
import Personal from '@/pages/personal'
import Pictoral from '@/pages/pictoral'
import Details from '@/pages/details'
import Comment from '@/pages/comment'
import About from '@/pages/about'

Router.prototype.goBack = function(){
    this.isBack = true;
    window.history.go(-1);
};

Vue.use(Router);

const routers = new Router({
  routes: [
    {
      path:'',
      name:'',
      component:pageView,
      children:[
        {
          path:'/',
          name:'',
          component:Home,
          children:[
           {
            path:'',
                name:'pictoral',
                meta:{index:1},
                component:Pictoral
              },
              {
                path:'/things',
                name:'things',
                meta:{index:1},
                component:Things
              },
              {
                path:'/designer',
                name:'designer',
                meta:{index:1},
                component:Designer
              },
              {
                path:'/personal',
                name:'personal',
                meta:{index:1},
                component:Personal
              },
          ]
        },
        {
          path:'/details/:id',
          name:'details',
          meta:{index:2},
          component:Details
        },
        {
          path:'/comment/:id',
          name:'comment',
          meta:{index:2},
          component:Comment
        },
        {
          path:'/about',
          name:'about',
          meta:{index:2},
          component:About
        }
      ]
    }
  ]
})

routers.beforeEach(function (to, from, next) { 
    document.body.scrollTop = document.documentElement.scrollTop = 0
    // 进入下一个页面的时候,都是页面的top为0那种
    next()
});

export default routers;

我们会发现引入了vue-scroller,这个其实是实现下拉刷新,上拉获取数据的功能的。
store中的内容不多,只是对tabIndex做了一个简单的下标赋值

//index.js
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

const store = new Vuex.Store({
    state:{
        tabIndex:0
    },
    mutations:{
        changeTab: function(state,index){
            state.tabIndex = index;
        }
    }
});

export default store

在mian.js页面还引入了tabBar,swiper,toast组件
先看tabBar组件

<template>
    <div class="tab-bar">
        <ul>
            <li v-for="(item,index) in itemList" 
                :key="index" class="tab-bar-item" 
                :class="{active: index == isActive}" 
                @click="addActive(index,item)">
                
                <span class="tab-bar-item_icon" :class="item.icon"></span>
                <span class="tab-bar-item_Text">{{item.text}}</span>
            </li>
        </ul>
    </div>
</template>
<script>
    export default{
        name:'tabbar',
        data (){
            return {
                isActive:this.$store.state.tabIndex,
                itemList:[
                    {text:"推荐",icon:"fa fa-clipboard",link:'/'},
                    {text:"作品",icon:"fa fa-smile-o",link:'/things'},
                    {text:"设计师",icon:"fa fa-pencil",link:'/designer'},
                    {text:"我",icon:"fa fa-user-o",link:'/personal'}
                ]
            }
        },
        mounted(){
            if(this.isActive != 0){
                this.$router.push(this.itemList[this.isActive].link);
            }
        },
        methods:{
            addActive: function(index,item){
                console.log('.....index',index)
                console.log('...item',item.link)
                this.isActive = index;
                this.$router.push(item.link);
                this.$store.commit("changeTab",index);
            }
        }
    };
</script>
//swiper.vue
<template>
    <div class="swiper-box">
        <swiper :options="swiperOption" ref="swiper" >
            <swiper-slide v-for="(data, index) in dataList" 
                          :key="index"
                          :class="{active: activeIndex == index}">
                <slot name="swiperMain" :data="data">{{data.text}}</slot>   
            </swiper-slide>
            <div class="swiper-pagination" slot="pagination"></div>
        </swiper>
    </div>
</template>
<script>
    import 'swiper/dist/css/swiper.css'
    import { swiper, swiperSlide} from 'vue-awesome-swiper'
    export default{
        name: 'appnav',
        props:{
            activeIndex:{},
            swiperOption:{
                type:Object
            },
            dataList:{}
        },
        components:{
            swiper,
            swiperSlide
        }
    };
</script>
//toast.vue
<template>
  <transition name="toast-fade">
    <div class="toast" v-show="visible" >
        <div class="toast-content">{{message}}</div>
    </div>
  </transition>
</template>
<script>
export default {
  name:'toast',
  data(){
    return {
      visible:false,
      message:''
    }
  }
}
</script>
//main.js
import Vue from 'vue'
import App from './App'
import router from './router'
import axios from 'axios'
import store from './store'
import scroller from 'vue-scroller'
import 'font-awesome/scss/font-awesome.scss'
import './assets/style/reset.css'
import './assets/style/style.scss'
import tabbar from './components/tabBar'
import swiper from './components/swiper'
import toast from './components/toast'

Vue.config.productionTip = false
Vue.config.devtools = true

Vue.prototype.$axios = axios;

Vue.use(scroller)
Vue.use(tabbar)
Vue.use(swiper)
Vue.use(toast)

new Vue({
  router,
  store,
  components: { App },
  render: h => h(App),
}).$mount("#app");

接下来我们结合router来看页面

//src\pages\pageView.vue
<template>
    <div class="page-view">
        <transition :name="transitionName">
            <router-view class="child-view"></router-view>
        </transition>
    </div>
</template>
<script>
    export default {
        name:"pageView",
        data() {
            return {
                transitionName:'slide-left'
            }
        },
        watch:{
            $route: function(to,from){
                console.log('what is to',to)
                console.log('what is from',from)
                let isBack = this.$router.isBack;
                if(isBack){
                    this.transitionName = 'slide-right';
                }else{
                    this.transitionName = 'slide-left';
                }
                this.$router.isBack = false;
            },
        }
    }/*  */
</script>
//src\pages\pageView.vue
<template>
    <div class="tab-bar">
        <ul>
            <li v-for="(item,index) in itemList" 
                :key="index" class="tab-bar-item" 
                :class="{active: index == isActive}" 
                @click="addActive(index,item)">
                
                <span class="tab-bar-item_icon" :class="item.icon"></span>
                <span class="tab-bar-item_Text">{{item.text}}</span>
            </li>
        </ul>
    </div>
</template>
<script>
    export default{
        name:'tabbar',
        data (){
            return {
                isActive:this.$store.state.tabIndex,
                itemList:[
                    {text:"推荐",icon:"fa fa-clipboard",link:'/'},
                    {text:"作品",icon:"fa fa-smile-o",link:'/things'},
                    {text:"设计师",icon:"fa fa-pencil",link:'/designer'},
                    {text:"我",icon:"fa fa-user-o",link:'/personal'}
                ]
            }
        },
        mounted(){
            if(this.isActive != 0){
                this.$router.push(this.itemList[this.isActive].link);
            }
        },
        methods:{
            addActive: function(index,item){
                console.log('.....index',index)
                console.log('...item',item.link)
                this.isActive = index;
                this.$router.push(item.link);
                this.$store.commit("changeTab",index);
            }
        }
    };
</script>

效果为
1037363-20190709204437057-1265957108.png
代码为:

<template>
    <div class="personal">
        <div class="personal-logo">
            <div class="logo">
                <span class="logo_img"><img src="/static/images/logo.jpg" alt=""></span>
                <span>登录</span>
            </div>
        </div>
        <div class="personal-main">
            <div class="personal-main_menu">
                <ul>
                    <li><i class="fa fa-thumbs-o-up"></i><span>我推荐的</span></li>
                    <li><i class="fa fa-heart-o"></i><span>我关注的</span></li>
                    <li><i class="fa fa-folder-open-o"></i><span>我的作品</span></li>
                </ul>
            </div>
            <div class="personal-main_list">
                <ul>
                    <li><i class="fa fa-bell-o"></i><span>消息中心</span><i class="fa fa-angle-right"></i></li>
                    <li><i class="fa fa-bullhorn"></i><span>联系我</span><i class="fa fa-angle-right"></i></li>
                    <li @click="toAbout"><i class="fa fa-meh-o"></i><span>关于</span><i class="fa fa-angle-right"></i></li>
                </ul>
            </div>
        </div>
    </div>
</template>
<script>
    import {prevent} from '../utils'
    export default{
        name: 'personal',
        mounted(){
            document.body.removeEventListener("touchmove",prevent);
        },
        methods: {
            toAbout:function(){
                this.$router.push("/about");
            }
        }
    };
</script>

1037363-20190709204600579-1343287980.png

//src\pages\about.vue
<template>
    <div class="about">
        <div class="page-title">    
            <span @click="goBack" class="goBack"><i class="fa fa-2x fa-angle-left"></i></span>  
            <h3>关于</h3> 
        </div>
        <div class="main">
            <p>声明:这只是一个练习的demo :( </p>
        </div>
    </div>
</template>
<script>
    export default{
        name: '',
        data (){
            return{
                desc:''
            }
        },
        methods: {
            goBack: function(){ 
                this.$router.goBack();  
            }
        }
    };
</script>

1037363-20190709205000114-281799490.png

//src\pages\things.vue
<template>
    <div class="things">
        <div class="things-nav">
            <swiper :dataList="navList" :activeIndex="activeIndex" ref="navSwiper" :swiperOption="swiperOptionNav" ></swiper>
        </div>
        <div class="things-main">
            <scroller 
                :on-refresh="refresh" 
                :refreshText="refreshText" ref="scroller">
                <span style="width:20px;height:20px;" class="spinner" slot="refresh-spinner"></span>
                <div class="things-time">TODAY</div>
                <swiper 
                    :dataList="navList"  
                    :swiperOption="swiperOptionMain"  ref="mainSwiper">
                    <div slot="swiperMain" slot-scope="slotProps">
                        <div v-for="(item, index) in slotProps.data.dataList" :key="index" class="things-item" >
                            <div class="things-img-wrapper" @click="showDetails(item.id)">
                                <img class="things-item_img" :src="item.img" alt="">
                                <span class="things-item_tips">{{item.author}}</span>
                            </div>
                            <div class="things-item-foot">
                                <div class="foot-desc">
                                    <span class="foot-desc_logo"><img :src="item.icon" alt=""></span>
                                    <div class="foot-desc_text">
                                        <p>{{item.author}}</p>
                                        <p class="origin">{{item.origin}}</p>
                                    </div>
                                </div>
                                <div class="foot-action">
                                    <span @click="like(item)" class="fa fa-meh-o action-up"></span><span  v-show="item.likeNum" class="like">+<i>{{item.likeNum}}</i></span> | <span @click="dislike(item)" class="fa fa-frown-o action-down"></span><span v-show="item.dislikeNum" class="dislike"><i>{{item.dislikeNum}}</i></span>
                                </div>
                            </div>
                        </div>
                    </div>
                </swiper>
            </scroller>
            <div class="to-top" @click="toTop"><i class="fa fa-arrow-up"></i></div>
        </div>
    </div>
</template>
<script>
    import { mixin,pageAct } from '../utils'
    export default{
        name: 'things',
        data (){
            return{
                likeNum:0,
                dislikeNum:0,
            }
        },
        mixins:[mixin,pageAct],
        methods:{
            showDetails: function(index){
                this.$router.push("/comment/"+index);
            },
            getData: function(cb){
                var self = this;
                this.$axios.post("/things",{}).then(function(response){
                    console.log('aaaaa...',response)
                    var result = response.data;
                    if(result.code == 200){
                        self.navList  = result.list;
                    }
                    
                }).catch(function(error){
                    console.log(error);
                });
            },
            loadMore: function(cb){
                var self = this;
                this.$axios.post("/things",{author:self.activeIndex}).then(function(response){
                    var result = response.data;
                    cb && cb(result);
                }).catch(function(error){
                    console.log(error);
                });
            }
        }
    };
</script>

1037363-20190709205439755-952897057.png

//src\pages\designer.vue

<template>
    <div class="designer">
        <div class="designer-nav">
            <swiper :dataList="navList" :activeIndex="activeIndex" ref="navSwiper" :swiperOption="swiperOptionNav" ></swiper>
        </div>
        <div class="designer-main">
            <keep-alive>
            <scroller :on-refresh="refresh" :refreshText="refreshText" ref="scroller">
                <span style="width:20px;height:20px;" class="spinner" slot="refresh-spinner"></span>
                <div class="designer-time">TODAY</div>
                    <swiper :dataList="navList"  ref="mainSwiper" :swiperOption="swiperOptionMain">
                        <div slot="swiperMain" slot-scope="slotProps">
                            <div v-for="(item, index) in slotProps.data.dataList" :key="index" class="designer-item" >
                                <div class="designer-img-wrapper" @click="showDetails(item.id)">
                                    <img class="designer-item_img" :src="item.img" alt="">
                                    <span class="foot-desc_logo"><img :src="item.icon" alt=""></span>
                                </div>
                                <div class="designer-item-foot">
                                    <div class="foot-desc">
                                        <div class="foot-desc_text">
                                            <p>{{item.author}} | <span class="origin">{{item.origin}}</span></p>
                                        </div>
                                    </div>
                                    <div class="foot-action">
                                        <span @click="showTotast" class="foot-actionr_follow">+ 关注</span>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </swiper>
            </scroller>
        </keep-alive>
            <div class="to-top" @click="toTop">
                <i class="fa fa-arrow-up"></i>
            </div>
        </div>
    </div>
</template>
<script>
    import {pageAct} from '../utils'
    export default{
        name: 'designer',
        mixins:[pageAct],
        methods:{
            showDetails: function(index){
                this.$router.push("/details/"+index);
            },
            getData: function(cb){
                var self = this;
                this.$axios.post("/designer",{}).then(function(response){
                    console.log('designer',response)
                    var result = response.data;
                    if(result.code == 200){
                        self.navList  = result.list;
                    }
                    
                }).catch(function(error){
                    console.log(error);
                });
            },
            loadMore: function(cb){
                var self = this;
                this.$axios.post("/designer",{author:self.activeIndex}).then(function(response){
                    var result = response.data;
                    cb && cb(result);
                }).catch(function(error){
                    console.log(error);
                });
            },
            showTotast: function(){
                this.$toast({message:"敬请期待关注功能 :-)"});
            }
        }
    };
</script>

1037363-20190709205744214-122587734.png
```vue
//src\pages\details.vue



<span @click="goBack" class="goBack">

{{title}}





<img :src="img" alt="">

简介


<div class="desc-item" v-for="(item, index) in descList" :key="index">
<i class="fa" :class="item.icon">
{{item.tips}}:

{{item.text}}




其他作品


<div class="desc-img-item" v-for="(item, index) in imgList" :key="index">
—{{item.originate}}—

<img :src="item.img" alt="">




转载于:https://www.cnblogs.com/smart-girl/p/11160453.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值