vue项目什么刷新当前页面包车型地铁点子,vue项目怎么样刷新当前页面

By admin in 4858美高梅 on 2019年4月4日

1.场景

1.场景

导言


最近在学AngularJS的实例教程PhoneCat Tutorial
App,发现网上的华语教程都比较遥远,与英文版对应不上,而且缺少组件和文件重构两节。所以决定自身收十一个汉语简明教程。

此篇为6-7节。
上一篇:AngularJS
Phonecat(步骤0-步骤5)

本篇小说是一篇Vue.js的教程,目的在于用壹种普遍的业务场景——分页/Infiniti加载,协助读者更好的理解Vue.js中的壹些布置思想。与众多Todo
List类的入门教程比较,更完美的浮现使用Vue.js达成二个急需的怀念进程;与1些创设大型应用的高阶教程比较,又更令人瞩目于部分零星细节的贯彻,方便读者相当慢控制、致用。

在处理列表时,平日有删除一条数据可能新增多少之后须要再行刷新当前页面包车型地铁供给。

在处理列表时,日常有删除一条数据恐怕新增多少今后须求再行刷新当前页面包车型地铁急需。

陆 下拉挑选框–双向绑定


大家要追加2个下拉摘取框,用于选拔排序必要,让手提式无线电话机列表按须求排序。
为了落到实处机关排序,大家要在数据模型中添加排序的依据,并与迭代器联系起来。

须求分析

当2个页面中国国投息量过大时(例如一个谍报列表中有200条新闻须求展现),就会产生难点,例如:

  • 数据量过大,影响加载速度
  • vue项目什么刷新当前页面包车型地铁点子,vue项目怎么样刷新当前页面。用户体验差,很难定位到事先本身看过的某篇小说
  • 扩大性差,假诺200条变为3000条只怕更加多

因而广大的消除思路正是至底时加载数据依旧分页显示。Infiniti加载的贯彻进程看似于:

  1. ajax类方法获取数据
  2. 数码存入本地数组
  3. 数组中的每条数据对应插入三个HTML模板片段中
  4. 将HTML片段append到节点中

前端分页的完成进度看似于:

  1. ajax类方法获取数据
  2. 数量替换本地数组
  3. 数组中的每条数据对应插入三个HTML模板片段中
  4. 清空节点后将HTML片段append到节点中

多次修改可能保卫安全代码时,大家会发现渲染HTML和插入部分是比较烦人的。因为大家必要将HTML拼接成字符串,在对应的地方插入数据,往往就是一段相当的短的字符串,之后想要加个class都来之不易。es6的模版字符串让这些景况拥有好转,不过如故有欠缺(例如实际编写时心慌意乱HTML代码高亮)。

再者大家还索要写过多for可能forEach去循环数组,再命令式的append,倘若那段代码片段有①部分错综复杂的互相,恐怕还必要经过事件代理绑定一批方法。

要是在成就那类业务时,你也遇上过上述的难点,那么您就会发觉Vue真是太coooooool了,let’s
vue!

贰.相见的难点

二.遇上的题目

零件模板

app/phone-list/phone-list.template.html:

<div class="container-fluid">
  <div class="row">
    <div class="col-md-2">
      <!--Sidebar content-->

      <p>
        Search:
        <input ng-model="$ctrl.query">
      </p>

      <!--新增选择框,绑定$ctrl.orderProp-->
      <p>
        Sort by:        
        <select ng-model="$ctrl.orderProp">
          <option value="name">Alphabetical</option>
          <option value="age">Newest</option>
        </select>
      </p>

    </div>
    <div class="col-md-10">
      <!--Body content-->
      <!--新增orderBy,以$ctrl.orderProp为依据-->
      <ul class="phones">
        <li ng-repeat="phone in $ctrl.phones | filter:$ctrl.query | orderBy:$ctrl.orderProp">                
          {{phone.name}}
          <p>{{phone.snippet}}</p>
        </li>
      </ul>

    </div>
  </div>
