vue watchers_具有Vue Watchers的简单异步无限滚动

vue watchers

Infinite Scroll is a UX pattern that suggests showing users few contents on page or app load. More contents are then loaded once the user starts scrolling down the page. These contents are loaded asynchrounously by making request to the server responsible for providing the content. In this post I’m going to talk about asynchronous operations in JavaScript, as well as how Vue ‒ an awesome JavaScript framework, can be used in this context. In the process, we will see a simple page that uses infinite scroll.

无限滚动是一种UX模式,建议向用户显示页面或应用程序加载时很少的内容。 一旦用户开始向下滚动页面,便会加载更多内容。 通过向负责提供内容的服务器发出请求,可以随意加载这些内容。 在本文中,我将讨论JavaScript中的异步操作,以及如何在这种情况下使用Vue ‒一个很棒JavaScript框架。 在此过程中,我们将看到一个使用无限滚动的简单页面。

了解异步操作 ( Understanding Asynchronous Operations )

In programs written synchronously, here’s the deal ‒ you’ve got two lines of codes, L1 and L2. L2 cannot execute until L1 has finished running. check out the most basic example of a synchronous written program below:

在同步编写的程序中,这是交易‒您有两行代码L1和L2。 在L1完成运行之前,L2无法执行。 在下面查看同步编写程序的最基本示例:

console.log("quavo");
  console.log("takeoff");
  console.log("offset");

  //Console logs
  > quavo
  > takeoff
  > offset

The problem with writing code this way is that it makes your app's UX rigid and awkward. Let's say you visit a shopping website, say Amazon, if you're not running an ad blocker chances are you'll be flooded with ads. If Amazon was running on synchronously written code, your page would freeze up repeatedly while all of the images loaded for the pages and ads and you wouldn't be able to click on anything until after the page has finished loading. If the page loaded a lot in the background it could take a while before you could interact with the page which would be very inconvenient.

用这种方式编写代码的问题是,它会使您的应用的用户体验变得僵硬而笨拙。 假设您访问购物网站,例如Amazon ,如果您没有运行广告拦截器,那么您很可能会被广告充斥。 如果Amazon使用同步编写的代码运行,则在页面和广告加载的所有图像加载期间,您的页面将反复冻结,并且只有在页面完成加载后,您才能单击任何内容。 如果该页面在后台加载了很多内容,则可能需要一段时间才能与该页面进行交互,这非常不便。

Enter asynchronous programs, they offer us a much better deal I think. You’ve got two lines of code, L1 and L2, where L1 schedules some task to be run in the future but L2 runs before that task completes. Check out this basic demo of writing asynchronous code:

输入异步程序,它们为我们提供了更好的协议。 您有两行代码,L1和L2,其中L1安排了一些将来要运行的任务,而L2在该任务完成之前运行。 查看这个编写异步代码的基本演示:

console.log "quavo"
  $http.get("our_url", (data) => console.log "takeoff")
  console.log "offset"

  // Console logs
  > quavo
  > offset
  > takeoff

Normally we would see the code above executed in the order in which it was written but because the $http.get request above will take some time to get data from our_url, JavaScript won’t wait for that, instead it goes ahead and executes the next line of code while waiting for $http.get to finish what it is doing thus the arrangement of logging in the console. Other ways of writing code asynchronously include:

通常,我们会看到上面的代码按其编写顺序执行,但是由于上面的$http.get请求将需要一些时间才能从our_url获取dataour_url JavaScript不会等待,而是继续执行该代码。等待$http.get完成其工作的下一行代码,从而安排在控制台中进行登录的方式。 其他异步编写代码的方法包括:

  • setTimeout functions which schedule something to happen in the future and then go ahead to execute the next block of code:

    setTimeout函数可安排将来发生的事情,然后继续执行下一个代码块:
console.log("Can I take your order?");
  setTimeout(function() {
    console.log("Yes please!");
  }, 2000);
  console.log("Sure, one second please");

  // Console logs
  > Can I take your order?
  > Sure, one second please
  > Yes please!
  • Higher order functions (also known as callback functions) which are functions that are passed to other functions as parameters. Let’s assume a callback function named function X, it is then passed to another function called function Y as a parameter. Eventually function X is executed or called inside function Y. Check out the code block below:

    高阶函数(也称为回调函数)是作为参数传递给其他函数的函数。 假设一个名为function X的回调函数,然后将其作为参数传递给另一个称为function Y的函数。 最终, 函数X函数Y中执行或调用。 查看下面的代码块:
function Y(X) {
    $.get("our_url", X);
  }

Callback functions exist in different modes, chances are you’ve used them without knowing. Examples include window.onclick, setTimeout and setInterval.

回调函数以不同的模式存在,很可能您在不知不觉中使用了它们。 示例包括window.onclicksetTimeoutsetInterval

什么是观察者? ( What are Watchers? )

Vue watchers allow us to perform asynchronous operations in response to changing data. They’re like a more general way to react to data changes in your Vue instance. In our Vue Instance, watchers are denoted with the watch keyword and are used thus:

Vue观察者使我们能够响应更改的数据执行异步操作。 它们就像是对Vue实例中的数据更改做出React的更通用的方式。 在我们的Vue实例中,观察者用watch关键字表示,因此可以这样使用:

new Vue({
    el: '#app',
    data: {
      // data we intend to bind to our view
    },
    watch: {
      // asynchronous operations that we'll be working with in our app
    }
  });

使用观察者扩展异步操作 ( Extending Asynchronous Operations with Watchers )

Let’s see how Vue uses watchers to monitor asynchronous operations. Using Vue, we’ll build an app with an infinite scroll feature, once a user gets to the bottom of the page, a GET request is performed and more data is retrieved. Let me just chip in here that this article works through Sarah Drasner's original pen. I'm a big fan. Let’s get to work:

让我们看看Vue如何使用观察程序来监视异步操作。 使用Vue,我们将构建具有无限滚动功能的应用程序,一旦用户到达页面底部,便会执行GET请求并检索更多数据。 让我在这里说一下,这篇文章是通过Sarah Drasner的原始笔来完成的。 我是大粉丝。 让我们开始工作:

Amazon

亚马孙

  • Import the necessary tools via the DOM, using script tags. Here we’ll import Vue and Axios, a promise based HTTP client for the browser

    使用脚本标签通过DOM导入必要的工具。 在这里,我们将导入Vue和Axios ,这是浏览器的基于Promise的HTTP客户端
<head>
    <script src="https://unpkg.com/vue"></script>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
  </head>
  • Create a new Vue Instance:

    创建一个新的Vue实例:
new Vue({
    //  The el property points to the DOM using a query selector
    el: '#app',
  });
  • Create the data function and append any data that should be bound to the DOM. Initially, we won’t be at the bottom of the page thus the bottom boolean property is set to false. Whatever results our API fetches will be stored in the beers property, which is an empty array.

    创建data功能,并附加应绑定到DOM的所有数据。 最初,我们不会在页面底部,因此, bottom boolean属性设置为false。 无论我们提取的API结果如何,都将存储在beers属性中,该属性为空数组。
data() {
    return {
      bottom: false,
      beers: []
    }
  }
  • Define our methods using the methods member. Methods allow us create functions and bind events to these functions as well as handle these events. In the bottomVisible() function, we use three read-only properties to manually create our infinite scroll feature:

    使用methods成员定义我们的methods 。 方法使我们可以创建函数并将事件绑定到这些函数以及处理这些事件。 在bottomVisible()函数中,我们使用三个只读属性来手动创建无限滚动功能:
  1. scrollY: Returns the Y coordinate of the top edge of the current viewport. If there is no viewport, the returned value is zero.

    scrollY :返回当前视口顶部边缘的Y坐标。 如果没有视口,则返回值为零。
  2. clientHeight: The inner height of an element in pixels, including padding but not the horizontal scrollbar height, border, or margin.

    clientHeight :元素的内部高度(以像素为单位),包括填充,但不包括水平滚动条的高度,边框或边距。
  3. scrollHeight: The height of an element's content, including content not visible on the screen due to overflow.

    scrollHeight :元素内容的高度,包括由于溢出而在屏幕上不可见的内容。

In the addBeer() function, we perform a GET request using Axios. Using promises and callbacks, we create an object apiInfo and pass in the values retrieved from our API call. Every function in our Vue Instance can access data properties using this.

addBeer()函数中,我们使用Axios执行GET请求。 使用承诺和回调,我们创建一个对象apiInfo并传递从我们的API调用中检索的值。 Vue实例中的每个函数都可以使用this访问数据属性。

