Skip to content

5. 项目 [vuejs-03]:事件管理

项目 [vuejs-03] 引入了两个概念:

  • 按钮上的 [clic] 事件处理;
  • [v-if] 指令,用于条件显示 HTML 代码块;

该项目的目录结构如下:

Image

5.1. 主脚本 [main.js]

脚本 [main.js] 保持不变:


// 导入
import Vue from 'vue'
import App from './App.vue'

// 插件
import BootstrapVue from 'bootstrap-vue'
Vue.use(BootstrapVue);

// Bootstrap
import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap-vue/dist/bootstrap-vue.css'

// 配置
Vue.config.productionTip = false

// 项目实例化[App]
new Vue({
  render: h => h(App),
}).$mount('#应用程序')

5.2. 主组件 [App.vue]

主组件 [App.vue] 使用组件 [ClickOnMe] 代替组件 [HelloBootstrap]


<template>
  <b-container>
    <b-card>
    <!-- Bootstrap Jumbotron -->
    <b-jumbotron>
      <!-- 行 -->
      <b-row>
        <!-- 宽度为 4 的列 -->
        <b-col cols="4">
          <img src="./assets/logo.jpg" alt="Cerisier en fleurs" />
        </b-col>
        <!-- 宽度为 8 的列 -->
        <b-col cols="8">
          <h1>Calculez votre impôt</h1>
        </b-col>
      </b-row>
    </b-jumbotron>
    <!-- 组件 -->
    <ClickOnMe msg="Information..." />
    </b-card>
  </b-container>
</template>


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

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

5.3. 组件 [ClickOnMe]

组件 [ClickOnMe] 引入了新概念:


<template>
  <div>
    <!-- 绿色背景上的消息 -->
    <b-alert show variant="success" align="center">
      <h4>[vuejs-03] : événement @click, directive v-if, méthodes</h4>
    </b-alert>
    <!-- 黄色背景上的消息 -->
    <b-alert show variant="warning" align="center" v-if="show">
      <h4>{{msg}}</h4>
    </b-alert>
    <!-- 蓝色按钮 -->
    <b-button variant="primary" @click="changer">{{buttonTitle}}</b-button>
  </div>
</template>

<script>
  export default {
    name: "ClickOnMe",
    // 组件参数
    props: {
      msg: String
    },
    // 组件属性
    data() {
      return {
        // 按钮标题
        buttonTitle: "Cacher",
        // 控制消息显示
        show: true
      };
    },
    // 方法
    methods: {
      // 显示/隐藏消息
      changer() {
        if (this.show) {
          // 隐藏消息
          this.show = false;
          this.buttonTitle = "Montrer";
        } else {
          // 显示消息
          this.show = true;
          this.buttonTitle = "Cacher";
        }
      }
    }
  };
</script>

注释

  • 第 4-6 行:一个 Bootstrap 绿色提示。未指定占用的列数,因此默认使用 Bootstrap 的 12 列布局;
  • 第8-10行:一个Bootstrap黄色提示框:
    • 第 8 行:[v-if] 指令(源自 [Vue.js])控制 HTML 块的可见性。 此处的提示框由布尔值 [show](第 29 行)控制。若 [show==true] 为真,则提示框可见;否则不可见;
    • 第 9 行:该提示显示一条消息 [msg],该消息是组件的一个属性(第 20-22 行);
  • 第12行:一个蓝色按钮,点击可隐藏/显示[warning]警报;
  • 第16-48行:组件的代码jS。该代码控制组件的动态运行:
  • 第 20-22 行:组件的属性;
  • 第24-31行:组件的属性;

组件的 [propriétés][attributs] 之间有何区别?第 17-47 行中,组件导出的对象的 [props] 字段与 [data] 字段之间有何区别?

  • 正如我们之前所见,组件的 [props] 属性是组件的参数。其值由组件外部设定。 使用具有属性 [prop1, prop2, ..., propn] 的组件 B 的组件 A 将按以下方式使用它:<B :prop1=’val1’ :prop2=’val2’ ...>
  • 第24-31行中由函数[data]返回的对象代表组件的状态或属性。该状态通过组件的方法进行操作(第33-46行)。 第 1-14 行中的 <template> 同时使用了 [propriétés] [attributs] 元素:
    • 属性值由父组件设定;
    • 属性的值最初由函数 [data] 设定,随后可通过方法进行修改;
    • 在两种情况下,视觉呈现都会立即响应属性(父组件)或属性(组件方法)的变更。这被称为响应式界面

在组件的 [template] 中,[prop] 属性与 [data] 属性并无区别。 要判断 [template] 的动态数据应放入 [props] 属性中,还是放入由函数 [data] 返回的对象中,只需考虑谁确定了该数据的值:

  • 如果答案是父组件,则将该数据放入 [props] 属性中;
  • 如果答案是组件中处理该事件的方法,则将数据放入函数 [data] 返回的对象中;

此处的 [template] 使用了以下动态数据:

  • [show],第8行。该数据由方法[changer]在内部处理,该方法负责处理第12行按钮上的事件[click]。 因此,这是一个由函数 [data](第 29 行)构建的属性;
  • [msg],第 9 行。这是由父组件设定的消息。因此将其放入 [props] 属性中(第 21 行);
  • [buttonTitle],第12行。该数据由方法[changer]在内部处理,该方法负责处理第12行按钮上的事件[click]。 因此,这是一个由函数 [data](第 27 行)生成的属性;
  • 组件导出对象中 [name, props, data, methods] 属性的名称是预定义的。不能使用其他名称;
  • 第 12 行:按钮的 [@click] 属性用于指定响应按钮点击的操作方法。该方法必须位于组件的 [methods] 属性中;
  • 第 33 行:组件的 [methods] 属性汇集了该组件的所有方法。大多数情况下,这些是响应组件事件的函数;
  • 第 35-46 行:当用户点击按钮时,将调用方法 [changer]
    • 如果显示了 [warning] 提示框,则将其隐藏,且按钮文本变为 [Montrer](第 39 行);
    • 如果警报 [warning] 处于隐藏状态,则将其显示,且按钮文本变为 [Cacher](第 43 行);
    • 要显示/隐藏警报 [warning],需修改布尔值 [show] 的值(第 38 行和第 42 行);
    • 当某个方法需要引用由函数 [data] 返回的属性 [attr] 时,应写为 [this.attr](第 38 行和第 42 行)。 这意味着由函数 [data] 返回的对象的属性是组件 [this] 的直接属性;

5.4. 项目执行

Image

结果如下:

Image

Image