</div>
  • 扩充<select>成分,并绑定到
    $ctrl.orderProp(数据模型),用户可以从七个接纳中展开抉择。而orderBy又以$ctrl.orderProp为基于,那样选定的选项就会成为排序依照。
    那种双向数据绑定,能够让数据变动及时反映到视图中,且不要求钦定DOM操作。
  • orderBy连接了filter,过滤后的数据才会输入orderBy举办排序。orderBy的做事原理是,复制输入的数组、举行排序、输出。

新建一个Vue.js项目

强烈推荐使用vue-cli来新建一个品类。

1起头你也许会觉得用node.js和npm安装一大堆库,生成了有的你不太精通的目录和布局文件,一写代码还会跳出一群eslint的提醒。可是那纯属物有所值,因为那样的三个模板能够帮你更好的明白Vue.js协会文件的笔触,并且当您适应之后,你会意识那个规则十分的大地加速了您的支出功能。

在本次的教程中,大家新建了3个称作loadmore的类型,具体的新建项目流程能够参照官网教程的设置壹节。

  1. 用vue-router重新路由到日前页面,页面是不开始展览刷新的
  1. 用vue-router重新路由到近来页面,页面是不进行刷新的

零件控制器

app/phone-list/phone-list.component.js:

angular.
  module('phoneList').
  component('phoneList', {
    templateUrl: 'phone-list/phone-list.template.html',
    controller: function PhoneListController() {
      this.phones = [
        {
          name: 'Nexus S',
          snippet: 'Fast just got faster with Nexus S.',
          age: 1            //新增了age属性
        }, {
          name: 'Motorola XOOM™ with Wi-Fi',
          snippet: 'The Next, Next Generation tablet.',
          age: 2
        }, {
          name: 'MOTOROLA XOOM™',
          snippet: 'The Next, Next Generation tablet.',
          age: 3
        }
      ];

      this.orderProp = 'age';       //默认以“age”为排序依据
    }
  });
  • 修改数据模型:各种phone对象都新增了age属性,用于按手提式有线电话机推出时间排序。
  • 设置默许以“age”为排序依照。如果不安装暗中同意值,即手提式有线电话机列表不会议及展览开排序,直到用户从下拉菜单中选用选项。
  • 双向绑定:页面加载后,大家会看出“Newest”被选中,那是因为控制器设置了私下认可排序依照“age”,达成了数据模型–>UI的绑定。如若大家在下拉菜单中甄选“Alphabetically”,数据模型也会更新,进而手提式有线电话机列表重新展开排序,那正是UI–>数据模型的绑定。
    小结起来正是,改变数据模型会变动视图,改变视图也会变动数据模型。

布局页面结构

为了合作课程的稳步深切,小编先从实现加载更加多效益入手。为了和事后的分页保持1致,作者的页面准备由两部分构成,一是音信列表,2是底层的3个加载更加多的按钮,作者将他们都置身App.vue这一个根组件中。

<template>
  <div id="app">
    <list></list>
    <a class="button" @click="next" >GO NEXT</a>
  </div>
</template>

<script>
import List from './components/List'

export default {
  components: {
    List
  },
  data () {
    return {
      ...
    }
  },
  methods: {
    next () {
      ...
    }
  }
}
</script>

<style scoped>
  .button {
    display: block;
    width: 100%;
    background: #212121;
    color: #fff;
    font-weight: bold;
    text-align: center;
    padding: 1em;
    cursor: pointer;
    text-decoration: none;
  }
  .button span {
    margin-left: 2em;
    font-size: .5rem;
    color: #d6d6d6;
  }
</style>

在那几个进度中,大家根据Vue的宏图思想有了之类思路:

  1. 在新闻列表中,我们会成功大家上文中涉及的多少个步骤,而这么些手续都只和音讯列表本人有关,与Next按钮间唯一的联络就是Next点击后需求接触新闻列表去获得,而那能够透过props传递。所以大家把列表及其本身业务逻辑、样式都放在List.vue那么些组件中。
  2. 大家为按钮定义了壹部分中央的体裁,然则大家用的css采纳器就是3个.button类名,大概会和其余组件中的.button样式争辩,所以大家投入了一个scoped属性,让App.vue中的style样式只效力于这么些组件内部。
    注意:scoped并不会影响css的效率优先级,使用scoped不表示不会被外表样式表覆盖。
  3. 咱俩想引入一些基础样式,比如reset.css。假若在类型中使用了sass之类的语言,那么能够将相应的外表sass文件放在assets文件夹中,通过import引入。普通的css可以一直写在三个不加scoped属性的零部件中,不过若是你规定这么些样式表不会被反复变更,那么也足以看做第2方静态财富引入index.html中。例如那几个事例中,我在index.html中投入了:

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

