美文网首页
van-tab van-pull-refresh下拉加载(网上抄

van-tab van-pull-refresh下拉加载(网上抄

作者: 糖醋里脊120625 | 来源:发表于2022-06-24 16:47 被阅读0次
    image.png

    watch
    const emit = defineEmits(['changeLabel'])
    const labelList = store.getters['label/labelList']

    主要van-tabs.vue

    
    
    <template>
      <div class="app-container">
        <form action="/">
          <van-search
            v-model="keyword"
            input-align="center"
            :clearable="false"
            :show-action="!!keyword"
            placeholder="请输入搜索关键词"
            @search="() => (params.keyword = keyword)"
            @cancel="() => (params.keyword = '')"
          />
        </form>
        <LabelSelect
          @changeLabel="(val) => (params.type = val)"
          ref="label"
        ></LabelSelect>
        <van-tabs
          v-model:active="params.sortBy"
          color="#009688"
          title-active-color="#009688"
          title-inactive-color="#595959"
          line-width="24px"
          line-height="2px"
        >
          <van-tab title="全部" name=""></van-tab>
          <van-tab title="推荐" name="level"></van-tab>
          <van-tab title="最新" name="releaseTime"></van-tab>
          <van-tab title="最热" name="pv"></van-tab>
          <van-tab title="最赞" name="likes"></van-tab>
    
          <List :showTitle="false" :params="params"></List>
        </van-tabs>
      </div>
    </template>
    
    <script setup lang="ts">
    import LabelSelect from './components/labelSelect.vue'
    import List from '@/views/home/components/list.vue'
    import { reactive, ref } from 'vue'
    import SvgIcon from '@/components/svgIcon'
    
    let params = reactive({
      keyword: '',
      sortBy: '',
      type: '',
      isMobile: true,
    })
    let keyword = ref('')
    </script>
    
    

    主要LabelSelect.vue

    <template>
      <div class="label-box">
        <div
          class="label-text"
          :class="{ 'label-text__active': activeIndex === index && labelName }"
          :style="{
            backgroundColor:
              activeIndex === index && labelName ? item.bgColor : '#fff',
          }"
          v-for="(item, index) in labelList"
          :key="item.label"
          @click="handleLabel(index, item.label)"
        >
          {{ item.label }}
        </div>
      </div>
    </template>
    
    <script setup lang="ts">
    import { useStore } from 'vuex'
    import { ref } from 'vue'
    
    const store = useStore()
    const emit = defineEmits(['changeLabel'])
    const labelList = store.getters['label/labelList']
    console.log(labelList)
    let activeIndex = ref(-1)
    let labelName = ref('')
    
    // 选择label类别
    // index的类型有可能是 string | number | symbol,不能写 number,打包编译会报错
    const handleLabel = (index: any, label: string) => {
      labelName.value = activeIndex.value === index && labelName.value ? '' : label
      activeIndex.value = index
      emit('changeLabel', labelName)
    }
    </script>
    

    主要list.vue

    <template>
      <div
        :class="{ 'list-container': true, 'list-container__pt': !props.showTitle }"
        v-if="hasLoad"
      >
        <van-pull-refresh
          v-model="refreshing"
          @refresh="handleRefresh"
          v-if="total"
        >
          <div class="list-title" v-if="props.showTitle">
            <SvgIcon name="icon-label01"></SvgIcon>
            <span>最新文章({{ total }})</span>
          </div>
          <van-list
            v-model:loading="loading"
            :finished="finished"
            :immediate-check="false"
            :finished-text="total > 10 ? '--我是有底线的--' : ''"
            @load="handleLoad"
          >
            <div
              class="list-item"
              v-for="item in list"
              :key="item._id"
              @click.stop="gotoDetail(item._id)"
            >
              <div class="item-content">
                <img :src="item.imageUrl" />
                <div class="content-box">
                  <div class="content-top">
                    <div class="content-title">{{ item.name }}</div>
                    <div class="content-desc">{{ item.specification }}</div>
                  </div>
                  <div class="content-label">
                    <div
                      class="label-text"
                      :style="{ backgroundColor: getLabelColor(label) }"
                      v-for="label in item.type"
                      :key="label"
                    >
                      {{ label }}
                    </div>
                  </div>
                </div>
              </div>
              <div class="item-footer">
                <div class="footer-item">
                  <SvgIcon name="icon-date02"></SvgIcon>
                  <div class="footer-text">
                    2020-12-30
                  </div>
                </div>
                <div class="footer-item">
                  <SvgIcon name="icon-browse02"></SvgIcon>
                  <div class="footer-text">800</div>
                </div>
                <div
                  class="footer-item"
                  :class="{ 'icon-likes': getLikesColor(item._id) }"
                  @click.stop="handleLikes(item._id)"
                >
                  <SvgIcon name="icon-like02"></SvgIcon>
                  <div class="footer-text">
                    1000
                    {{ formatNumber(getLikesNumber(item._id, item.likes)) }}
                  </div>
                </div>
              </div>
            </div>
          </van-list>
        </van-pull-refresh>
        <NoData v-else></NoData>
      </div>
    </template>
    
    <script setup lang="ts">
    import base from '@/utils/base'
    import NoData from '@/components/noData'
    import SvgIcon from '@/components/svgIcon'
    import { apiGetBlogList, apiUpdateLikes } from '@/api/blog'
    import { formatTime, formatNumber } from '@/filters/index'
    import useClickLike from '@/useMixin/useClickLike'
    import useGetLabelColor from '@/useMixin/useGetLabelColor'
    import { ref, watch } from 'vue'
    import { useRouter } from 'vue-router'
    import { articleModel } from '@/models/index'
    
    interface Props {
      showTitle?: boolean
      params?: object
    }
    // 定义props默认值
    const props = withDefaults(defineProps<Props>(), {
      showTitle: true,
      params: undefined,
    })
    const { getLikesNumber, getLikesColor, handleLikes, likeList } =
      useClickLike(apiUpdateLikes)
    const { getLabelColor } = useGetLabelColor()
    const route = useRouter()
    
    let loading = ref(false)
    let finished = ref(false)
    let refreshing = ref(false)
    let hasLoad = ref(false)
    let pageindex = ref(1)
    let pagesize = ref(10)
    let total = ref(0)
    let list = ref<Array<articleModel>>([])
    
    // 监听label页传下来的参数
    if (props.params) {
      watch(props.params, () => {
        pageindex.value = 1
        hasLoad.value = false
        loading.value = false
        finished.value = false
        list.value = []
        likeList.value = []
        getBlogList()
      })
    }
    // 获取文章列表
    const getBlogList = (reload = true) => {
      reload && base.showLoading()
      return apiGetBlogList({
        pageindex: pageindex.value,
        pagesize: pagesize.value,
        ...props.params,
      })
        .then((res) => {
          list.value = [...list.value, ...res?.data?.list]
          total.value = res?.data?.total
          finished.value = pageindex.value * pagesize.value >= total.value
        })
        .catch((err) => console.log(err))
        .finally(() => {
          hasLoad.value = true
          loading.value = false
          refreshing.value = false
          reload && base.hideLoading()
        })
    }
    getBlogList()
    
    // 下拉刷新
    const handleRefresh = () => {
      pageindex.value = 1
      list.value = []
      likeList.value = []
      getBlogList()
    }
    // 滚动加载
    const handleLoad = () => {
      if (!refreshing.value) {
        pageindex.value++
        getBlogList(false)
      }
    }
    // 去详情页
    const gotoDetail = (id: string) => {
      route.push({ path: '/article/detail', query: { id } })
    }
    </script>
    
    

    vuex.main

    import { createStore } from "vuex";
    import label from "./modules/label";
    
    export default createStore({
      state: {},
      mutations: {},
      actions: {},
      modules: {
        label,
      },
    });
    
    

    vuex label.ts

    import { apiGetLabelList } from "@/api/label";
    import { labelModel } from "@/models/index";
    
    type State = {
      labelList: Array<labelModel>;
    };
    export default {
      namespaced: true,
      state: {
        labelList: [ {
          _id: "1",
          label: "查询记录_蘑菇",
          bgColor: "string",
          createTime: "string",
        }],
      },
      mutations: {
        setLabelList(state: State, data: Array<labelModel>) {
          state.labelList = data;
        },
      },
      actions: {
        getLabelList(context: { commit: (arg0: string, arg1: any) => void }) {
          let params = {
            pageindex: 1,
            pagesize: 50,
          };
          return apiGetLabelList(params)
            .then((res) => {
              context.commit("setLabelList", res?.data?.list);
            })
            .catch((err) => {
              console.log(err);
            })
            .finally(()=>{
              alert(2)
            })
            ;
        },
      },
      getters: {
        labelList(state: State) {
          return state.labelList;
        },
      },
    };
    
    

    引用段落
    actions中
    getLabelList方法触发

    <script lang="ts">
    import { useStore } from 'vuex'
    import { defineComponent } from 'vue'
    export default defineComponent({
      name: 'App',
      setup() {
        const store = useStore()
        const getLabelList = () => store.dispatch('label/getLabelList')
        getLabelList()
      },
    })
    </script>
    

    相关文章

      网友评论

          本文标题:van-tab van-pull-refresh下拉加载(网上抄

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