Vue列表實現滾動到指定位置樣式改變


這個需求大概是這樣子:

我做的一個聊天Demo,在搜索框搜索用戶,可以滾動到指定的用戶。然后成選中狀態。

這是目前狀態,我搜索 南宮仆射 ,想要下面的用戶列表直接滾動到 南宮仆射 並改變CSS樣式。

 

 查詢之后是這個子:

 

 

 嗯,我的思路:

在搜索框搜索到用戶之后會返回一個用戶對象,之后會調用列表的點擊事件,改變CSS樣式及做一些聊天的邏輯。然后需要獲取到列表對應的id值,直接使用   document.getElementById(it).scrollIntoView();

具體實現:

列表:使用vue的 v-for指令 ,這里的id值使用的是遍歷的索引值,外層是一個自定義滾動條組件。樣式也是使用vue指令,一個語法糖。

<GeminiScrollbar
                            class="my-scroll-bars">
                        <li v-for="(item,index) in hrs" :id="index"
                            :key="index"
                            :class="{ active: currentSession?item.username === currentSession.username:false}"
                            @click="changeCurrentSession(item)">
                            <img class="avatar"
                                 :src="item.userface">
                            <el-badge :is-dot="isDot[user.username+'#'+item.username]">
                                <p class="name">{{item.name}}</p>
                            </el-badge>
                        </li>
                    </GeminiScrollbar>

 

搜索框:這里使用帶提示的輸入框,

 @click="SearchCurrentSession(SearchHr)為查詢方法。
  <el-autocomplete
                            v-model="SearchHr" class="input-with-select" popper-append-to-body="false"
                            style="width: 90%;padding-left: 5%;padding-top: 10px;margin-bottom: 10px"
                            size="small"
                            :fetch-suggestions="querySearch"
                            placeholder="請輸入內容"
                            @select="handleSelect"
                    >
                        <el-button slot="append" icon="el-icon-search"
                                   @click="SearchCurrentSession(SearchHr)"></el-button>
                    </el-autocomplete>

 

JS代碼:請求為get請求的axios封裝,hr為查詢返回的對象,hrs為所有的列表對象。

SearchCurrentSession() {
                this.getRequest("/chat/?name=" + this.SearchHr).then(resp => {
                    if (resp) {
                        this.hr = resp;
                        this.SearchHr = '';
                        this.changeCurrentSession(this.hr);
                        let it = 0;
                        this.hrs.forEach((item, index) => {
                            if (item.name == this.hr.name) {
                                it = index;
                            }
                        })
                        document.getElementById(it).scrollIntoView();
                        // document.getElementsByClassName("active")[0].scrollIntoView();

                    }
                });

            },

 

  changeCurrentSession(currentSession) {
                this.$store.commit('changeCurrentSession', currentSession)
            },

 

 

頁面全部代碼:

<template>

    <div style="display: flex;justify-content:space-between;height: 100%;width: 100%">
        <div class="leftlist">

            <el-menu background-color="#2e3238" router
                     class="el-menu-vertical-demo"
                     active-text-color="#67C23A"
                     text-color="#fff"
                     :collapse="isCollapse">
                <el-menu-item index="/chat" style="padding-left: 10px;margin:10px 0px 20px 2px">
                    <el-tooltip effect="light" placement="right-start" popper-class="el-scrollbar">
                        <div slot="content">

                            <div style="margin-top: 5px;font-size: 13px;lineHeight:1.5;">
                                <div>用戶名:{{user.name}}</div>
                                <div>手機號碼:{{user.phone}}</div>
                                <div>電話號碼:{{user.telephone}}</div>
                                <div>地 址:{{user.address}}</div>
                                <div>備注:{{user.remark}}</div>
                            </div>
                        </div>
                        <img class="avatar"
                             :src="user.userface"
                             :alt="user.name"></el-tooltip>
                </el-menu-item>
                <el-menu-item index="/chat" style="padding-left: 15px">
                    <i class="fa fa-weixin fa-2x"></i>

                </el-menu-item>
                <el-menu-item index="/chat" style="padding-left: 15px">
                    <i class="fa fa-windows fa-2x"></i>

                </el-menu-item>
                <el-menu-item index="/chat" style="padding-left: 15px">
                    <i class="fa fa-modx fa-2x"></i>

                </el-menu-item>
                <el-menu-item index="/chat" style="padding-left: 15px">
                    <i class="fa fa-share-alt fa-2x"></i>

                </el-menu-item>
            </el-menu>

        </div>
        <div id="list">

            <div style="height:100%;width:100%;overflow-x: hidden">

                <ul style="padding-left: 0px; overflow-x: hidden;">
                    <el-autocomplete
                            v-model="SearchHr" class="input-with-select" popper-append-to-body="false"
                            style="width: 90%;padding-left: 5%;padding-top: 10px;margin-bottom: 10px"
                            size="small"
                            :fetch-suggestions="querySearch"
                            placeholder="請輸入內容"
                            @select="handleSelect"
                    >
                        <el-button slot="append" icon="el-icon-search"
                                   @click="SearchCurrentSession(SearchHr)"></el-button>
                    </el-autocomplete>

                    <GeminiScrollbar
                            class="my-scroll-bars">
                        <li v-for="(item,index) in hrs" :id="index"
                            :key="index"
                            :class="{ active: currentSession?item.username === currentSession.username:false}"
                            @click="changeCurrentSession(item)">
                            <img class="avatar"
                                 :src="item.userface">
                            <el-badge :is-dot="isDot[user.username+'#'+item.username]">
                                <p class="name">{{item.name}}</p>
                            </el-badge>
                        </li>
                    </GeminiScrollbar>
                </ul>
            </div>

        </div>
    </div>
