Skip to content

6. 项目 [vuejs-04]:指令 [v-model, v-bind]、计算属性、输入表单

项目 [vuejs-04] 的树形结构如下:

Image

6.1. 主脚本 [main.js]

与前一个示例中的相同。

6.2. 主组件 [App]

[App.vue] 的代码如下:


<template>
  <b-container>
    <b-card>
      <!-- 提示信息 -->
      <b-row>
        <b-col cols="8">
          <b-alert show variant="success" align="center">
            <h4>[vuejs-04] : directives [v-model, v-bind], attributs calculés, formulaire de saisie</h4>
          </b-alert>
        </b-col>
      </b-row>
      <Form />
    </b-card>
  </b-container>
</template>


<script>
  import Form from "./components/Form.vue";

  export default {
    name: "app",
    components: {
      Form
    }
  };
</script>

组件 [App.vue] 使用了新组件 [Form](第 12、19、24 行)。

6.3. 组件 [Form]

组件 [Form] 的代码如下:


<template>
  <div>
    <!-- 表单 -->
    <b-form>
      <!-- 表单元素 -->
      <b-row>
        <b-col cols="4">
          <b-card bg-variant="light">
            <b-form-group label="Nombre d'enfants à charge" label-for="enfants">
              <b-input type="text"
                       id="enfants"
                       placeholder="Indiquez votre nombre d'enfants"
                       v-model="enfants"
                       v-bind:state="enfantsValide" />
              <b-form-invalid-feedback :state="enfantsValide">Vous devez saisir un nombre positif ou nul</b-form-invalid-feedback>
            </b-form-group>
            <!-- 按钮 -->
            <b-button variant="primary" :disabled="formInvalide" @click="doSomething">Valider</b-button>
          </b-card>
        </b-col>
      </b-row>
    </b-form>
    <b-row class="mt-3">
      <b-col cols="4">
        <b-alert show variant="warning" align="center">
          <h4>enfants= {{enfants}}</h4>
        </b-alert>
      </b-col>
    </b-row>
  </div>
</template>

<!-- 脚本 -->
<script>
  export default {
    // 名称
    name: "Form",
    // 组件的静态属性
    data() {
      return {
        // 子元素数量
        enfants: ""
      };
    },

    // 计算属性
    computed: {
      // 属性 [formInvalide]
      formInvalide() {
        return !this.enfantsValide;
      },
      // 属性 [enfantsInvalide]
      enfantsValide() {
        return Boolean(this.enfants.match(/^\s*\d+\s*$/));
      }
    },
    // 方法
    methods: {
      doSomething() {
        // 在验证时已知子节点数量
        alert("Nombre d'enfants : " + this.enfants);
      }
    }
  };
</script>

视觉呈现

Image

Image

注释

  • 第 4-32 行:<b-form> 标签引入了一个 Bootstrap 表单;
  • 第 6 行:<b-row> 标签在表单中插入一行;
  • 第 7 行:<b-col cols=’4’> 标签引入了一列,该列占据 4 个 Bootstrap 列宽;
  • 第8行:标签 <b-card> [6] 引入了一个Bootstrap卡片,即一个带有边框的区域;
  • 第 9 行:<b-form-group> 标签引入了一组相互关联的表单元素。此处,文本(属性 [label][1] 与一个输入框(属性 [label-for])相关联。 [label-for] 的值即为输入框第 12 行字段 [id] 的值;
  • 第 10-14 行:<b-input> 标签 [2] 引入了一个输入框:
    • 第 10 行:[type=’text’] 表示可以在输入框中输入文本。 本可以使用 [min=’val1’ max=’val2’ step=’val3’] 作为约束条件,因为预期该区域包含多个子元素。此处采用 [type=’text’] 是为了演示如何验证输入的有效性;
    • 第 12 行:属性 [placeholder] [3] 用于在用户尚未输入内容时,在输入框中显示提示信息;
    • 第 13 行:指令 [v-model] 将输入值与组件第 42 行的属性 [enfants] 建立双向关联:
      • 当输入值发生变化时,[enfants]属性的值也会随之变化;
      • [enfants] 属性的值发生变化时,输入值也会随之变化,即 [2] 的内容发生变化;
      • 需要理解的关键点是,通过上述机制,当用户点击按钮 [Valider] [5] 时, 第42行的[enfants]属性的值即为在[2]中输入的值;
    • 第14行:指令[v-bind]建立了一条关联,一端是<b-input>标签的属性(此处为[state]),另一端是组件的属性(此处为[enfantsValide],位于第53行)。 [enfantsValide] 属性具有特殊性,因为它是一个返回该属性值的函数。此类属性被称为计算属性。计算属性位于组件的 [computed] 属性中(第 47 行)。 计算属性的使用方式与函数 [data] 中的静态属性相同:第 14 行不写 [v-bind:state=’enfantsValide()’],而是写 [v-bind:state=’enfantsValide’],且不带括号。 此外,仅通过阅读 [template] 无法区分计算属性与静态属性。为此,必须查看组件脚本的代码;
    • 第14行:属性[state]将确定输入值的有效/无效状态:如果[enfantsValide]返回值[true],则输入值被视为有效;否则视为无效。 上图截图展示了当函数 [enfantsValide] 返回值 [false] 时,组件 [b-input] 的状态;
    • 第 15 行:当 [2] 中的输入无效时,<b-form-invalid-feedback> 标签 [4] 会显示一条消息。 其属性 [:state=’enfantsValide’] 与第 14 行的属性 [v-bind:state=’enfantsValide’] 相同。可以省略指令 [v-bind],但必须保留符号 [:]。 因此,当属性 [enfantsValide] 的值为 [false] 时,会显示错误信息;
    • 第16行:<b-group> 元素组的结束;
    • 第18行:用于提交输入的按钮 [5]
      • 该按钮将显示为蓝色 [variant=’primary’]
      • [:disabled="formInvalide"]:属性 [disabled] 用于启用/禁用该按钮。该属性通过 v-bind 绑定至第 49 行的计算属性 [formInvalide]
      • [@click="doSomething"]:当用户点击该按钮时,将执行第59行的[doSomething]方法
    • 第 19-22 行:关闭所有已打开的标签;
    • 第23-29行:在[template]中插入新行。[class=’mt-3’]表示[margin (m) top (t) égale à 3 spacers]。[spacer]是Bootstrap的间距单元。 该类在上述截图中生成 [8] 的间距。若无此类,[7] 区域将紧贴 [1-6] 区域;
    • 第 24 行:占用 4 个 Bootstrap 列宽的列;
    • 第 25-27 行:一个 [warning] 提示框,显示静态属性 [enfants](第 42 行)的值。 由于该属性与输入框存在双向绑定,一旦用户修改输入框内容,提示框中显示的值也会随之改变;
    • 第 34-65 行:组件的代码 jS;
    • 第 42 行:组件的唯一静态属性;
    • 第 47-56 行:组件的计算属性;
    • 第 53-55 行:若输入为正整数(前后可带空格),则视为有效;
    • 第49-51行:若“子女数量”的输入有效,则表单被视为有效。通常,表单包含多个输入项,当所有输入均有效时,表单才被视为有效;
    • 第58-63行:响应组件事件的组件方法。此处仅有一个事件:按钮上的[click]事件。我们仅显示输入的值,以证明能够正常访问该值;

6.4. 项目运行

修改文件 [package.json] 并运行项目:

Image