• vue3使用vant4的列表vant-list点击进入详情自动滚动到对应位置,踩坑日记(一天半的踩坑经历)


    1.路由添加keepAlive

     <!-- Vue3缓存组件,写法和Vue2不一样-->
        <router-view v-slot="{ Component }">
          <keep-alive>
            <component :is="Component" v-if="$route.meta.keepAlive"/>
          </keep-alive>
          <component :is="Component" v-if="!$route.meta.keepAlive"/>
        </router-view>
    

    2.路由添加mate标识

     {
            path: "/user-manage", // 用户管理
            name: "user-manage",
            meta: {
              keepAlive: true, //此页面需要缓存
              isBack: false,
              scrollTop:0
            },
            component: () => import("../pages/user/index.vue"),
          },
    

    3.在beforeRouteEnter里面给如果从详情页面返回meta.isBack改变值为true ps(beforeRouteEnter这个生命周期函数里滑动不生效需要在onActivated里面执行),(因为vu3 setup里面没有beforeRouteEnter)需要单独引入一个script,在onActivated生命周期函数里让页面滑动到指定位置(全部代码)

    <template>
      <div class="area-setting-list" ref="wrapper">
        <!-- 导航栏 -->
        <TopMenu
          :titleText="state.menuText"
          :backgroundColor="state.bgColor"
          :pathName="state.pathName"
        ></TopMenu>
        <!-- 搜索框 -->
        <van-sticky offset-top="44">
          <div
            class="search-box"
            :style="{ backgroundColor: state.backgroundColor }"
          >
            <div>
              <van-field
                v-model="state.queryType.keyword"
                left-icon="search"
                placeholder="请输入邮箱/手机号"
                @blur="init"
                @click-input="updataChange"
              />
            </div>
            <div @click="state.show = true"></div>
          </div>
        </van-sticky>
        <div class="device-list">
          <van-list
            v-model:loading="state.loading"
            :finished="state.finished"
            finished-text="没有更多了"
            @load="onLoad"
            offset="100"
            :immediate-check="false"
          >
            <div
              class="device-item"
              v-for="(item, index) in state.list"
              :key="index"
              @click="goUserDetail(item)"
            >
              <div class="first-item">
                <div>
                  <div class="first-item_light">
                    {{ item.userIdentity?.value + index }}
                  </div>
                  <div>账号: {{ item.account }}</div>
                </div>
                <div>
                  <van-switch
                    v-model="item.checked"
                    size="20px"
                    :loading="item.switchLoading"
                    @click.stop="switchChange(item)"
                  />
                </div>
              </div>
              <div class="second-item">
                <div>创建时间 : {{ item.createTime }}</div>
                <div>{{ item.enableStatus?.value }}</div>
              </div>
            </div>
          </van-list>
        </div>
        <div class="addBtn" @click="addUser">添加用户</div>
        <!-- 筛选弹框 -->
        <van-action-sheet v-model:show="state.show" title="筛选">
          <div class="pop-content">
            <div class="title">账户类型</div>
            <div class="select-ite">
              <div class="active">
                电站业主
                <div class="select-bage"></div>
              </div>
              <div>
                经销商
                <div class="select-bage"></div>
              </div>
              <div>
                服务商
                <div class="select-bage"></div>
              </div>
              <div>
                安装商
                <div class="select-bage"></div>
              </div>
            </div>
            <div class="title">创建时间</div>
            <div class="select-time">
              <div @click="selectStartTime">
                {{
                  state.queryType.startTime == ""
                    ? "开始时间"
                    : state.queryType.startTime
                }}
              </div>
              <div>~</div>
              <div @click="selectEndTime">
                {{
                  state.queryType.endTime == ""
                    ? "结束时间"
                    : state.queryType.endTime
                }}
              </div>
            </div>
            <div class="select-btn">
              <div @click="restQuery">重置</div>
              <div @click="getMoreQuery">确定</div>
            </div>
          </div>
        </van-action-sheet>
        <!-- 日期选择器 -->
        <van-popup
          v-model:show="state.showPop"
          position="bottom"
          round
          label="有效日期"
          custom-style="height: 50%;"
          @close="state.showPop = false"
        >
          <van-date-picker
            title="选择日期"
            :min-date="minDate"
            :max-date="maxDate"
            @cancel="state.showPop = false"
            @confirm="selectTime"
          />
        </van-popup>
      </div>
    </template>
    <script>
    import { defineComponent } from "vue";
    
    export default defineComponent({
      beforeRouteEnter(to, from, next) {
        if (from.name === "edit-user") {
          to.meta.isBack = true;
          window.scrollTo({
            top: 300,
            behavior: "smooth", // 平滑滚动
          });
          console.log("beforeRouteEnter");
          console.log(from.meta);
          console.log(store.state.listHeight);
          console.log("beforeRouteEnter");
        } // 放行路由
    
        next();
      },
    });
    </script>
    <script setup>
    import daohang from "../../assets/daohang.png";
    import {
      getCurrentInstance,
      onMounted,
      reactive,
      inject,
      ref,
      onActivated,
      onUnmounted,
      nextTick,
      watch,
    } from "vue";
    import TopMenu from "../../component/topMenu.vue";
    import { useRouter, useRoute, onBeforeRouteLeave } from "vue-router";
    import store from "@/store/index";
    
    const { proxy } = getCurrentInstance();
    const router = useRouter();
    const route = useRoute();
    const wrapper = ref(null);
    
    const state = reactive({
      menuText: "用户管理",
      pathName: "",
      bgColor: "transparent",
      activeColor: "#EA5514",
      backgroundColor: "#F9EBE5",
      loading: false,
      finished: false,
      list: [],
      pageNum: 1,
      backgroundColor: "transparent",
      checked: true,
      show: false,
      showPop: false,
      queryType: {
        endTime: "",
        keyword: "",
        startTime: "",
      },
      pageType: {
        pageIndex: 1,
        pageSize: 10,
      },
      currentScrollTop: 0,
      timeType: 0,
    });
    watch(
      () => state.queryType.keyword, // 要监听的响应式属性
      (newValue, oldValue) => {
        // 当属性值变化时,这个回调函数会被调用
        console.log(newValue);
        if (newValue == "") {
          init();
        }
      }
    );
    // 列表触底加载
    const onLoad = () => {
      console.log("触底了");
      state.loading = false;
      state.pageType.pageIndex++;
      getList();
    };
    
    // 监听页面滚动的方法
    const doScroll = (event) => {
      console.log(window.scrollY);
      state.currentScrollTop = window.scrollY;
      if (window.scrollY > 20) {
        state.bgColor = "#D6E6F9";
        state.backgroundColor = "#D6E6F9";
      } else {
        state.bgColor = "transparent";
        state.backgroundColor = "transparent";
      }
    };
    
    // 数据初始化
    const init = () => {
      state.list = [];
      state.finished = false;
      state.pageType.pageIndex = 1;
      getList();
    };
    // 查询
    const searchList = () => {
      state.pageType.pageIndex = 1;
      state.finished = false;
      state.list = [];
      getList();
    };
    const updataChange = (value) => {
      console.log(value);
    };
    // 查询用户列表
    const getList = () => {
      state.loading = true;
      proxy.$H
        .post(proxy, proxy.$A.user.list, {
          data: state.queryType,
          page: state.pageType,
        })
        .then((res) => {
          let lists = res.data.data;
          state.loading = false;
          if (lists.length > 0) {
            for (let item of lists) {
              if (item.enableStatus.key == "ENABLE") {
                item.checked = true;
              } else {
                item.checked = false;
              }
              item.switchLoading = false;
            }
          }
          if (lists.length < 10) {
            state.finished = true;
          }
          state.list = state.list.concat(lists);
          console.log("ccccc");
          console.log(state.list);
          console.log("ccccc");
        });
    };
    // 启用禁用用户
    const switchChange = (item) => {
      console.log(item);
      item.switchLoading = true;
      proxy.$H
        .post(proxy, proxy.$A.user.updateEnableStatus, {
          data: {
            key: item.id,
            value: item.checked ? "DISABLE" : "ENABLE",
          },
        })
        .then((res) => {
          item.switchLoading = false;
          init();
        })
        .catch((err) => {
          item.switchLoading = false;
        });
    };
    // 新增用户
    const addUser = () => {
      console.log("点了新增用户");
      router.push("/add-user");
    };
    
    // 用户详情
    const goUserDetail = (item) => {
      // store.commit("setDetailFlag", true);
      console.log("点击了详情");
      store.commit("setListHeight", state.currentScrollTop);
      router.push({path:'/edit-user',query:{id:item.id}})
      
    };
    
    // 选择开始时间
    const selectStartTime = () => {
      state.showPop = true;
      state.timeType = 0;
    };
    
    // 选择结束时间
    const selectEndTime = () => {
      state.showPop = true;
      state.timeType = 1;
    };
    // 时间picker触发的事件
    const selectTime = (value) => {
      let time =
        value.selectedValues[0] +
        "-" +
        value.selectedValues[1] +
        "-" +
        value.selectedValues[2];
      console.log(time);
      if (state.timeType == 0) {
        state.queryType.startTime = time;
      } else {
        state.queryType.endTime = time;
      }
      state.showPop = false;
    };
    // 更多筛选点击确定
    const getMoreQuery = () => {
      if (state.queryType.startTime != "") {
        if (state.queryType.endTime == "") {
          proxy.$U.errMsg("请选择结束时间");
          return;
        }
      }
      state.show = false;
      init();
    };
    // 重置查询条件
    const restQuery = () => {
      state.queryType = {
        endTime: "",
        keyword: "",
        startTime: "",
      };
    };
    onMounted(() => {
      // 当天日期
      console.log("onMounted");
      // 监听页面滚动
      window.addEventListener("scroll", doScroll, true);
    });
    onUnmounted(() => {
      window.removeEventListener("scroll", doScroll);
    });
    onActivated(() => {
      console.log("onActivated");
      console.log(route.meta.isBack);
      console.log("onActivated");
      if (!route.meta.isBack) {
        // 不是从详情页面进来的就重新加载数据
        init();
        route.meta.isBack = false;
      }
      window.scrollTo({
        top: store.state.listHeight,
        behavior: "smooth", // 平滑滚动
      });
    });
    </script>
    
    <style lang="less" scoped>
    @import "./index.less";
    .dialog-content {
      max-height: 60vh;
      overflow-y: scroll;
      border: 1px solid red;
      padding: 20px;
      .dia-cent {
        margin-bottom: 3px;
      }
    }
    </style>
    
    

    在这里插入图片描述
    注意点!!!!!!!
    在这里插入图片描述
    否则window.scrollTo()会不执行

  • 相关阅读:
    pbootcms中使用composer
    ES6基础5
    微服务学习 | Eureka注册中心
    Spring——如何理解Spring,DI和IoC
    悬崖边:企业如何应对网络安全漏洞趋势
    OpenCV实战(4)——像素操作
    OpenAI 组建安全 AGI 新团队!应对AI“潘多拉魔盒”
    使用CMake进行C++项目管理
    RabbitMQ和spring boot整合及其他内容
    Perl 语言入门教程
  • 原文地址:https://blog.csdn.net/weixin_44705979/article/details/139982493