效果:

4858美高梅 1

效果图1

二.用到window.reload(),大概router.go(0)刷新时,整个浏览器实行了再次加载,闪烁,体验不佳

二.接纳window.reload(),或许router.go(0)刷新时,整个浏览器进行了双重加载,闪烁,体验不佳

测试

组件的单元测试,用于注明暗中同意排序
app/phone-list/phone-list.component.spec.js:

describe('phoneList', function() {

  // 测试前需加载`phoneList` 模块
  beforeEach(module('phoneList'));

  // 测试控制器
  describe('PhoneListController', function() {
    var ctrl;

    beforeEach(inject(function($componentController) {
      ctrl = $componentController('phoneList');
    }));

    it('should create a `phones` model with 3 phones', function() {
      expect(ctrl.phones.length).toBe(3);
    });

    it('should set a default value for the `orderProp` model', function() {
      expect(ctrl.orderProp).toBe('age');
    });

  });

});

测试成功,则命令行输出:

Chrome 22.0: Executed 2 of 2 SUCCESS (0.021 secs / 0.001 secs)

端到端测试:用于评释下拉菜单改变时的排序
e2e-tests/scenarios.js:

describe('PhoneCat Application', function() {

  describe('phoneList', function() {

    ...

    it('should be possible to control phone order via the drop-down menu', function() {
      var queryField = element(by.model('$ctrl.query'));
      var orderSelect = element(by.model('$ctrl.orderProp'));
      var nameOption = orderSelect.element(by.css('option[value="name"]'));
      var phoneNameColumn = element.all(by.repeater('phone in $ctrl.phones').column('phone.name'));

      function getNames() {
        return phoneNameColumn.map(function(elem) {
          return elem.getText();
        });
      }

      queryField.sendKeys('tablet');   // Let's narrow the dataset to make the assertions shorter
//测试默认状态下的排序
      expect(getNames()).toEqual([
        'Motorola XOOM\u2122 with Wi-Fi',
        'MOTOROLA XOOM\u2122'
      ]);
//选择按“name”排序
      nameOption.click();
//测试排序
      expect(getNames()).toEqual([
        'MOTOROLA XOOM\u2122',
        'Motorola XOOM\u2122 with Wi-Fi'
      ]);
    });

    ...

运作测试,在命令行中输入:

npm run protractor

完成List.vue

现阶段大家根本的事务逻辑都是围绕消息列表展开的,也正是我们创设的List.vue。

第三,咱们须要获得指标数据,笔者选用了cnodejs.org社区的API作为例子举行编辑。如果您也想用一个包装好的ajax库的话,应该如此做:

三.化解方法

叁.缓解措施

尝试

  • phoneList组件控制器中,删除orderProp的暗中认可值,下拉菜单会多2个空白栏(”unknown”)。
  • 在phone-list.template.html模板添加七个{{$ctrl.orderProp}}的绑定来显示当前的排序依照。
  • 反转排序只须求在排序值前面添加三个-号:

<option value="-age">Oldest</option>

引入第壹方JS库

将对象JS库文件放在static文件夹中,例如作者选用的是reqwest.js,然后在index.html先引入。

<script src="./static/reqwest.min.js"></script>

下一场在build配置文件夹中,修改webpack.base.conf.js,export
externals属性:

externals: {
  'reqwest': 'reqwest'
}

4858美高梅,如此那般我们在大家的品种中,就能够随时加载第三方库了。

import reqwest from 'reqwest'

provide / inject 组合

provide / inject组合

七 XH君越和信赖性注入


1个实在的应用程序不会只有3条数据,也不会一向写到前端代码中。所以那壹节,我们会使用AngularJS的放权服务$http从服务器中收获更加多的多寡,并利用重视注入(dependency
injection)为phonelist组件控制器提供劳动。

写个API接口

在那几个例子中,大家只须要调用小说列表那二个接口,不过实际上项目中,可能您须要调用很多接口,而那个接口又会在四个零件中被用到。那么调用接口的逻辑4散在11零部件中肯定是不好的,想象一下对方的url发生了变更,你就得在众七个零部件中多少个个反省是或不是要修改。

据此本身在src文件夹中新建了二个api文件夹,用于存放各样API接口。当前例子中,要获得的是情报列表,所以新建一个news.js文件:

import reqwest from 'reqwest'

const domain = 'https://cnodejs.org/api/v1/topics'

export default {
  getList (data, callback) {
    reqwest({
      url: domain,
      data: data
    })
    .then(val => callback(null, val))
    .catch(e => callback(e))
  }
}

如此大家就具有了贰个赢得情报列表的API:getList。

意义:允许一个祖先组件向其持有子孙后代注入叁个借助,不管组件层次有多少深度,并在起上下游关系创制的小时里始终身效。

效益:允许3个祖辈组件向其负有子孙后代注入1个凭借,不论组件层次有多少深度,并在起上下游关系建立的光阴里始一生效。

数据

app/phones/phones.json用于保存手提式有线电话机数码,保存格式为json,文件中的一组手提式有线电话机数据如下所示:

[
  {
    "age": 13,
    "id": "motorola-defy-with-motoblur",
    "name": "Motorola DEFY\u2122 with MOTOBLUR\u2122",
    "snippet": "Are you ready for everything life throws your way?"
    ...
  },
  ...
]

编写组件

我们用三个<ol>作为音讯列表,内部的每1个<li>就是一条新闻,当中囊括标题、时间和小编二个消息。

在data中,大家用2个名称叫list的数组来囤积新闻列表的数量,一开端当然是空的。我们再在data中安装叁个名称叫limit的值,用来决定每页加载多少条数据,作为参数字传送给getList那一个API。

于是大家的template部分是这么的(参与了某些style美化样式):

<template>
  <ol>
    <li v-for="news of list">
      <p class="title">{{ news.title }}</p>
      <p class="date">{{ news.create_at }}</p>
      <p class="author">By: {{ news.author.loginname }}</p>
    </li>
  </ol>
</template>

<style scoped>
  ol {
    margin-left: 2rem;
    list-style: outside decimal;
  }
  li {
    line-height: 1.5;
    padding: 1rem;
    border-bottom: 1px solid #b6b6b6;
  }
  .title {
    font-weight: bold;
    font-size: 1.3rem;
  }
  .date {
    font-size: .8rem;
    color: #d6d6d6;
  }
</style>

事后大家强烈必要动用getList来获取数据,可是先想想我们会在哪几个地方采纳啊?首先,大家供给在组件开始渲染时自动获取贰回列表,填充基础内容。其次,大家在每一遍点击应用程式.vue中的Next按钮时也急需取得新的列表。

为此我们在methods中定义一个get方法,成功获得到多少后,就把获得的数组拼接到当前list数组后,从而达成了加载越来越多。

顺着那个思路,再想想get方法要求的参数,八个是富含了page和limit四个属性的目的,另三个是回调函数。回调函数我们曾经说过,只须要拼接数组即可,由此只剩余最终八个page参数还没安装。

在开端化的时候,page的值应该为一,私下认可是第贰页内容。之后page的值只由Next按钮改变,所以我们让page通过props获取App.vue中传来的page值。

末尾则是补充get方法触发的条件。1是在组件的生命周期函数created中调用this.get()获取起初内容,另1是在page值变化时对应获得,所以大家watch了page属性,当其变动时,调用this.get()。

最后List.vue的script长这样:

<script>
import news from '../api/news'

export default {
  data () {
    return {
      list: [],
      limit: 10
    }
  },
  props: {
    page: {
      type: Number,
      default: 1
    }
  },
  created () {
    this.get()
  },
  watch: {
    page (val) {
      this.get()
    }
  },
  methods: {
    get () {
      news.getList({
        page: this.page,
        limit: this.limit
      }, (err, list) => {
        if (err) {
          console.log(err)
        } else {
          list.data.forEach((data) => {
            const d = new Date(data.create_at)
            data.create_at = `${d.getFullYear()}-${d.getMonth() + 1}-${d.getDate()}`
          })
          this.list = this.list.concat(list.data)
        }
      })
    }
  }
}
</script>

与此同时大家将App.vue中的<list>修改为:

<list :page="page"></list>

再为page在App.vue中添加二个开首值以及对应的不二秘诀next:

data () {
  return {
    page: 1
  }
},
methods: {
  next () {
    this.page++
  }
}

那样大家就已经达成了加载越多的效用。

4858美高梅 2

效果图2

 

App.vue:

零件控制器

使用$http向web服务器发送HTTP请求,并从文件app/phones/phones.json
中拿走手提式有线电话机数据。$http是Angular的放置服务(built-in
Services)之1,内置服务用于拍卖大规模操作,Angular会在先后须要时自动注入那个服务。
劳动由Angular的正视性注入子系统一管理理。重视注入能让你的web
app实现更好的布局(如独立的呈现结构、数据结构和控制器)和组件松耦合(组件不用自身达成依靠关系,而是经过正视注入子系统来促成),那样app也会更易于测试。
app/phone-list/phone-list.component.js:

angular.
  module('phoneList').
  component('phoneList', {
    templateUrl: 'phone-list/phone-list.template.html',
//向控制器函数注入$http
    controller: function PhoneListController($http) {
      var self = this;
      self.orderProp = 'age';
//$http获取json文件中的数据
      $http.get('phones/phones.json').then(function(response) {
        self.phones = response.data;
      });
    }
  });
  • $http发起GET请求,服务器响应请求,再次回到json文件中的手机数据
  • $http服务重临3个promise对象,该对象有then()函数,我们在then()函数元帅服务器再次来到的数量放入控制器。
    留意:Angular会自动物检疫验和平解决析json数据。
  • 由于回调函数中的this不会指向控制器,须要引用变量self来指向控制器实例。

使用Angular的有个别服务,只须求将该服务名称放入控制器构造函数的参数中,比如:

function PhoneListController($http) {...}

Angular的重视注入会在控制器初叶化时提供服务,并机关处理相应的层次信赖关系(平时二个劳动还凭借于其余服务)。
在意:参数的名字很重点(不可能轻易改动),重视注入会用这几个名字查找服务功效并开始展览注入。

改写为分页

因为此前大家的笔触1二分清楚,代码结构也很掌握,所以改写起来会拾分简单,只要求将List.vue中拼接数组改为赋值数组就能够了:

// 常规loadmore
// this.list = this.list.concat(list.data)
// 分页
this.list = list.data

就像此简单的壹行就完了了作用的变更,那正是Vue.js中挑益州的数量驱动视图的威力。当然,接下去大家还要做点更cooooool的。

App.vue:

证明reload方法,控制router-view的来得或隐蔽,从而控制页面包车型地铁双重加载

$前缀命名规则

Angula的内置服务service、功效域scope和部分别样的API都有三个$前缀。该前缀用于Angular提供的劳务,所以大家自定义服务和数据模型的时候最棒别用$前缀,避防产生命名冲突。其它,$$前缀用于个人属性,不大概访问或改动。

丰富效劳

因为分页替换了本来的数组,所以只是2个Next按钮不够用了,大家还需求1个Previous按钮重回上1页。同样的,也给Previous按钮绑定一个previous方法,除了用this.page–改变page的值以外,还供给对this.page
=== 1的边界条件举行二个断定。

并且为了便利清楚大家脚下的页数,在按钮中,加入{{ page }}展现页数。

<a class="button" @click="next" >GO NEXTCURRENT:{{page}}</a>

证明reload方法,控制router-view的显得或隐蔽,从而决定页面的双重加载

4858美高梅 3

压缩代码时的注意事项

因为依靠注入是由此参数名来促成的,所以压缩代码的时候,要注意参数名不能被核减,不然会招致注重注入出错。
对于该难题,大家需求提供三个取缔压缩的依靠名称列表,具体有七个艺术:

  • 在控制器构造函数中成立一个$inject字符串数组,种种字符串表示叁个亟需注入的劳务名。例如:

function PhoneListController($http) {...}
//$inject字符串数组
PhoneListController.$inject = ['$http'];
...
.component('phoneList', {..., controller: PhoneListController});
  • 在组件注册控制器的代码中利用内联证明数组,例如:

function PhoneListController($http) {...}
...
.component('phoneList', {..., controller: ['$http', PhoneListController]});

那三种办法可任选这么些。要是采取第二种艺术,经常会用内联构造函数来注册控制器:

.component('phoneList', {..., controller: ['$http', function PhoneListController($http) {...}]});

近年来开头,大家会在课程中利用内联表明的艺术展开处理。

app/phone-list/phone-list.component.js(为PhoneListController添加内联诠释):

angular.
  module('phoneList').
  component('phoneList', {
    templateUrl: 'phone-list/phone-list.template.html',
    controller: ['$http',   //内联注解
      function PhoneListController($http) {
        var self = this;
        self.orderProp = 'age';

        $http.get('phones/phones.json').then(function(response) {
          self.phones = response.data;
        });
      }
    ]
  });

transition动画

编写制定和周到作用的长河中,已经足够显示了Vue.js清晰和造福的三头,接下去继续看看其余好用的效应,首先就是transition动画。

为了体现transition的威力,首先本身找到了1个仿照的对象:lavalamp.js(Demo地址)。

在德姆o中得以看来页面以一种十一分优雅的动画片过渡实现了切换内容的进度,其本人是用JQuery+CSS动画完毕的,小编准备用Vue.js举办改写。

第壹学习了刹那间原来的著小编的落到实处思路以往,发现是将三个div作为loader,position设定为fixed。当翻页时,依据点击的按钮分化,loader从顶部照旧尾部扩充高度,达到百分百。数据加载达成后,再折叠中度,最终隐藏。

那正是说初始的思路如下:

  1. 丰硕三个loader,最小高度与按钮一致,背景同为浅紫蓝,让过渡显得更自然。
  2. loader中度需求落成3个荧屏的万丈,所以设置html和body的height为百分百。
  3. 内需有2个值,作为loader是还是不是出示的依据,小编定为finish,其暗许值值为true,通过给loader添加v-show=”!finish”来支配其出示。
  4. 在next和previous方法中添加this.finish = false触发loader的显示。
  5. 在App.vue和List.vue建立三个双向的props属性绑定至finish,当List.vue中的get方法执行完结后,通过props将App.vue中的finish设定为true,隐藏loader。
  6. 给loader添加2个transition。由于动画分为顶部开始展览和底部展开三种,所以利用动态的transition为其钦点正确的transition名称。
  7. 新增三个值up,用于判断动画从哪些方向开始,其私下认可值为false。在previous方法中,执行this.up
    = true,反之在next方法中,则履行this.up = false。

依据思路,写出的loader应该是那样的(style等体制设定在最后统一体现):

<div id="loader" v-show="!finish" :transition="up? 'up-start':'down-start'">
  Loading
</div>

能够看看自家设定了up-start和down-start三种transition格局,对应的css动画代码如下:

.down-start-transition {
    bottom: 0;
    height: 100%;
  }
  .down-start-enter {
    animation: expand .5s 1 cubic-bezier(0, 1, 0, 1) both;
  }
  .down-start-leave {
    animation: collapse .5s 1 cubic-bezier(0, 1, 0, 1) both;
    top: 0;
    bottom: auto;
  }
  .up-start-transition {
    top: 0;
    height: 100%;
  }
  .up-start-enter {
    animation: expand .5s 1 cubic-bezier(0, 1, 0, 1) both;
  }
  .up-start-leave {
    animation: collapse .5s 1 cubic-bezier(0, 1, 0, 1) both;
    top: auto;
    bottom: 0;
  }
  @keyframes expand {
    0% {
      height: 3em;
      transform: translate3d(0, 0, 0);
    }
    100% {
      height: 100%;
      transform: translate3d(0, 0, 0);
    }
  }
  @keyframes collapse {
    0% {
      height: 100%;
      transform: translate3d(0, 0, 0);
    }
    100% {
      height: 3em;
      transform: translate3d(0, 0, 0);
    }
  }

安装了expand和collapse多个animation,再在transition的次第生命周期钩子中做相应的绑定,就高达了和lavalamp.js相接近的功效。

为了确定保障动画能执行总体,在List.vue的get方法执行完现在,还运用了二个set提姆eout定时器让finish延时0.5秒变为true。

4858美高梅 4

tableList.vue:

测试

运用正视注入使得控制器有了借助关系,所以打造控制器的单元测试变复杂了。可以动用new运算符在构造函数中提供$http的模拟实现,可是未来毫不那么艰难。
Angular提供了用于单元测试的一成不变$http服务,大家得以一贯调用服务中的$httpBackend方法完毕服务器的模仿响应。

app/phone-list/phone-list.component.spec.js:

describe('phoneList', function() {

  beforeEach(module('phoneList'));

  describe('controller', function() {
    var $httpBackend, ctrl;

    // 这里的依赖注入会忽略头部和尾部的下划线(如 _$httpBackend_).
    // 这样变量就可以用和服务同样的名字,而不会有命名冲突
    beforeEach(inject(function($componentController, _$httpBackend_) {
      $httpBackend = _$httpBackend_;
      //模拟发送http请求
      $httpBackend.expectGET('phones/phones.json')
                  //模拟响应
                  .respond([{name: 'Nexus S'}, {name: 'Motorola DROID'}]);

      ctrl = $componentController('phoneList');
    }));

    ...

  });

});

注意:因为须求加载Jasmine和angular-mocks.js到测试环境,所以我们有八个帮忙方法module和inject用于访问和配备注入器。

  • 动用inject()向Jasmin的beforeEach()函数注入$componentController和
    $httpBackend服务的实例,用于创建每个测试。那样有限支撑各个测试有多只的起源,又各自独立。
  • 调用$componentController(),并传播参数’phoneList’(组件的名字)。

代码应用$http获取手提式有线电话机列表到控制器中,所以在开创控制器(PhoneListController)前,我们要报告测试程序预期的输入请求:

  • 向beforEach()函数注入$httpBackend的伏乞服务,它会模仿生产环境中的XH本田UR-V和JSONP请求。那样大家在编写测试时,就不用处理原生API和与它们相关的大局状态(服务器响应结果)。那样也幸免了异步请求(XHOdyssey和JSONP是异步请求),能够加快单元测试。
  • $httpBackend.expectGET()方法能够效仿预期的HTTP请求和响应。注意:在调用$httpBackend.flush()之后,才会回到响应。

接着,大家来验证在接到响应以前,控制器中是或不是有phones属性:

it('should create a `phones` property with 2 phones fetched with `$http`', function() {
//收到响应前,phones未定义
  expect(ctrl.phones).toBeUndefined();
//收到响应后,phones变成一个对象数组
  $httpBackend.flush();
  expect(ctrl.phones).toEqual([{name: 'Nexus S'}, {name: 'Motorola DROID'}]);
});
  • $httpBackend.flush()激活浏览器请求类别,那会让$http服务重返预期的响应。

最后,们表达默认的orderProp值是还是不是设置科学:

it('should set a default value for the `orderProp` property', function() {
  expect(ctrl.orderProp).toBe('age');
});

命令行应该出口:

Chrome 49.0: Executed 2 of 2 SUCCESS (0.133 secs / 0.097 secs)

优化体验

动画片效果实现现在,实际使用时意识lavalamp.js还有个美丽纷呈地规划,正是点击Previous后,页眼下往底部,反之点击Next后则前往顶部。

兑现后者并不复杂,在next方法中进入以下一行代码调整岗位即可:

document.body.scrollTop = 0

previous前往底部则略微复杂一点,因为获取到多少以往,页面中度会生出改变,假诺在previous中举行scrollTop的变更,有十分的大可能率会现身新的始末填充后中度变长,页面不到底的场地。

故而自个儿watch了finish的值,仅当点击按钮为previous且finish变化为false至true时前往尾巴部分,代码如下:

watch: {
  finish (val, oldVal) {
    if (!oldVal && val && this.up) {
      document.body.scrollTop = document.body.scrollHeight
    }
  }
}

 

在页面注入App.vue组件提供(provide)的 reload
注重,在逻辑完毕之后(删除或添加…),直接this.reload()调用,即可刷新当前页面。

尝试

  • 在phone-list.template.html底部,插手代码:

<pre>{{$ctrl.phones | filter:$ctrl.query | orderBy:$ctrl.orderProp | json}}</pre>

能够看出json格式的无绳电话机列表。

  • 在控制器PhoneListController的$http回调函数中输入:

self.phones = response.data.slice(0, 5);

能够预处理HTTP响应,将赶回的手提式有线电话机序号限制为0-伍。

下一篇:AngularJS Phonecat
(步骤8-步骤9)

4858美高梅 5

前端路由

做到上述内容之后,发现无论是翻到第几页,一旦刷新,就会回来第叁页。vue-router正是为焚林而猎那类难题而生的。

率先大家引入VueRouter,格局得以参见上文中的“引入第二方JS库”。然后在main.js对路由规则举行一些安插。

我们的笔触包涵:

  1. 咱俩供给在url上浮现出当下所处的页数。
  2. url中的页数应该与全数组件中的page值保持1致。
  3. 点击Next和Previous按钮要跳转到对应的url去。
  4. 在那一个事例中大家向来不router-view。

故而main.js的安排如下:

import Vue from 'vue'
import App from './App'
import VueRouter from 'VueRouter'

Vue.use(VueRouter)

const router = new VueRouter()
router.map({
  '/page/:pageNum': {
    name: 'page',
    component: {}
  }
})

router.redirect({
  '/': '/page/1'
})

router.beforeEach((transition) => {
  if (transition.to.path !== '/page/0') {
    transition.next()
  } else {
    transition.abort()
  }
})

router.start(App, 'app')

第1定义了二个名叫page的签署路径。之后将装有指标路径为’/’,也正是开首页的请求,重定向到’/page/1’上保险1致性。最后再在每一遍路由实施从前做二个论断,假如到了’/page/0’那样的私行路径上,就不举办transition.next()。

根据以前的思绪,在App.vue中,获取路由对象的参数值,赋值给page。同时给几个按钮添加对应的v-link。

最终的demo地址
Github仓库

tableList.vue:

4858美高梅 6

在页面注入App.vue组件提供(provide)的 reload
正视,在逻辑完结未来(删除或添加…),直接this.reload()调用,即可刷新当前页面。

4858美高梅 7

4858美高梅 8

4.provide / inject 用法

4858美高梅 9

provide:选项应该是一个指标或回到一个对象的函数。该对象涵盖可注入其后裔的性质。

 

inject:1个字符串数组,或一个对象,对象的 key 是地点的绑定名

4.provide / inject 用法

提示:provideinject绑定并不是可响应的。那是刻意为之的。假诺您传入了五个可监听的目的,那么其目的的质量照旧可响应的。

provide:选项应该是三个目的或再次回到3个对象的函数。该对象涵盖可注入其后代的品质。

如上正是本文的全体内容,希望对我们的就学抱有帮忙,也愿意大家多多协助脚本之家。

inject:3个字符串数组,或2个目的,对象的 key 是地点的绑定名

你也许感兴趣的篇章:

  • 消除vue单页使用keep-alive页面重返不刷新的题材
  • 缓解vue
    路由变化页面数据不刷新的题材
  • vue通过路由完结页面刷新的不2法门
  • 消除Vue使用mint-ui
    loadmore完结上拉加载与下拉刷新出现1个页面使用多个上拉加载后争持难点
  • vue.js达成刷新当前页面的秘籍教程
  • 至于页面刷新vuex数据流失难题化解方案
  • 焚林而猎vue this.$forceUpdate()
    处理页面刷新难点(v-for循环值刷新等)

提示:provide 和 inject 绑定并不是可响应的。那是刻意为之的。假诺您传入了2个可监听的目的,那么其目的的习性依旧可响应的。

 

==========================================

深远掌握数据驱动

如上算是开发进度中的二个坑,用了一段时间,明天再读代码的时候,感觉被坑的很严重。

  1. 收获列表方法

4858美高梅 10

二.重新获取数据

4858美高梅 11

三.这么重复调用获取数据,即可一并达成页面数据更新(不会再一次刷新页面),同时有限辅助有分页时,能够停留在当前页(刷新前假设是第三页,刷新后照旧在第一页),

即其余查询条件保险不变,体验效果好

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图
Copyright @ 2010-2019 美高梅手机版4858 版权所有