使用浏览器的返回/前进按钮进行Vue.js调查

3

我正在使用Vue.js创建一个多页调查。一切都正常,唯一需要解决的是让浏览器的后退/前进按钮与页面上的上一步/下一步按钮相同。

我已经搜索了多次,但目前还没有找到任何解决方案...

我知道可以使用vue-router,但我不知道如何适应它。

我该如何实现这个功能?

HTML

<!DOCTYPE html>
***head***

<body>
    <div id="app">
        <h1>{{ survey.title }}</h1>

        <div id="survey" v-for="(question, index) in survey.questions">

            <div v-show="index === questionIndex">
                <h3>{{ question.text }}</h3>
                <div v-if="questionIndex === 2">
                    <input type="text" v-model="userResponses[2]" placeholder="Please enter your location:"> 
                </div>
                <div v-else-if="questionIndex === 4">
                    <select v-model="question4" multiple>
                        <option v-for="response in question.responses"> {{ response.text }} </option></select>
                </div>
                <div v-else-if="questionIndex === 5">
                    <select v-model="question5" multiple>
                        <option v-for="response in question.responses"> {{ response.text }} </option></select>
                </div>
                <div v-else>
                    <ol>
                        <li v-for="response in question.responses">
                            <label>
                                <input type="radio" v-bind:value="response" 
                                                    v-bind:name="index" 
                                                    v-model="userResponses[index]"> {{ response.text }}
                            </label>
                        </li>
                    </ol>
                </div>
                <div id="container">
                    <button id="left" v-if="questionIndex > 0" v-on:click="prev">Previous</button>
                    <button id="right" v-on:click="next">Next</button>
                </div>
            </div>
        </div>
        <div v-show="questionIndex === survey.questions.length">
            <h2>Thank you for taking our survey!</h2>
            <p>{{ userResponses }}</p>
            <p>{{ question4 }}</p>
            <p>{{ question5 }}</p>
        </div>
    </div>

    <footer>&copy; 2018 George Salukvadze for ***</footer>
</body>
</html>

Vue.js

window.onload = survey;
function survey(){
 var survey = {
    title: 'Welcome to online survey for Liquid!',
    questions: [
        {
            text: "What is your age group?",
            responses: [
                {text: '15-24'}, 
                {text: '25-34'},
                {text: '35-44'},
            ]
        }, {
            text: "What is your gender?",
            responses: [
                {text: 'Male'}, 
                {text: 'Female'},
                {text: 'Do not identify'},
            ]
        }, {
            text: "Where do you live?",
            responses: [
                {text: 'Please enter your location'},
            ]
        }, {
            text: "Do you like to shop?",
            responses: [
                {text: 'Yes'},
                {text: 'No'},
            ]
        }, {
            text: "Select your favorite things to buy:",
            responses: [
                {text: 'Clothing'},
                {text: 'Lingerie'},
                {text: 'Shoes'},
                {text: 'Devices'},
                {text: 'Cars'},
            ]
        }, {
            text: "Please select your favorite brands:",
            responses: [
                {text: 'Sandro'},
                {text: 'Maje'},
                {text: 'Sony'},
                {text: 'Ferrari'},
                {text: 'BMW'},
                {text: 'Asus'},
            ]
        }
    ]
 };

 new Vue({
     el: '#app',
     data: { 
         survey: survey,
         questionIndex: 0,
         userResponses: Array(survey.questions.length),
         question4: Array(5),
         question5: Array(9),
     }, 
     methods: {
         next: function() {
             this.questionIndex++;
         },
         prev: function() {
             this.questionIndex--;
         }
     }
 });
}

这不是你的答案,但我认为这可能是一个问题:在函数内定义调查不会让它具有全局范围,对吧?我认为你需要将 new Vue({...}) 代码放在 onload 处理程序中。 - Robert Moore
@RobertMoore,感谢您的评论。页面本身运行得很好,唯一的问题是浏览器的“返回”按钮不能返回到上一个问题(例如),而是返回到浏览器之前打开的页面。所以您认为您的想法可能解决这个问题?我会尝试一下并回复您。 - George Salukvadze
1个回答

4

您可以使用所暗示的vue-router。然而,对于您的例子,最简单的解决方案是仅使用浏览器的历史记录API。步骤如下:

  • When moving to previous/next questions, use history.pushState to add a state to the browser's history:

     methods: {
         next: function() {
             this.questionIndex++;
             this.updateHistory();  // added this line
         },
         prev: function() {
             this.questionIndex--;
             this.updateHistory();  // added this line
         },
         updateHistory: function() {  // added this method
             history.pushState({questionIndex: this.questionIndex}, "Question " + this.questionIndex);
         }
     }
    
  • And now all you have to do is listen to those history state changes. A good spot to hook a listener to this event is the mounted:

     mounted: function() {
         var vm = this;
         window.addEventListener('popstate', function(event) {
             vm.questionIndex = (event.state || {questionIndex: 0}).questionIndex;
         });
     },
    

就是这样。

点击这里查看在JSBin上的演示页面(查看历史按钮)

您可以在这里找到该演示的源代码


只要我们在这里,我也想实现一个cookie,以便在浏览器关闭时保存调查状态。你能帮我吗? - George Salukvadze
你应该开一个新的问题,这样其他人也可以帮助你。你可能需要一个插件来处理cookies。 - acdcjunior

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接