【问题标题】:Vue method runs even if I change route, how to run method only if I am on a specific route/component?即使我更改路线,Vue 方法也会运行,仅当我在特定路线/组件上时如何运行方法?
【发布时间】:2020-06-20 10:48:31
【问题描述】:

我正在从 Wordpress API 检索帖子,并且在滚动时我想加载更多帖子并且它可以工作。但是,每当我在底部滚动时单击帖子以打开另一条路线时,应用程序都会调用 API,它基本上会从其他组件运行 scroll() 方法。我正在使用 vue-router 和 axios。

主页组件:

    <template>
    <div class="container-fluid">
        <div class="container">
            <div class="row">
                <!--       Post         -->
                <div class="col-md-4 mb-4" v-for="post in posts" :key="post.id">
                    <div class="card h-100">
                        <div style="overflow: hidden">
                            <img class="card-img-top img-fluid" v-bind:src="post._embedded['wp:featuredmedia']['0'].source_url" alt="Card image cap">
                        </div>
                        <div class="card-body">
                            <router-link :to="{ path: '/article/' + post.slug, query: { id: post.id }, params: { title: post.slug }}">
                                <h5 class="card-title">{{ post.title.rendered }}</h5>
                            </router-link>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>

<script>

import axios from 'axios';

    export default {
        name: "Home",
        data(){
            return {
                posts: [],
                errors: [],
                pagination: 2,
                totalPages: null
            }
        },

        // Fetches posts when the component is created.

        methods: {
            getPosts() {
                axios.get('https://example.com/wp-json/wp/v2/posts?_embed')
                    .then(response => {
                        // JSON responses are automatically parsed.
                        this.posts = response.data;
                        this.totalPages = response.headers['x-wp-totalpages'];
                    })
                    .catch(e => {
                        this.errors.push(e)
                    });
            },

            scroll () {
                window.onscroll = () => {
                    let bottomOfWindow = document.documentElement.scrollTop + window.innerHeight === document.documentElement.offsetHeight;

                    if (bottomOfWindow) {
                        if(this.pagination <= this.totalPages) {
                            axios.get('https://example.com/wp-json/wp/v2/posts?_embed&&page=' + this.pagination)
                                .then(response => {
                                    this.posts = this.posts.concat(response.data);
                                    this.pagination = this.pagination + 1;
                                });
                        }
                    }
                };
            }
        },
        beforeMount() {
            this.getPosts();
        },

        mounted() {
            this.scroll();
        }

    }


</script>

<style scoped lang="scss">
    h1{
        font-weight: 300;
    }
    .card-body{
        a{
            color: #00b6f1;
            text-decoration: none;
            transition: 0.2s ease-in-out;

            &:hover{
                color: #62d4f9;
            }
        }
    }
</style>

单个帖子组件:

<template>
    <div class="container-fluid">
        <div class="container">
            <div class="row">
                <div class="col-12 text-center mt-5 mb-5">
                    <img class="img-fluid" :src="featuredImage" alt="Card image cap">
                </div>
                <div class="col-12">
                    <h1>{{ title }}</h1>
                </div>
                <div class="col-12 content">
                    <p v-html="content">{{ content }}</p>
                </div>
            </div>
        </div>
    </div>
</template>

<script>
    import axios from "axios";


    export default {
        name: "Single",
        data(){
            return {
                post: {},
                featuredImage: null,
                errors: [],
                title: null,
                content: null,
            }
        },

        methods:{
            getPost() {
                axios.get('https://example.com/wp-json/wp/v2/posts/'+this.$route.query.id+'?_embed')
                    .then(response => {
                        // JSON responses are automatically parsed.
                        this.post = response.data;
                        this.featuredImage = response.data._embedded['wp:featuredmedia']['0'].source_url;
                        this.title = response.data.title.rendered;
                        this.content = response.data.content.rendered;
                    })
                    .catch(e => {
                        this.errors.push(e)
                    })
            },
        },
        beforeMount() {
            this.getPost();
        },
    }

</script>

<style lang="scss">
    .content{
        img, iframe{
            max-width: 100%;
            height: auto;
            margin: auto;
            display: block;
            margin-top: 30px;
            margin-bottom: 30px;
        }

        iframe{
            height: 300px;
        }

        p{
            color: #767676;
            font-size: 14px;
            line-height: 24px;
            font-weight: 400;
        }

        h2{
            color: black;
        }

        a {
            color: #00b6f1;
            text-decoration: none !important;
            transition: 0.2s ease-in-out;

            &:hover{
                color: #62d4f9;
            }
        }
    }
</style>

【问题讨论】:

  • 我看不到该方法是直接放在视图上还是放在外部组件文件中。也许,您可以将它从当前位置移动到另一个位置(在单个帖子视图文件之外或在您不在那里导入的组件中)。基本上scroll() 方法不应该出现在单个帖子视图中。
  • 您好,滚动方法在主视图内部。当我转到不使用或安装滚动方法的单个帖子视图时,它仍然运行。此外,当我直接进入单个帖子视图时,滚动方法不会运行,但是当我进入主视图并返回单个帖子视图时,滚动方法会在任何地方再次运行
  • 我从两个组件中添加了更好的屏幕截图
  • stackoverflow.com/help/how-to-ask ,问题应该包含代码,而不是图像。

标签: javascript vue.js components vue-component vue-cli-4


【解决方案1】:

Home.vue试试这个:

beforeDestroy() {
  this.scroll = null
  delete this.scroll
}

发生这种情况是因为在更改路由时,scroll() 方法仍然挂载。这应该可以防止它被加载到Home.vue以外的其他地方。

【讨论】:

  • 谢谢,钩子可以工作,但里面的函数不行。它仍然在其他视图上运行。有没有办法卸载函数?
  • 我相信这与window.onscroll 函数有关。我用console.log尝试了scroll()函数,当我改变路由时它成功删除了函数。
  • 试试我的更新。它应该可以工作,但如果不行,请尝试调用destroyed 而不是beforeDestroy。更多关于 Vue.js 生命周期的信息:scotch.io/tutorials/demystifying-vue-lifecycle-methods
  • 试过了,没用。但我想出了一个不同的方法,就像这样:destroyed() { window.onscroll = null; } 并且可以工作。我不确定这是否正确但有效,再次感谢
  • 这是因为你绑定了一个匿名函数到全局window.scroll事件。当您使用单页应用程序时,即使组件不再在范围内,它仍然被绑定,因为页面没有刷新。要删除它,您确实需要将window.scroll 设置为null。删除this.scroll没有效果,因为它没有绑定window.scroll,但匿名函数仍然是。
猜你喜欢
  • 2015-06-22
  • 2020-01-21
  • 1970-01-01
  • 2023-01-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多