美文网首页
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