methods: {
    bottomVisible() {
      const scrollY = window.scrollY
      const visible = document.documentElement.clientHeight
      const pageHeight = document.documentElement.scrollHeight
      const bottomOfPage = visible + scrollY >= pageHeight
      return bottomOfPage || pageHeight < visible
    },
    addBeer() {
      axios.get('https://api.punkapi.com/v2/beers/random')
        .then(response => {
          let api = response.data[0];
          let apiInfo = {
            name: api.name,
            desc: api.description,
            img: api.image_url,
            tips: api.brewers_tips,
            tagline: api.tagline,
            food: api.food_pairing
          };
          this.beers.push(apiInfo)
          if (this.bottomVisible()) {
            this.addBeer()
          }
        })
    }
  }
  • The watch option watches for changes to the state of the app and updates the DOM accordingly:

    watch选项watch应用程序状态的更改并相应地更新DOM:
watch: {
    bottom(bottom) {
      if (bottom) {
        this.addBeer()
      }
    }
  }
  • We use the created lifecycle hook to add a scroll event that fires each time the bottomVisible() function is called. To implement our infinite scroll feature, we equate the bottom boolean property in the data function to the bottomVisible() function. created hooks allow us access reactive data as well as functions in our Vue instance.

    我们使用created生命周期挂钩添加一个滚动事件,该事件在每次调用bottomVisible()函数时触发。 为了实现无限滚动功能,我们将data函数中的bottom布尔属性等同于bottomVisible()函数。 created钩子使我们可以访问响应数据以及Vue实例中的函数。
created() {
    window.addEventListener('scroll', () => {
      this.bottom = this.bottomVisible()
    })
    this.addBeer()
  }

Move over to the DOM, where the following Vue directives will be used to provide two way binding between the DOM and the Vue instance:

移至DOM,以下Vue指令将用于在DOM和Vue实例之间提供两种方式的绑定:

  1. v-if: For conditionally rendering statements on the DOM

    v-if :用于在DOM上有条件地呈现语句

  2. v-for: For rendering a list of items based on an array, requires a special syntax in the form of beer in beers, where beers is the source data array and beer is an alias for the array element being iterated on.

    v-for :要基于数组呈现项目列表,需要使用beer in beersbeer in beers形式的特殊语法,其中beers是源数据数组,而beer是要迭代的数组元素的别名

  3. v-if: For conditionally rendering statements on the DOM

    v-if :用于在DOM上有条件地呈现语句

  4. v-for: For rendering a list of items based on an array, requires a special syntax in the form of beer in beers, where beers is the source data array and beer is an alias for the array element being iterated on.

    v-for :要基于数组呈现项目列表,需要使用beer in beersbeer in beers形式的特殊语法,其中beers是源数据数组,而beer是要迭代的数组元素的别名

<div id="app">
    <section>
      <h1>Make yourself some Punk Beers </h1>
      <div v-if="beers.length === 0" class="loading">Loading...</div>
      <div v-for="beer in beers" class="beer-contain">
        <div class="beer-img"> <img :src="beer.img" height="350" /> </div>
        <div class="beer-info">
          <h2>{{ beer.name }}</h2>
          <p class="bright">{{ beer.tagline }}</p>
          <p><span class="bright">Description:</span> {{ beer.desc }}</p>
          <p><span class="bright">Tips:</span> {{ beer.tips }}</p>
          <h3 class="bright">Food Pairings</h3>
          <ul>
            <li v-for="item in beer.food"> {{ item }} </li>
          </ul>
        </div>
      </div>
    </section>
  </div>

https://codepen.io/codebeast/pen/ooZYvN Original Pen by Sarah Drasner

Sarah Drasner的 https://codepen.io/codebeast/pen/ooZYvN 原装笔

摘要 (Summary)

One might ask “Why don’t we just use computed properties for this?”, the reason is that computed properties are synchronous and must return a value. When carrying out asynchronous operations such as timeout functions, or like our demo above, GET requests, it’s best to use watchers because Vue listens for the return value of the function. It’s also cool to use event listeners but these have the disadvantage of manually handling the event and calling a method instead of just listening to data changes. In any case, you now know how to handle asynchronous operations when you see or want to use them in Vue.

有人可能会问“为什么不为此使用计算属性?”,原因是计算属性是同步的,必须返回一个值。 当执行诸如超时功能之类的异步操作时,或者像上面的演示一样,执行GET请求时,最好使用观察程序,因为Vue会监听该函数的返回值。 使用事件侦听器也很酷,但是它们具有手动处理事件并调用方法而不是仅侦听数据更改的缺点。 无论如何,您现在都知道在Vue中看到或想要使用异步操作时如何处理它们。

翻译自: https://scotch.io/tutorials/simple-asynchronous-infinite-scroll-with-vue-watchers

vue watchers

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值