美文网首页IT编程web前端别人的好货
Vue2.0史上最全入坑教程(下)—— 实战案例

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

作者: 诺奕 | 来源:发表于2017-03-03 12:06 被阅读48609次

书接上文

前言:经过前两节的学习,我们已经可以创建一个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{
  width: 100%;
  height: 2rem;
}
.header{
  width: 100%;
  height: 2rem;
  position: fixed;
  left: 0;
  top: 0;
  background-color: #fff;
  border-bottom: 2px solid #ff8000;
}
.header h4 {
  width: 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;
    width: 100%;
    position: fixed;
    bottom: 0;
    left: 0;
    border-top: 2px solid #ccc;
    background-color: #fff;
  }
  .footer-cont li {
    float: left;
    width: 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;
    width: 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 {
    width: 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 {
    width: 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 {
    width: 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史上最全入坑教程(完)

相关文章

网友评论

  • f70a504813a0:找本地json文件那里 具体怎么弄得啊 为什么我配置没有用啊
  • ClarkM:漂亮
  • ded95bf9ba21:刚刚接触,请多多指教
  • ded95bf9ba21:你显示list的方法不太会,我就把list里的数据放到list.vue里了,为什么报img、title、price在实例里没有定义呢?
  • 75c4fe8609a0:托管托管你倒是发地址啊
  • 海是最蓝的天:github地址能发下吗
  • 89baf1829ac2:楼主,请问有把这个小例子的代码托管到github吗?我想看下代码
    诺奕:@Glee_59ea 已经托管了
  • 代码使劲儿搬:有没有源码参考一下呢,我这几个路由路径搭不好
  • a3e874c2cc2e:dev-server.js 已经不存在了, 楼主什么时候更新一下文档啊?
    诺奕:@小辣条丶 是的。【这个是解决方案】(http://www.jianshu.com/p/9c52ba3113da)
    17e47205a480:dev-server.js好像已经整合到webpack.dev.conf.js里了。
  • 5383a4404e3a:看了下评论,好多人都出现http://localhost:8080/api/goods/打不开,也不报错的情况,我这的症状是:浏览器地址栏输入http://localhost:8080/api/goods/,页面会秒跳到http://localhost:8080/api/goods/#/ 或者http://localhost:8080/api/goods#/ 直接又跳会vue欢迎页了,卡这了,不知道作者知道原因不(不是json文件注释的问题,我没加注释,甚至直接拷贝作者github上的goods.json过来,依然不行)
    8b39dd6c7022:@太想飞 请问解决了么 我也是这个情况
    5383a4404e3a:重新 npm run dev 也试过了 没用
  • 1b61edd205e1:楼主老哥,问下为什么我建的项目的没有dev-server.js这个文件
    诺奕:@要你命3千 解决方案(http://www.jianshu.com/p/9c52ba3113da)
  • fb0802d0abaa:请问下这个demo,有下载连接吗??我想下载一个,谢谢
    诺奕:@生活离奇 有的,在我github上就有。
  • 智慧互联:<div class="goods-list-pic">
    ![](img) <!-- 注意这图片的:src是vue的属性,里面的img是来自该组件的data中数据 -->
    </div>
    请问一下博主: ![](img)这是什么语法啊?
    诺奕:@Undefined_cabe 这个是markdown的语法,我编辑文章的时候写的。
  • 3c1798180979:获取不到JSON数据 注释删除了 App.vue也删除了 也npm run dev了 提示的是 Cannot GET / 什么原因啊
    诺奕:@好心小萍宝 他解决了。
    一名有马甲线的程序媛:我也遇到同样的问题了 请问你解决了吗
    诺奕:@後知後觉_63f6 删除App.vue的前提是你在路由配置指向到相关的地方,而增加的接口请求,需要在var app = express() 下面添加,因为要用到app这个东西。
  • aa4da27b7e5d:我按你的步骤下来的,获取不到数据,为什么?是有些步骤你省略了吗

    诺奕:@Ivy_c420 加QQ群吧。585472963,步骤我没省略。
    aa4da27b7e5d:我都自学好久了,:sob:
    aa4da27b7e5d:我把原本的router文件和main.ja删了,
  • 进击柚子:请问楼大大, props: ['price', 'title', 'img'] 这个父组件向子组件传递的参数,应该是detail.vue详情页会用到的吧,文章里只给出了传递,是不是还没写子组件detail.vue,所以暂时没用到?
    诺奕:@兜兜转转101 恩恩,我会加油的:blush: 谢谢支持!
    进击柚子:@datura_lj 是的看到了,谢谢。希望博主后面继续写好的博客,多多支持你!加油
    诺奕:您好这个是子组件用来接收父组件传递过来的数据,在本例中使用到了。具体数据传递看下我的另一个博客【http://www.jianshu.com/p/4cbc409516bf】
  • d094791f756c:我照着上面的顺序写,http://localhost:8080/api/goods 的json数据怎么都没有出来啊
    d094791f756c:@datura_lj 出来了,我代码打错了。。。多了一个 .
    诺奕:这个你看下,是不是你复制的代码,把注释复制了,.json文件不要有注释。然后在浏览器地址栏输入上面的地址,看看能否出来,或者报错信息是啥
    进击柚子:你可能还是code有问题,再认真检查一下,我的json数据就显示出来了
  • 5123ce5fab08:楼主,我的数据获取不到,也没有报错
    诺奕:您好,在浏览器地址栏输入也没有嘛?看看是不是在.json文件加注释了
  • 小草君w:很赞 学习了
    诺奕: @小草君w 谢谢支持
  • 95504c1e5a39:什么时候继续更新这篇呀
    95504c1e5a39: @datura_lj 好的,谢谢
    诺奕:@MrZ_6846 已经更新了啊 你看看下面的有的
  • 3812adf4de80:JSON数据的图片是绝对路径。怎么使用相对路径
  • ae17036eb1ef::joy: 没了?! 路由啥的怎么配的,组件怎么相互引用的?大哥
    诺奕:@HymanChen_0601 585472963
    ae17036eb1ef:@datura_lj 不好意思,群号没找到,请发下,
    诺奕:@Hyman_774b 恩 ,这个还没写呢。想了解其他的知识进群吧
  • af2e3d64c042:想问您一下 目前我按照您的代码完成了goods.json 删除了app.vue文件 然后更改了dev-server.js,但是使用网址查是否获取到json'数据时却一片空白没有数据 您能指点下可能的原因么
    af2e3d64c042:查了查发现需要重新npm run dev 谢谢您了 问题已经解决
    诺奕:@Silencer_valkyr 把.json文件内的注释删除一下
  • 844e3e877f38:你好,我新建项目之后,完全按照上面的步骤来做,也没用删改任何代码,但是测试数据的时候,打不开,显示localhost拒绝访问,是什么情况?
    844e3e877f38:F12 报错了 GET http://localhost:8080/api/goods net::ERR_CONNECTION_REFUSED http://localhost:8080/api/goods:1
    844e3e877f38:@datura_lj F12 没有报错信息,dev-sever.js 里加上那段代码之后,npm run dev 也运行不起来了,有error,注释之后就能运行。
    诺奕: @欲望涨停板 看看,什么报错信息。还有不要复制代码。尽量手敲
  • 悟空弜厸:楼主我的定义的接口访问不了,不报错,看了下逻辑没啥问题啊!!!
    诺奕: @悟空弜厸 不客气。好了就行。棒棒哒
    悟空弜厸: @悟空弜厸 谢谢回复,已经弄好了😊
    诺奕: @悟空弜厸 截图,看看啥问题
  • 88c54d1c0d95:[Vue warn]: Unknown custom element: <router-veiw> - did you register the component correctly? For recursive components, make sure to provide the "name" option.
    报这样的错误
    诺奕:@芮蕊 这句话的意思是<router-veiw>,没有注册。另外你的问题是单词写错了。router-view不是router-veiw。ps:话说你和我一个同学同名...
  • 8e0a2d888f28:作者你的学习目录的那里少了"Vue2.0史上最全入坑教程(中)—— 脚手架代码详解",如果不是有意可以加一下(逃
    诺奕:@执迷不悟_febe 好的,歇息,因为是之前写的,所以有的文章可能漏掉了。歇息提醒
  • YichenCWG:app.use('/api', apiRoutes) /* 定义接口在/api目录下,方便管理 */
    初学vue跟着走到这里,这个/api目录不是太理解,作者有空解答一下吗
    尝嗨:获取模拟数据的路径是不是不需要加/api
    YichenCWG:@datura_lj 懂了,谢谢
    诺奕: @YichenCWG 好的,有时间给你相信说下。你可以理解为在那个api下有n个配置的接口,api名字可以是随意的,但是开发后期需要和后台同事联调接口的时候用的是poxyTable 进行转发的
  • ea291a935151:json的注释不能复制进去,不然会报错,我用的是sublime,不知道是不是这个原因
    诺奕: @Mortimers 现在是什么报错信息
    Mortimers:我的把注释删了,还是出不来goods.json的数据,无法访问
    诺奕: @安迪范德 挺好,代码尽量手打
  • afb3671f2316:如果style添加了lang="scss",是不是需要下载相应的loader?
    诺奕:@让思想去远方 是
  • 7e85a4f2f2e2:菜鸟求教:每个组件里的 default export 是怎么处理的呀,有的为空,有的写了东西。希望作者能详细解释一下,多谢!
    诺奕:@兴兴兴哈哈哈 这个为啥要那么写就得去问作者尤大大了,个人理解为就是组件化开发吧,当前这个模板(或称组件)需要用的东西就在这个模板内写。当然如果需要进入别的组件内容就用es6的那个模块引入方式。
    7e85a4f2f2e2:@datura_lj 又看了一下,确实是这样,所有的 js 部分都在 default export 里面,但是为什么要这样呢?(可能问的低级了,望赐教!)
    诺奕: @兴兴兴哈哈哈 每个组件,有三个部分吧分别为写html和css和js的,你说的export default那个就是用来写js的,举个简单的例子,点击按钮弹1,就需要定义一个方法。在比如需要一个数据,就需要在定义一个数据
  • 活在初音的未来:另外,之前那个name,是用来定位错误的,最好每个vue页都进行定义。
    看到我报错下面有一行:
    found in <List>
    这个就是在定义过‘name‘之后才会有的,否则会提示让你去定义name
    诺奕:嗯 ,知道了,就是的那个哪一个组件有错的时候好查找,多谢
  • 活在初音的未来:list.vue
    <p class="goods-list-price">{{ price|dTofixed|dCurrency }}</p> <!-- 这里用到了过滤器货币形式和保留两位小数 -->
    这个vue2的过滤器不需要自定义吗?我这边报错:
    [Vue warn]: Failed to resolve filter: dCurrency
    (found in <List>)
    诺奕:Vue2.x所有的内置过滤器全部取消了,如果需要的话,只能自己手动去写
  • 相思雨gg:要获取数据必须要配置express吗?不能直接获取到数据文件吗
    8e0a2d888f28:@相思雨gg express在这里是搭建了一个简单的服务器来提供一个完整的开发环境,正常工作中的服务器如何发送数据是后端写,不用前端配置
    相思雨gg: @datura_lj 正常工作中用vue-resource获取后台数据就不用配置express了吗
    诺奕:这个只是 模拟下数据获取,正常情况下是通过vue-resouce的ajax函数来获取后台的数据的

本文标题:Vue2.0史上最全入坑教程(下)—— 实战案例

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