</template>

<script>
    import {mapState} from 'vuex'
    export default {
        name: 'list',
        data() {
            return {
                isCollapse: true,
                SearchHr: '',
                hr: "",
                restaurants: [],
                user: JSON.parse(window.sessionStorage.getItem("user"))
            }
        },
        computed: {
            ...mapState([
                'hrs',
                'isDot',
                'currentSession'
            ])
        },
        methods: {
            SearchCurrentSession() {
                this.getRequest("/chat/?name=" + this.SearchHr).then(resp => {
                    if (resp) {
                        this.hr = resp;
                        this.SearchHr = '';
                        this.changeCurrentSession(this.hr);
                        let it = 0;
                        this.hrs.forEach((item, index) => {
                            if (item.name == this.hr.name) {
                                it = index;
                            }
                        })
                        document.getElementById(it).scrollIntoView();
                        // document.getElementsByClassName("active")[0].scrollIntoView();

                    }
                });

            },
            querySearch(queryString, cb) {
                this.restaurants = this.loadAll();
                let restaurants = [];
                this.restaurants.forEach(value => {
                    let {name, username} = value;
                    let restaurant = {value: name, username: username}
                    restaurants.push(restaurant);
                });
                var results = queryString ? restaurants.filter(this.createFilter(queryString)) : restaurants;
                // 調用 callback 返回建議列表的數據
                cb(results);
            },
            createFilter(queryString) {
                return (SearchHr) => {
                    return (SearchHr.value.toLowerCase().indexOf(queryString.toLowerCase()) === 0);
                };
            },
            loadAll() {
                return this.hrs;
            },
            changeCurrentSession(currentSession) {
                this.$store.commit('changeCurrentSession', currentSession)
            },
            handleSelect(item) {
                console.log(item);
            }
        },
        mounted() {
            this.$store.dispatch('initData');
        }
    }
</script>

<style lang="scss" scoped>


    .my-scroll-bars {
        height: 610px;
    }

    /* override gemini-scrollbar default styles */

    /* vertical scrollbar track */
    .gm-scrollbar.-vertical {
        background-color: #f0f0f0
    }

    /* horizontal scrollbar track */
    .gm-scrollbar.-horizontal {
        background-color: transparent;
    }

    /* scrollbar thumb */
    .gm-scrollbar .thumb {
        background-color: rebeccapurple;
    }

    .gm-scroll-view {
        overflow-x: hidden;
    }

    .gm-scrollbar .thumb:hover {
        background-color: fuchsia;
    }


    input-with-select {
        margin-top: 50px;
        padding-top: 20px;

    }

    .el-scrollbar__wrap {
        width: 100%;
        height: 100%;
        overflow-x: hidden;
    }

    .el-menu-item is-active {
        padding-left: 10px;

    }

    .el-menu-vertical-demo {
        background-color: #2e3238;
        width: 80px;
        height: 100%;
        /*opacity:0.8;*/

    }

    .leftlist {
        background-color: transparent;
        width: 90px;
        height: 700px;
        overflow-x: hidden;
    }

    .avatar {
        width: 45px;
        height: 45px;
        /*這個是圖片和文字居中對齊*/
        border-radius: 5px;
        margin-top: 5px;
    }

    .el-scrollbar__wrap {
        background-color: #E4E7ED;
    }

    #el-scrollbar {
        background-color: #E4E7ED;
    }

    #list {
        background-color: #E4E7ED;
        width: 100%;
        overflow-x: hidden;

        li {
            padding: 7px 15px;
            border-bottom: 1px solid #E4E7ED;
            cursor: pointer;
            list-style: none;
            color: #505458;

            &:hover {
                background-color: rgba(0, 0, 0, 0.07);
            }
        }

        li.active {
            /*注意這個是.不是冒號:*/
            background-color: rgba(0, 0, 0, 0.1);
        }

        .avatar {
            border-radius: 2px;
            width: 30px;
            height: 30px;
            vertical-align: middle;
        }

        .name {
            display: inline-block;
            margin-left: 15px;
            margin-top: 0px;
            margin-bottom: 0px;
        }
    }
</style>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM