美文网首页Vue插件
在Vue应用中添加虚拟滚动

在Vue应用中添加虚拟滚动

作者: 开心人开发世界 | 来源:发表于2019-11-28 18:13 被阅读0次

    要在您的应用程序中显示大量数据,一次加载所有内容不是一个好的解决方案。加载大列表会加重用户计算机资源的负担。因此,我们需要一个更好的解决方案。最有效的解决方案是一次加载少量数据。仅加载屏幕上显示的所有内容。此解决方案称为虚拟滚动。

    使用Vue.js,我们可以使用位于https://www.npmjs.com/package/vue-virtual-scroll-list的vue-virtual-scroll-list程序包将虚拟滚动添加到我们的Vue.js应用程序中。这是为此目的使用的最简单的软件包之一。

    在本文中,我们将制作一个应用程序,使我们可以生成大量假数据并将其显示在虚拟滚动列表中。它将询问用户要创建多少个条目,然后在用户提交编号时创建它。

    首先,我们使用Vue CLI创建Vue.js项目。我们运行npx @vue/cli create data-generator来创建应用程序。在向导中,我们选择“手动选择功能”,然后选择包括Babel和Vue-Router。

    接下来,我们需要安装一些软件包。我们需要使用BootstrapVue进行样式设置,使用Faker创建虚假数据,使用Vee-Validate进行用户输入验证以及使用Vue-Virtual-Scroll-List来显示虚拟滚动列表中的项目列表。我们通过运行以下命令安装所有组件:

    npm i bootstrap-vue faker vee-validate vue-virtual-scrolling-list
    

    安装软件包后,我们将添加页面。首先,我们Address.vueviews文件夹中创建并添加:

    <template>
      <div class="page">
        <h1 class="text-center">Generate Addresses</h1>
        <ValidationObserver ref="observer" v-slot="{ invalid }">
          <b-form [@submit](http://twitter.com/submit).prevent="onSubmit" novalidate>
            <b-form-group label="Number" label-for="number">
              <ValidationProvider
                name="number"
                rules="required|min_value:1|max_value:100000"
                v-slot="{ errors }"
              >
                <b-form-input
                  :state="errors.length == 0"
                  v-model="form.number"
                  type="text"
                  required
                  placeholder="Number"
                  name="number"
                ></b-form-input>
                <b-form-invalid-feedback :state="errors.length == 0">{{errors.join('. ')}}</b-form-invalid-feedback>
              </ValidationProvider>
            </b-form-group>
            <b-button type="submit" variant="primary">Generate</b-button>
          </b-form>
        </ValidationObserver><br /><h2>Addresses</h2><virtual-list :size="itemHeight" :remain="3">
          <div v-for="(item, index) of list" :key="index" class="result-row">
            <div class="index">{{index + 1}}</div>
            <div class="column">{{item.streetAddress}}</div>
            <div class="column">{{item.streetName}}</div>
            <div class="column">{{item.city}}</div>
            <div class="column">{{item.county}}</div>
            <div class="column">{{item.state}}</div>
            <div class="column">{{item.country}}</div>
            <div class="column">{{item.zipCode}}</div>
          </div>
        </virtual-list>
      </div>
    </template><script>
    const faker = require("faker");
    import virtualList from "vue-virtual-scroll-list";export default {
      name: "home",
      data() {
        return {
          form: {},
          list: [],
          itemHeight: 80
        };
      },
      components: { "virtual-list": virtualList },
      methods: {
        async onSubmit() {
          const isValid = await this.$refs.observer.validate();
          if (!isValid) {
            return;
          }
          this.list = Array.from({ length: this.form.number }).map((l, i) => {
            return {
              city: faker.address.city(),
              streetName: faker.address.streetName(),
              streetAddress: faker.address.streetAddress(),
              county: faker.address.county(),
              state: faker.address.state(),
              country: faker.address.country(),
              zipCode: faker.address.zipCode()
            };
          });
        }
      }
    };
    </script><style scoped>
    .column {
      padding-right: 20px;
      width: calc(80vw / 7);
      overflow: hidden;
      text-overflow: ellipsis;
    }.result-row {
      height: 80px;
    }
    </style>
    
    

    在此页面中,我们让用户输入1到100000之间的数字来生成虚假地址,然后在用户输入该数字后,onSubmit就会调用该地址来生成商品。Faker库用于生成项目。表单验证是通过将表单包装在ValidationObserver组件中并将输入包装在ValidationProvider组件中来完成的。我们提供的验证规则rules的道具ValidationProvider。规则将在main.js以后添加。

    b-form-invalid-feedback组件中显示错误消息显示。获取错误ValidationProvider作用。这是我们从中获取errors对象的地方。

    用户提交号码后,将onSubmit调用该函数。这是ValidationObserver有用的地方,因为它为我们提供了this.$refs.observer.validate()检查表单有效性的功能。

    如果isValid解析为true,则我们使用该Array.from方法生成列表,方法是映射生成用户输入的长度为(this.form.number)的数组,然后将每个条目映射到假地址行。

    我们virtual-list在本script节中从Vue-Virtual-Scroll-List 添加组件,以便可以在模板中使用它。这些项目在virtual-list组件中,因此我们一次只显示一些。该remain道具是我们指定一次在屏幕上显示的项目数的地方。该size道具用于设置每行的高度。

    接下来的Home.vue,我们将现有代码替换为:

    <template>
      <div class="page">
        <h1 class="text-center">Generate Emails</h1>
        <ValidationObserver ref="observer" v-slot="{ invalid }">
          <b-form [@submit](http://twitter.com/submit).prevent="onSubmit" novalidate>
            <b-form-group label="Number" label-for="number">
              <ValidationProvider
                name="number"
                rules="required|min_value:1|max_value:100000"
                v-slot="{ errors }"
              >
                <b-form-input
                  :state="errors.length == 0"
                  v-model="form.number"
                  type="text"
                  required
                  placeholder="Number"
                  name="number"
                ></b-form-input>
                <b-form-invalid-feedback :state="errors.length == 0">{{errors.join('. ')}}</b-form-invalid-feedback>
              </ValidationProvider>
            </b-form-group>
            <b-button type="submit" variant="primary">Generate</b-button>
          </b-form>
        </ValidationObserver> <br /> <h2>Emails</h2> <virtual-list :size="itemHeight" :remain="30">
          <div v-for="(item, index) of list" :key="index" class="result-row">
            <div class="index">{{index + 1}}</div>
            <div>{{item}}</div>
          </div>
        </virtual-list>
      </div>
    </template><script>
    const faker = require("faker");
    import virtualList from "vue-virtual-scroll-list";export default {
      name: "home",
      data() {
        return {
          form: {},
          list: [],
          itemHeight: 30
        };
      },
      components: { "virtual-list": virtualList },
      methods: {
        async onSubmit() {
          const isValid = await this.$refs.observer.validate();
          if (!isValid) {
            return;
          }
          this.list = Array.from({ length: this.form.number }).map((l, i) => {
            return faker.internet.email();
          });
        }
      }
    };
    </script>
    
    

    它的工作方式与极为相似Address.vue,除了我们生成的是电子邮件而不是地址。

    接下来Name.vue,在views文件夹中创建一个文件并添加:

    <template>
      <div class="page">
        <h1 class="text-center">Generate Names</h1>
        <ValidationObserver ref="observer" v-slot="{ invalid }">
          <b-form [@submit](http://twitter.com/submit).prevent="onSubmit" novalidate>
            <b-form-group label="Number" label-for="number">
              <ValidationProvider
                name="number"
                rules="required|min_value:1|max_value:100000"
                v-slot="{ errors }"
              >
                <b-form-input
                  :state="errors.length == 0"
                  v-model="form.number"
                  type="text"
                  required
                  placeholder="Number"
                  name="number"
                ></b-form-input>
                <b-form-invalid-feedback :state="errors.length == 0">{{errors.join('. ')}}</b-form-invalid-feedback>
              </ValidationProvider>
            </b-form-group>
            <b-button type="submit" variant="primary">Generate</b-button>
          </b-form>
        </ValidationObserver> <br /> <h2>Names</h2> <virtual-list :size="itemHeight" :remain="30">
          <div v-for="(item, index) of list" :key="index" class="result-row">
            <div class="index">{{index + 1}}</div>
            <div>{{item.firstName}} {{item.lastName}}</div>
          </div>
        </virtual-list>
      </div>
    </template><script>
    const faker = require("faker");
    import virtualList from "vue-virtual-scroll-list";export default {
      name: "home",
      data() {
        return {
          form: {},
          list: [],
          itemHeight: 30
        };
      },
      components: { "virtual-list": virtualList },
      methods: {
        async onSubmit() {
          const isValid = await this.$refs.observer.validate();
          if (!isValid) {
            return;
          }
          this.list = Array.from({ length: this.form.number }).map((l, i) => {
            return {
              firstName: faker.name.firstName(),
              lastName: faker.name.lastName()
            };
          });
        }
      }
    };
    </script>
    
    

    在用户输入所需的项目数后,我们会在此文件中生成伪造的名字和姓氏。

    然后在中App.vue,将现有代码替换为:

    <template>
      <div id="app">
        <b-navbar toggleable="lg" type="dark" variant="info">
          <b-navbar-brand to="/">Data Generator</b-navbar-brand>
    <b-navbar-toggle target="nav-collapse"></b-navbar-toggle>
    <b-collapse id="nav-collapse" is-nav>
            <b-navbar-nav>
              <b-nav-item to="/" :active="path  == '/'">Home</b-nav-item>
              <b-nav-item to="/name" :active="path  == '/name'">Name</b-nav-item>
              <b-nav-item to="/address" :active="path  == '/address'">Address</b-nav-item>
            </b-navbar-nav>
          </b-collapse>
        </b-navbar>
        <router-view />
      </div>
    </template>
    <script>
    export default {
      data() {
        return {
          path: this.$route && this.$route.path
        };
      },
      watch: {
        $route(route) {
          this.path = route.path;
        }
      }
    };
    </script>
    <style lang="scss">
    .page {
      padding: 20px;
    }
    .result-row {
      display: flex;
      height: calc(50vh / 10);
    }
    .index {
      padding-right: 20px;
      min-width: 100px;
    }
    </style>
    

    添加带有页面链接的BootstrapVue导航栏。在顶部栏中,我们active为链接设置属性,以便突出显示当前页面的链接。在本scripts节中,我们将观察$routeVue Router提供的对象以获取应用程序的当前路径,并将其分配给该对象,this.path以便我们可以使用它来设置active道具。

    接下来的main.js,我们将现有代码替换为:

    import Vue from "vue";
    import App from "./App.vue";
    import router from "./router";
    import store from "./store";
    import BootstrapVue from "bootstrap-vue";
    import "bootstrap/dist/css/bootstrap.css";
    import "bootstrap-vue/dist/bootstrap-vue.css";
    import { ValidationProvider, extend, ValidationObserver } from "vee-validate";
    import { required } from "vee-validate/dist/rules";
    import { min_value } from "vee-validate/dist/rules";
    import { max_value } from "vee-validate/dist/rules";
    extend("required", required);
    extend("min_value", min_value);
    extend("max_value", max_value);
    Vue.component("ValidationProvider", ValidationProvider);
    Vue.component("ValidationObserver", ValidationObserver);
    Vue.use(BootstrapVue);
    Vue.config.productionTip = false;
    new Vue({
      router,
      store,
      render: h => h(App)
    }).$mount("#app");
    

    我们在此处添加了先前文件中使用的验证规则,并包括了我们在应用程序中使用的所有库。我们进行了注册,ValidationProvider并进行ValidationObserver了调用,Vue.component以便可以在组件中使用它们。Vee-Validate提供的验证规则包含在应用程序中,以便模板可以通过extend从Vee-Validate 进行调用来使用它们。我们呼吁Vue.use(BootstrapVue)在我们的应用程序中使用BootstrapVue。

    router.js我们将现有代码替换为:

    import Vue from "vue";
    import Router from "vue-router";
    import Home from "./views/Home.vue";
    import Name from "./views/Name.vue";
    import Address from "./views/Address.vue";
    Vue.use(Router);
    export default new Router({
      mode: "history",
      base: process.env.BASE_URL,
      routes: [
        {
          path: "/",
          name: "home",
          component: Home
        },
        {
          path: "/name",
          name: "name",
          component: Name
        },
        {
          path: "/address",
          name: "address",
          component: Address
        }
      ]
    });
    

    包含我们在路线中创建的页面,以便用户可以通过顶部栏中的链接或直接输入URL来访问它们。

    接下来的index.html,我们将现有代码替换为:

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="utf-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width,initial-scale=1.0" />
        <link rel="icon" href="<%= BASE_URL %>favicon.ico" />
        <title>Data Generator</title>
      </head>
      <body>
        <noscript>
          <strong
            >We're sorry but vue-virtual-scroll-tutorial-app doesn't work properly
            without JavaScript enabled. Please enable it to continue.</strong
          >
        </noscript>
        <div id="app"></div>
        <!-- built files will be auto injected -->
      </body>
    </html>
    

    更改应用程序的标题。

    最后,我们运行npm run serve以获取以下屏幕:

    翻译自:https://medium.com/javascript-in-plain-english/how-to-add-virtual-scrolling-to-a-vue-app-19c21d55b3bc

    相关文章

      网友评论

        本文标题:在Vue应用中添加虚拟滚动

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