美文网首页
vue(移动端)webpack+rem+vant项目实战

vue(移动端)webpack+rem+vant项目实战

作者: 五四青年_4e7d | 来源:发表于2020-03-01 00:11 被阅读0次

    页面效果预览


    image.png

    目录设计:

    image.png

    下载stylus,并使用(不一定是必须的):

    命令:cnpm install stylus-loader --save-dev

    <style lang="stylus" rel="stylesheet/stylus">
    </style>
    

    路由导航(配置底部tabar):

    1.在\src\components\FooterGuide\FooterGuide.vue创建组件(底部导航栏)
    2.在\src\pages下创建4个文件夹分别是4个底部栏切换对应的页面;


    image.png

    移动端引入reset.css

    地址:https://huruqing.gitee.io/demos/source/reset.css
    在\static\css创建reset.css,并且引入项目(在index.html中引入):

     <link rel="stylesheet" href="./static/css/reset.css">
    

    页面index.html的注意事项:

    1.引入fastclick.js解决移动端页面300毫秒延迟问题;

    <script src="https://as.alipayobjects.com/g/component/fastclick/1.0.6/fastclick.js"></script>
      <script>
          if ('addEventListener' in document) {
          document.addEventListener('DOMContentLoaded', function() {
          FastClick.attach(document.body);
          }, false);
          }
          if(!window.Promise) {
          document.writeln('<script src="https://as.alipayobjects.com/g/component/es6-promise/3.2.2/es6-promise.min.js" '+'>'+'<'+'/'+'script>');
          }
        </script>
    

    2.获取浏览器的宽度:

    <script>
    //获取当前的浏览器宽度
    let htmlWidth = document.documentElement.clientWidth || document.body.clientWidth
    //获取页面的html标签
    let htmlDom = document.getElementsByTagName('html')[0]
    if(htmlWidth > 750 ) {htmlWidth=750}
    htmlDom.style.fontSize = htmlWidth/20 +'px'
    console.log(htmlWidth)
    
    
    </script>
    

    按需导入使用vant:

    1.下载:npm i vant -S

    1. 下载:npm install babel-plugin-import --save-dev
    2. 在.babelrc文件中配置plugins(插件)
    {
      "presets": [
        ["env", {
          "modules": false,
          "targets": {
            "browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
          }
        }],
        "stage-2"
      ],
      "plugins": [
        "transform-vue-jsx", 
        "transform-runtime",
        ["import", [{ "libraryName": "vant", "style": true }]]
      ]
    }
    
    

    4.组件按需使用:

    import { Button } from 'vant'
    export default {
       components: {
        [Button.name]: Button
      },
      data () {
        return {
        
        }
      }
    }
    </script>
    

    路由导入和导入组件:

    import Vue from 'vue'
    import Router from 'vue-router'
    import Home from '@/pages/home/home'
    import Move from '@/pages/move/move'
    import Myshop from '@/pages/myshop/myshop'
    import Search from '@/pages/search/search'
    Vue.use(Router)
    
    export default new Router({
      routes: [
        {
          path: "/",
          redirect: "/home",
        },
        {
          path: '/home',
          name: 'Home',
          component: Home
        },
        {
          path: '/move',
          name: 'Move',
          component: Move
        },
        {
          path: '/myshop',
          name: 'Myshop',
          component: Myshop
        },
        {
          path: '/search',
          name: 'Search',
          component: Search
        }
      ]
    })
    

    app.vue导入:

    <template>
      <div id="app">
        <router-view/>
        <FooterGuide/>
      </div>
    </template>
    <script>
    //引入封装好的footer
    import FooterGuide from './components/FooterGuide/FooterGuide'
    export default {
      components:{
       FooterGuide    //映射为组件标签
      },
      name: 'App'
    }
    </script>
    

    封装APP底部切换导航栏:

    <template>
    
      <div class="footer_guide">
        <a href="javascript:;"  class="guide_item" :class="{on: '/home'===$route.path}" @click="goTo('/home')">
            <span class="item_icon">
            <van-icon name="chat-o" />
            </span>
            <span>消息</span>
        </a>
        <a href="javascript:;" class="guide_item" :class="{on: '/move'===$route.path}" @click="goTo('/move')">
            <span class="item_icon">
            <van-icon name="star-o" />
            </span>
            <span>列表</span>
        </a>
        <a href="javascript:;" class="guide_item" :class="{on: '/myshop'===$route.path}" @click="goTo('/myshop')">
            <span class="item_icon">
            <van-icon name="play-circle-o" />
            </span>
            <span>视频</span>
        </a>
        <a href="javascript:;" class="guide_item" :class="{on: '/search'===$route.path}" @click="goTo('/search')">
            <span class="item_icon">
            <van-icon name="manager-o" />
            </span>
            <span>我的</span>
        </a>
     </div>
      
    </template>
    
    <script>
    import { Button,Icon } from 'vant'
    export default {
       components: {
        [Button.name]: Button,
        [Icon.name]: Icon
      },
      data () {
        return {
        
        }
      },
      methods:{
          goTo(path){
              this.$router.replace(path)
              } 
        }
    }
    </script>
    
    <!-- Add "scoped" attribute to limit CSS to this component only -->
    <style scoped>
    .footer_guide{
        position: fixed;
        bottom:0;
        left:0;
        width:100%;
        height:3.5rem;
        border-top:1px solid #ccc;
        display:flex;
        justify-content: space-between;
    }
    .footer_guide>a{
        display:flex;
        justify-content: center;
        align-items: center;
        flex-direction: column;
        font-size:1.2rem;
    }
    .footer_guide>a .item_icon{
     font-size:1.5rem;
    }
    .on{
        color:#409cef;
        font-weight: 500
    }
    a{
        color:#333
    }
    
    </style>
    
    

    封装顶部导航:

    组件:

    <template>
      <div class="header">
        <slot name="left"></slot>
        <span class="header_title">
          <span class="header_title_text ellipsis">{{title}}</span>
        </span>
        <slot name="right"></slot>
      
      </div>
    </template>
    
    <script>
    import { Col, Row } from 'vant';
    export default {
      props:{
       title:String
      },
      data () {
        return {
      
        }
      }
    }
    </script>
    
    
    <style scoped>
    .header{
      position: fixed;
      top:0;
      width:100%;
      height:2.5rem;
      background:#409cef;
      color:#fff;
      line-height: 2.5rem;
      display:flex;
      justify-content: center;
      align-items: center;
      font-size:1.2rem;
    }
    </style>
    
    

    页面使用:

    <template>
      <div class="home">
           <HeadTop title="陕西省西安市长安区">
           <van-icon name="location-o" color="#fff" slot="right"/>
           </HeadTop>
        <van-grid :gutter="10">
        <van-grid-item
        v-for="value in 8"
        :key="value"
        icon="photo-o"
        text="文字"
       />
    </van-grid>
      </div>
    </template>
    
    <script>
    import HeadTop from '../../components/HeadTop/HeadTop'
    import { Button, Grid, GridItem,Icon  } from "vant";
    export default {
      components: {
        HeadTop,
        [Button.name]: Button,
        [Grid.name]: Grid,
        [GridItem.name]: GridItem,
        [Icon.name]: Icon 
      },
      data() {
        return {
        
        };
      }
    };
    </script>
    <style scoped>
    </style>
    

    抽取列表组件

    1.封装列表组件

    <template>
      <div class="shoplist">
        <div v-for="(item,i) in images" :key="i">
       <van-card
        tag="新品"
      :price="item.num"
      desc="全场满220减50"
      :title="item.title"
      :thumb="item.url"
    />
    </div>
      </div>
    </template>
    
    <script>
    import { Card } from 'vant';
    export default {
      components:{
       [Card.name]:Card,
      },
      data () {
        return {
           images: [
            {url:'//img10.360buyimg.com/mobilecms/s500x500_jfs/t1/109124/17/7141/153432/5e576844E7f03e024/da069e4dcf5a2208.jpg',num:6500,title:'凤凰智能电动车电瓶车'},
            {url:'//img11.360buyimg.com/mobilecms/s280x280_jfs/t1/85491/12/12484/174088/5e4a503aEd1def3c6/aa427e4576cb7f54.jpg.webp',num:120,title:'水保湿水嫩肌肤 网红泡泡面膜'},
            {url:'//img14.360buyimg.com/mobilecms/s144x144_jfs/t1/96519/34/12982/178001/5e511c49E8540d811/369718c8dddf7e8b.jpg!q70.jpg.webp',num:190,title:'加绒】加厚打底裤女裤保暖'},
            {url:'//img11.360buyimg.com/mobilecms/s500x500_jfs/t1/92861/31/13325/107318/5e54d4a2Ef3437c5b/ffb820244bca796b.jpg',num:340,title:'今日必抢●西域骆驼 休闲男鞋'},
            {url:'//img13.360buyimg.com/img/s200x200_jfs/t24502/249/196118255/249774/2449f607/5b28b2e4Necc55ac2.jpg!cc_100x100.webp',num:200,title:'生鲜馆尝遍天下鲜'}
          ]
        }
      }
    }
    </script>
    <style scoped>
    
    </style>
    
    

    2.页面调用:

    <template>
      <div class="home">
           <HeadTop title="陕西省西安市长安区">
           <van-icon name="location-o" color="#fff" slot="right"/>
           </HeadTop>
        <van-grid :gutter="10">
        <van-grid-item
        v-for="value in 8"
        :key="value"
        icon="photo-o"
        text="文字"
       />
    </van-grid>
    <ShopList/>
      </div>
    </template>
    
    <script>
    import HeadTop from '../../components/HeadTop/HeadTop'
    import ShopList from '../../components/ShopList/ShopList'
    import { Button, Grid, GridItem,Icon  } from "vant";
    export default {
      components: {
        HeadTop,
          ShopList,
        [Button.name]: Button,
        [Grid.name]: Grid,
        [GridItem.name]: GridItem,
        [Icon.name]: Icon 
      },
      data() {
        return {
          msg: "Welcome to Your Vue.js App"
        };
      }
    };
    </script>
    
    <!-- Add "scoped" attribute to limit CSS to this component only -->
    <style scoped>
    </style>
    

    3.效果:


    image.png

    (登录注册)页面和(我的页面)逻辑:

    1.创建登录页面组件:

    <template>
      <div class="seach">
        <HeadTop title="登录"></HeadTop>
        <div class="top"><van-icon name="arrow-left"  @click="$router.back()"/></div>
        <van-form @submit="onSubmit">
          <van-field
            v-model="username"
            name="用户名"
            label="用户名"
            placeholder="用户名"
            :rules="[{ required: true, message: '请填写用户名' }]"
          />
          <van-field
            v-model="password"
            type="password"
            name="密码"
            label="密码"
            placeholder="密码"
            :rules="[{ required: true, message: '请填写密码' }]"
          />
          <div style="margin: 16px;">
            <van-button round block type="info" native-type="submit">登录</van-button>
          </div>
        </van-form>
      </div>
    </template>
    
    <script>
    import { Form, Field,Button, Icon  } from "vant";
    import HeadTop from "../../components/HeadTop/HeadTop";
    export default {
      components: {
        HeadTop,
        [ Field.name]: Field,
        [Form.name]:Form,
        [Button.name]:Button,
        [Icon.name]:Icon
      
      },
      data() {
        return {
         username: '',
          password: '',
    
        };
      },
      methods:{
        onSubmit(values) {
          console.log('submit', values);
        },
      }
    };
    </script>
    
    <!-- Add "scoped" attribute to limit CSS to this component only -->
    <style scoped>
    .top{
      width: 100%;
        height: 2.5rem;
        /* background: Red; */
        /* margin-top: -1.3rem; */
        color: #fff;
        position: fixed;
        z-index: 999;
        top: 0;
        font-size: 1.2rem;
        justify-content: flex-start;
        align-items: center;
        display: flex;
    }
    </style>
    

    2.我的页面组件:

    <template>
      <div class="seach">
        <HeadTop title="我的"></HeadTop>
        <router-link to="/login">
    登录/注册
        </router-link>
        <van-contact-card
        type="edit"
       name="李慷"
       tel="18092641737"
      :editable="false"
    />
      </div>
    </template>
    
    <script>
    import HeadTop from "../../components/HeadTop/HeadTop";
    import { ContactCard, ContactList, ContactEdit } from "vant";
    export default {
      components: {
        HeadTop,
        [ContactCard.name]: ContactCard,
        [ContactList.name]: ContactList,
        [ContactEdit.name]: ContactEdit
      },
      data() {
        return {
        };
      }
    };
    </script>
    
    
    </style>
    
    

    3.使用路由的标识符判断(如果不是切换页面不显示底部栏目)

     {
          path: '/home',
          name: 'Home',
          component: Home,
          meta:{
            showFooter:true
          }
        },
     <FooterGuide  v-show="$route.meta.showFooter"/>
    

    4.效果:


    image.png

    项目中使用echrts

    1.下载:cnpm install echarts --save 注意页面按需使用
    2.页面导入使用:

     const echarts = require('echarts');
    

    3.页面使用,在 mounted()声明周期函数中:

     mounted()
    

    4.效果:


    image.png

    使用:highcharts

    1.下载:cnpm install highcharts --save
    2.在main.js中配置:

    import Vue from 'vue'
    import App from './App'
    import router from './router'
    Vue.config.productionTip = false
    
    
    import Highcharts from 'highcharts/highstock';
    import HighchartsMore from 'highcharts/highcharts-more';
    import HighchartsDrilldown from 'highcharts/modules/drilldown';
    import Highcharts3D from 'highcharts/highcharts-3d';
    import Highmaps from 'highcharts/modules/map';
    
    HighchartsMore(Highcharts)
    HighchartsDrilldown(Highcharts);
    Highcharts3D(Highcharts);
    Highmaps(Highcharts);
    
    
    
    /* eslint-disable no-new */
    new Vue({
      el: '#app',
      router,
      render: h => h(App),
      methods:{
     
        moreChart() {
            var options = this.getMoreOptions(this.type);
     
            if (this.chart) {
                this.chart.destroy();
            };
        // 初始化 Highcharts 图表
        this.chart = new Highcharts.Chart('highcharts-more', options);
        }
      }
    })
    
    

    相关文章

      网友评论

          本文标题:vue(移动端)webpack+rem+vant项目实战

          本文链接:https://www.haomeiwen.com/subject/qtgphhtx.html