Vue.js简单案例教程

16-11-03 banq
这里以Vue.js创建一个简单的小回答测验项目quiz为案例,一步步从无到有展示Vue的使用。

安装

创建HTML主要骨架,并导入Vue:

<html>
<body>
  
  <!-- Vue在这个div中起作用工作 -->
  <div id="app">
    <!-- Vue的data.title 显示在这儿-->
    <h1>{{ title }}</h1>
  </div>
  
  <!-- Load Vue script -->
  < script src = " https://vuejs.org/js/vue.js " >< /script >
  <!-- On load, init Vue -->  
    window.function(){
      new Vue({
        el: '#app', // Vue 工作在这个div 
        data: { title: 'Hello.' }, // title设置为 'Hello.'
      });
    }
  
</body>
<p>

将其保存为foo.html,在浏览器打开,会看到Hello,这里我们学习了{{title}}语法渲染数据。

Data数据

创建一个简单的quiz回答项目,带有一个标题和两个问题,每个问题有一个或多个答案,其中有多个可能答案正确。我们将其连接Vue的实例数据。

 
    window.function(){
      
      var quiz = {
        title: 'My quiz',
        questions: [
          {
            text: "问题 1",
            responses: [
              {text: '错误, too bad.'}, 
              {text: '正确!', correct: true}, 
            ]
          }, {
            text: "问题 2",
            responses: [
              {text: '正确答案', correct: true}, 
              {text: '回答错误'}, 
            ]
          } 
        ]
      };
      
      new Vue({
        el: '#app',
        data: { quiz: quiz }, // 连接quiz 到 Vue data
      });
    }
  
<p>

设置好基本回答问题后,下一步如何使用Vue loops循环输出。

在Html渲染数据

Vue提供指令驱动循环系统将数据加入HTML:v-for=”item on items”:

<div id="app">
  <!-- Quiz title -->
  <h1>{{ quiz.title }}</h1>
  <!-- questions: 为questions中每个question用div显示输出 -->
  <div v-for="question in quiz.questions">
    <h2>{{ question.text }}</h2>
    <!-- Responses: display a li for each possible response with a radio button -->
    <ol>
      <li v-for="response in question.responses">
        <label>
          <input type="radio"> {{response.text}}
        </label>
      </li>
    </ol>
  </div>
</div>
<p>

这里有一个不显眼的响应式reactive系统,如果数据对象改变,HTML试图会更新,现在quiz这个项目的所有问题都已经显示,它是活动的及时更新的,是积极响应的。

导航

现在这个项目中所有问题显示在一个页面上,那我们改一下,每个页面显示一个问题,需要在每个问题页面上增加next(上一页)和previous(下一页)。隐藏所有不不是当前问题的其他问题。

我们创建的app能够处理用户输入:按钮点按,首先,增加当前问题索引数据和两个导航方法到Vue实例:

new Vue({
  el: '#app',
  data: {
    quiz: quiz,
    // 存储当前问题索引Store current question index
    questionIndex: 0,
  },
  // 当点按按钮时,视图会触发这些方法
  methods: {
    // Go to next question 到下一个问题
    next: function() {
      this.questionIndex++;
    },
    // Go to previous question到上个问题
    prev: function() {
      this.questionIndex--;
    }
  }
});
<p>

questionIndex 会在next()增加,而在prev()调用是减少。

下面创建Html导航按钮触发上面两个方法,使用v-on:click=”next”指令触发next();使用v-show=”index === questionIndex”显示当前问题,不要忘记将index索引加入v-for中。

<div id="app">
  <h1>{{ quiz.title }}</h1>
  <!-- index is used to check with current question index -->
  <div v-for="(question, index) in quiz.questions">
    <!-- 隐藏不是当前问题的其他问题,只显示索引对应的问题 -->
    <div v-show="index === questionIndex">
      <h2>{{ question.text }}</h2>
      <ol>
        <li v-for="response in question.responses">
          <label>
            <input type="radio"> {{response.text}}
          </label>
        </li>
      </ol>
      <!-- 两个导航按钮 -->
      <!-- Note: prev is hidden on first question -->
      <button v-if="questionIndex > 0" v-on:click="prev">
        prev
      </button>
      <button v-on:click="next">
        next
      </button>
    </div>
  </div>
</div>
<p>

现在我们可以进入这个问答项目。最后一页是空白的,我们应该显示测验结果在它。

Quiz结果

要显示一个评分结果,我们必须处理每个问题的用户响应。这是最难的一步。

目前radio 按钮没有绑定Vue,点按radio 没有效果,v-model实现表单输入和应用状态两者双向绑定,使用下面radio 替代之前的:

<!-- for each response of the current question -->
<li v-for="response in question.responses">
  <label>
    <!-- The radio button has three new directives -->
    <!-- v-bind:如果回答正确设置 "value""true"-->
    <!-- v-bind:n设置 "name" 到问题索引,指向问题一组答案中一个-->
    <!-- v-model 和userResponses 绑定-->
    <input type="radio" 
           v-bind:value="response.correct" 
           v-bind:name="index" 
           v-model="userResponses[index]"> {{response.text}}
  </label>
</li>
<p>

name和value被绑定到Vue数据,然后在Vue实例初始化userResponses :

new Vue({
  el: '#app',
  data: {
    quiz: quiz,
    questionIndex: 0,
    // 数组为每个问题初始值为 "false" 
    // 意思是: "用户正确回答这个问题吗?" "no".
    userResponses: Array(quiz.questions.length).fill(false)
  },
  methods: {
    // ...
  }
});
<p>

这是为了处理用户响应的最后一步:userResponses包含一个数组,你可以向前和向后导航,选择和更改答案,会发现userresponses“自己更新”。

创建方法进行分数计算:

new Vue({
  // ...
  methods: {
    // ...
    // 返回 在userResponses中"true" 数量
    score: function() {
      return this.userResponses.filter(function(val) { return val }).length;
    }
  }
});
<p>

增加下面最后一页显示总分:

<div id="app">
  <h1>{{ quiz.title }}</h1>
  <div v-for="(question, index) in quiz.questions">
    <!-- //... -->
  </div>
  <!-- Last page, quiz is finished, display result -->
  <div v-show="questionIndex === quiz.questions.length">
    <h2>
    Quiz finished
  </h2>
    <p>
      Total score: {{ score() }} / {{ quiz.questions.length }}
    </p>
  </div>
</div>
<p>

最后项目完成,可在这里演示。源码这里

原文:

Create a quiz with Vue.js – Medium

[该贴被banq于2016-11-03 11:09修改过]

    

1
猜你喜欢