vue3使用vant4的列表vant-list点击进入详情自动滚动到对应位置,踩坑日记(一天半的踩坑经历)
vue
vuejs/vue: 是一个用于构建用户界面的 JavaScript 框架,具有简洁的语法和丰富的组件库,可以用于开发单页面应用程序和多页面应用程序。
项目地址:https://gitcode.com/gh_mirrors/vu/vue
免费下载资源
·
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()会不执行
GitHub 加速计划 / vu / vue
207.54 K
33.66 K
下载
vuejs/vue: 是一个用于构建用户界面的 JavaScript 框架,具有简洁的语法和丰富的组件库,可以用于开发单页面应用程序和多页面应用程序。
最近提交(Master分支:2 个月前 )
73486cb5
* chore: fix link broken
Signed-off-by: snoppy <michaleli@foxmail.com>
* Update packages/template-compiler/README.md [skip ci]
---------
Signed-off-by: snoppy <michaleli@foxmail.com>
Co-authored-by: Eduardo San Martin Morote <posva@users.noreply.github.com> 4 个月前
e428d891
Updated Browser Compatibility reference. The previous currently returns HTTP 404. 5 个月前
更多推荐
已为社区贡献5条内容
所有评论(0)