Nuxt.js 分页获取数据(及更新子组件数据、不刷新页面,异步请求追加数据)

2,557 阅读1分钟


下面是老办法,可以不用看了,没什么价值,仅作为参考!!


一、简介

  • 服务器渲染 模式中,分页获取数据常见的方式是:

    • 服务器数据全返前端自行处理

    • 异步请求数据,本地追加标签元素

    • 链接带分页参数进行获取

二、URL 带 分页参数 进行分页获取数据

  • 案例一:当前页面进行分页获取数据

    <template>
      <div class="content-view">
        <!-- 列表数据 -->
        <a-list class="list-view" item-layout="horizontal" :data-source="data">
          <a-list-item slot="renderItem" slot-scope="item">
            {{ item }}
          </a-list-item>
        </a-list>
        <!-- 加载更多 -->
        <a-button @click="touchMore">加载更多</a-button>
      </div>
    </template>
    <script>
    export default {
      data() {
        return {
          // 数据列表
          data: [],
          // 当前页码
          page: this.$route.query.page || 0
        }
      },
      // 监听路由 query 中的 page 参数变化时就重新调用 asyncData,字段参数可自定义
      watchQuery: ['page'],
      // 异步加载数据
      asyncData({ query, params }) {
        // 输出页面参数
        console.log(query, params)
        // 模拟获取分页数据
        const page = (query.page ? Number(query.page) : 0) + 1
        const datas = []
        for (let index = 0; index < page; index++) {
          datas.push(index)
        }
        // 返回分页数据
        return { data: datas }
      },
      methods: {
        // 切换分页数据
        touchMore () {
          // 切换分页数据
          this.$router.push({ name: 'index', params: { id: 1 }, query: { page: this.page + 1 } })
        }
      }
    }
    </script>
    <style>
    .content-view {
      margin: 0 100px;
    }
    </style>
    
  • 案例二:分页获取数据子组件展示

    父组件 - 路由页面 index.vue

    <template>
      <div class="content-view">
        <!-- 列表数据 自定义组件 -->
        <Dzm :data="data"></Dzm>
        <!-- 加载更多 -->
        <a-button @click="touchMore">加载更多</a-button>
      </div>
    </template>
    <script>
    export default {
      data() {
        return {
          // 数据列表
          data: [],
          // 当前页码
          page: this.$route.query.page || 0
        }
      },
      // 监听路由 query 中的 page 参数变化时就重新调用 asyncData,字段参数可自定义
      watchQuery: ['page'],
      // 异步加载数据
      asyncData({ query, params }) {
        // 输出页面参数
        console.log(query, params)
        // 模拟获取分页数据
        const page = (query.page ? Number(query.page) : 0) + 1
        const datas = []
        for (let index = 0; index < page; index++) {
          datas.push(index)
        }
        // 返回分页数据
        return { data: datas }
      },
      methods: {
        // 切换分页数据
        touchMore () {
          // 切换分页数据
          this.$router.push({ name: 'index', params: { id: 1 }, query: { page: this.page + 1 } })
        }
      }
    }
    </script>
    <style>
    .content-view {
      margin: 0 100px;
    }
    </style>
    

    子组件 Dzm.vue 页面数据更新

    <template>
      <!-- 展示列表 -->
      <a-list class="list-view" item-layout="horizontal" :data-source="dataSource">
        <a-list-item slot="renderItem" slot-scope="item">
          {{ item }}
        </a-list-item>
      </a-list>
    </template>
    
    <script>
    export default {
      // 外部传入的数据
      props: {
        data: {
          type: Array,
          default: () => []
        }
      },
      watch: {
        // 监听数据变化并重新赋值给当前数据源进行展示
        data: {
          handler (val) {
            this.dataSource = val
          },
          immediate: true
        }
      },
      data () {
        return {
          // 数据源
          dataSource: []
        }
      }
    }
    </script>
    
    <style>
    
    </style>
    
  • 上面两种 分页获取数据 方案效果一致

    temp.gif

三、不刷新页面,异步请求数据,页面追加数据

  • 这种方案就是怕遇到使用 第三方UI 框架,要么纯拼接,要么找找这个库是否有支持的 cdn 使用,如果有就会方便很多。

  • Nuxt 引入外部CDN插件配置

    <template>
      <div class="content-view">
        <!-- 加载更多 -->
        <a-button @click="touchMore">加载更多</a-button>
      </div>
    </template>
    <script>
    export default {
      methods: {
        // 切换分页数据
        touchMore () {
          // 当前页面主视图
          const contentView = document.getElementsByClassName('content-view')[0]
          // 创建新的标签
          var div = document.createElement("div");
          div.innerText = "异步请求数据,不刷新页面,追加数据"
          // 追加到指定内容位置
          contentView.appendChild(div);
        }
      }
    }
    </script>
    <style>
    .content-view {
      margin: 0 100px;
    }
    </style>
    

    temp.gif