• Vue2.0史上最全入坑教程(下)—— 实战案例


     

    书接上文

    前言:经过前两节的学习,我们已经可以创建一个vue工程了。下面我们将一起来学习制作一个简单的实战案例。

    说明:默认我们已经用vue-cli(vue脚手架或称前端自动化构建工具)创建好项目了

    一、 项目说明

    ps:这个简单小项目只提供一个小小小的骨架,需要向“它”身上具体加多少“肉”,需要大家考虑好功能和布局后进行完善。

    1.首先看下主页效果:如下图


     

    主页分析:大体上分为上(header)、中(body或content)、下(footer)三部分,中间body部分是由若干个相同的li组成的“列表”,所以我们可将li定义为一个组件。
    2.再来看下商品详情页:如下图


     

    详情页分析:也分为上、中、下三部分。
    分析后是不是觉得so easy呢!很好那么我们就一起来搞一下!!

    二、 配置目录文件

    在src文件夹(也就是我们码农主要工作区)下,创建assets文件夹(用来保存项目所需图片)、components(存组件commonFooter.vue、DetailHeader.vue、homeHeader.vue、list.vue)、pages(存页面goodsDetail.vue、home.vue)和main.js文件。详情请看下图:

    ps: 1.具体文件夹以及文件名称可根据自己项目进行“自拟”。 2.这里的每一个*.vue文件都是一个组件。
     

    三、配置相关接口

    主页商品信息及图片, 是从服务器端返回的json数据,不可能所以商品都“写死”。故这里需要模拟后台建立了一个数据文件。在根目录下建立一个goods.json文件用来放“伪数据”,如下图:


     
    注意:下面的注释不要复制进去。否则可能会报错。
    /* 模拟数据_代码 */
    /* 这里只简单模拟一组比较规整数据,如大家有需求可自行加所需数据 */
    {
        "goods": [
            { "price": "69.9", "title": "德芙", "img": "http://m.360buyimg.com/babel/s211x211_jfs/t3688/270/776223567/128582/fa074fb3/58170f6dN6b9a12bf.jpg!q50.jpg.webp" },
            { "price": "63", "title": "费列罗", "img": "http://m.360buyimg.com/babel/s211x211_jfs/t613/100/1264998035/221234/1a29d51f/54c34525Nb4f6581c.jpg!q50.jpg.webp"},
            { "price": "29.9", "title": "大米", "img": "http://m.360buyimg.com/babel/s211x211_jfs/t1258/40/17387560/108696/aced445f/54e011deN3ae867ae.jpg!q50.jpg.webp"},
            { "price": "54.9", "title": "安慕希", "img": "http://m.360buyimg.com/babel/s211x211_jfs/t2734/15/680373407/215934/3abaa748/572057daNc09b5da7.jpg!q50.jpg.webp"},
            { "price": "58", "title": "金典", "img": "http://m.360buyimg.com/babel/s211x211_jfs/t2482/145/1424008556/91991/d62f5454/569f47a2N3f763060.jpg!q50.jpg.webp"},
            { "price": "60", "title": "味可滋", "img": "http://m.360buyimg.com/babel/s211x211_jfs/t2368/3/874563950/70786/7b5e8edd/563074c8N4d535db4.jpg!q50.jpg.webp" },
            { "price": "248.00", "title": "泸州老窖", "img": "http://m.360buyimg.com/babel/s211x211_jfs/t283/166/1424018055/189580/7c0792b7/543b4958N05fa2feb.jpg!q50.jpg.webp"},
            { "price": "328.8", "title": "剑南春", "img": "http://m.360buyimg.com/babel/s350x350_g15/M05/1A/0A/rBEhWlNeLAwIAAAAAAHyok3PZY0AAMl8gO8My0AAfK6307.jpg!q50.jpg.webp"},
            { "price": "49.00", "title": "蓝莓", "img": "http://m.360buyimg.com/babel/s211x211_jfs/t2332/148/2952098628/94387/e64654e2/56f8d76aNb088c2ab.jpg!q50.jpg.webp" },
            { "price": "68", "title": "芒果", "img": "http://m.360buyimg.com/n0/jfs/t3709/334/1378702984/206759/5c100ab5/58253588Naaa05c5c.jpg!q70.jpg"}
        ]
    }
    

    数据文件创建完成后,就需要写一个接口了,在build文件夹下dev-server.js文件进行配置。如图:


     
    • 注意
      本文是在vue-cli2.8.1的时候编写。最近很多小伙伴vue -V版本为2.9.1找不到derver.js文件。。现已提供两种解决方案以便参考
    简单说明:
    1. 需要在var app = express() 代码下写新增代码,,因通过接口获取数据依赖与express() 对象下方法;
    1. 用require引入模拟数据的文件;
    2. 用express对象下的Router方法来指定入口在哪。
    3. 对进入“入口”的obj,返回相关数据。
    /* datura接口 20170302 */
    var appData = require('../goods.json')  /* 引入根目录下goods.json数据文件 */
    var goods = appData.goods   /* goods.json文件文件下的.goods数据赋值给变量goods */
    var apiRoutes = express.Router()  /* 定义express.Router() 对象 */
    apiRoutes.get('/goods', function(req, res){   /* 定义接口并返回数据 */
      res.json({
        data: goods
      })
    })
    app.use('/api', apiRoutes)  /* 定义接口在/api目录下,方便管理 */
    /* datura接口 _end */
    

    测试是否该数据可用,在浏览器地址栏中输入:http://localhost:8090/api/goods ,此处因为本人PC的8080端口有冲突所以改成端口8090。在浏览器中展示出如下图数据,代码数据数取成功:

     

    四、编写页面代码

    1. 页面入口index.html:

    知识点:

    1. 定义挂载Vue实例的对象“#app”;
    2. 必须定义数据战术区域,这里用<router-view></router-view>标签展示组件或模版;
    3. 根据不同设备分辨率改变根字体大小从而达到终端适配。
    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8">
        <title>secondproject</title>
        <style media="screen">  
        /* 简单进行默认样式重置 */
          * {margin: 0;padding: 0}
          li {list-style: none;}
          a {text-decoration: none;}
          img {vertical-align: middle;}
        </style>
      </head>
      <body>
        <div id="app">
          <router-view></router-view>  <!-- 这里是展示来自路由页面数据的 -->
        </div>
      </body>
      <script type="text/javascript">
      /* 因为我们后面用的是rem布局,所以这里做下处理,根据不用设备分辨率更改跟字体大小。 rem相关布局[请参考](http://www.jianshu.com/p/65f80d4b44bb)*/
        (function(win,doc){
              change();
              function change(){
                  doc.documentElement.style.fontSize = doc.documentElement.clientWidth *20/320+'px';
              }
              win.addEventListener('resize',change,false);
              win.addEventListener('orientationchange',change,false);  /* 这个是移动端设备横屏、竖屏转换时触发的事件处理函数 */
          })(window,document);
      </script>
    </html>
    
    2. 主要模版home.vue:这个是来展示数据的,并通过vue的路由展示到index.html。

    因为home.vue用到了三个组件,所以我们就先编写下这几个组件
    a). homeHeader.vue:和之前说的一样,在template标签里写html代码,style标签里写css代码,script标签里写js代码

    知识点:<style></style>属性可进行配置,scoped表此样式只在当前页面有效。lang="xxx"支持less/sass语法规则。

    <template lang="html">
      <div class="head">
        <div class="header">
          <h4 class="header-cont">主页</h4>
        </div>
      </div>
    </template>
    <script>
    export default {
    }
    </script>
    <style lang="css" scoped>
    .head{
       100%;
      height: 2rem;
    }
    .header{
       100%;
      height: 2rem;
      position: fixed;
      left: 0;
      top: 0;
      background-color: #fff;
      border-bottom: 2px solid #ff8000;
    }
    .header h4 {
       100%;
      text-align: center;
      line-height: 2rem;
      font-size: 1.4rem;
    }
    </style>
    

    b). commonFooter.vue:
    说明:定义一个footer并定位到页面的底部,在ul内写4个li来模拟按钮。

    <template lang="html">
      <div class="footer">
        <ul class="footer-cont">
            <li>1</li>
            <li>2</li>
            <li>3</li>
            <li>4</li>
        </ul>
      </div>
    </template>
    <script>
    export default {
    }
    </script>
    <style lang="css">
      .footer {
        height: 1.8rem;
         100%;
        position: fixed;
        bottom: 0;
        left: 0;
        border-top: 2px solid #ccc;
        background-color: #fff;
      }
      .footer-cont li {
        float: left;
         25%;
        height: 1.8rem;
        line-height: 1.8rem;
        font-size: 1.4rem;
        color: #ff8000;
        text-align: center;
      }
      .footer-cont li:active {
        background-color: #ccc;
      }
      .footer-cont:after {
        content: '';
        display: block;
        clear: both;
         0;
        height: 0;
      }
    </style>
    
    

    c). list.vue:这个组件用来展示每个商品列表信息

    知识点:

    1. 类似a标签功能的<router-link to="/detail"></router-link>标签,来规定发生点击事件后需要跳转的地址。
    2. :src="img" 中的img是来自父组件的数据,这里用到了父组件向子组件传递数据。props对象在后续的深入学习中会详细解释。
    3. {{ xxx }} 模版展示数据,也可用v-text='xxx',v-html='xxx'来展示数据。后者是防止当网速超慢时,用户会看到大花括号。
    4. {{ xxx|aa|bb }}模版展示数据+过滤器,过滤器顾名思义就是对展示的数据加以过滤,例如这里的是加个符号并保留两位小数。
    5. props
    <template lang="html">
      <li class="goods-list">
        <router-link to="/detail"  class="goods-list-link">  <!--  这个是用来跳转页面的,可以理解为a标签 -->
          <div class="goods-list-pic">
              <img :src="img" alt="">
          </div>
          <div class="goods-list-desc">
            <p class="goods-list-name">{{ title }}</p>   
            <p class="goods-list-price">{{ price|dTofixed|dCurrency }}</p>  <!-- 这里用到了过滤器货币形式和保留两位小数 -->
          </div>
        </router-link>
      </li>
    </template>
    
    <script>
    export default {
      props: ['price', 'title', 'img']   /*  props是子组件获取父组件数据用的 */
    }
    </script>
    
    <style lang="css" scoped>
      .goods-list {
         50%;
        float: left;
        box-sizing: border-box;
        margin-bottom: 0.2rem;
      }
      .goods-list:nth-of-type(odd) {
        border-right: 0.15rem solid #ccc;
      }
      .goods-list:nth-of-type(even) {
        border-left: 0.15rem solid #ccc;
      }
      .goods-list-link {
        display: block;
        padding: 0.5rem 0;
        margin: 0 0.3rem;
        text-align: center;
        background-color: #fff;
      }
      .goods-list:nth-of-type(even) .goods-list-link{
        margin-left: 0;
      }
      .goods-list:nth-of-type(odd) .goods-list-link{
        margin-right: 0;
      }
      .goods-list-pic {
        padding: 0.5rem;
      }
      .goods-list-pic > img {
         auto;
        height: 4rem;
      }
      .goods-list-desc {
        padding: 0 0.5rem;
      }
      .goods-list-desc:after {
        display: block;
        content: '';
        clear: both;
      }
      .goods-list-name,.goods-list-price {
         50%;
        height: 1.2rem;
        line-height: 1.2rem;
        font-size: 0.8rem;
        color: #333;
        float: left;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
      }
      .goods-list-price {
        color: #ff8000;
        float: right;
      }
    </style>
    
    

    Vue2.0史上最全入坑教程(完)

  • 相关阅读:
    deep_learning_Function_numpy_random.normal()
    deep_learning_Function_np.newaxis参数理解
    deep_learning_Function_numpy.linspace()
    deep_learning_Function_tf.identity()
    deep_learning_Function_tf.control_dependencies([])
    deep_learning_Function_tf.train.ExponentialMovingAverage()滑动平均
    deep_learning_Function_bath_normalization()
    deep_learning_PCA主成分分析
    deep_learning_Function_numpy_argmax()函数
    deep_learning_Function_matpotlib_scatter()函数
  • 原文地址:https://www.cnblogs.com/gluncle/p/8334690.html
Copyright © 2020-2023  润新知