一、自定义事件实现验证抛出事件

我们写一个自定义事件、该事件旨在创建一个活动。假设我们的邮箱和密码是必填项。我们通过自定义事件在验证完邮箱和密码之后将form表单数据传递给父组件。

页面效果如下:

验证事件.png

<custom-form @submit="submitData"></custom-form>

我们最终想要的效果是想要在数据验证通过在父组件中调用submitData方法,从而进行提交。
现在我们把焦点聚焦在custom-form组件中。以下是custom-form组件的详细实现代码:

<template>
  <el-form ref="form" :model="form" label-width="80px">
    <el-form-item label="活动名称">
      <el-input v-model="form.name"></el-input>
    </el-form-item>
    <el-form-item label="邮箱">
      <el-input v-model="form.email"></el-input>
    </el-form-item>
    <el-form-item label="密码">
      <el-input type="password" v-model="form.password"></el-input>
    </el-form-item>
    <el-form-item label="活动区域">
      <el-select v-model="form.region" placeholder="请选择活动区域">
        <el-option label="区域一" value="shanghai"></el-option>
        <el-option label="区域二" value="beijing"></el-option>
      </el-select>
    </el-form-item>
    <el-form-item label="活动时间">
      <el-col :span="11">
        <el-date-picker type="date" placeholder="选择日期" v-model="form.date1" style="width: 100%"></el-date-picker>
      </el-col>
      <el-col class="line" :span="2">-</el-col>
      <el-col :span="11">
        <el-time-picker placeholder="选择时间" v-model="form.date2" style="width: 100%"></el-time-picker>
      </el-col>
    </el-form-item>
    <el-form-item label="即时配送">
      <el-switch v-model="form.delivery"></el-switch>
    </el-form-item>

    <el-form-item label="活动性质">
      <el-checkbox-group v-model="form.type">
        <el-checkbox label="美食/餐厅线上活动" name="type"></el-checkbox>
        <el-checkbox label="地推活动" name="type"></el-checkbox>
        <el-checkbox label="线下主题活动" name="type"></el-checkbox>
        <el-checkbox label="单纯品牌曝光" name="type"></el-checkbox>
      </el-checkbox-group>
    </el-form-item>
    <el-form-item label="特殊资源">
      <el-radio-group v-model="form.resource">
        <el-radio label="线上品牌商赞助"></el-radio>
        <el-radio label="线下场地免费"></el-radio>
      </el-radio-group>
    </el-form-item>
    <el-form-item label="活动形式">
      <el-input type="textarea" v-model="form.desc"></el-input>
    </el-form-item>
    <el-form-item>
      <el-button type="primary" @click="submitForm(form.email, form.password)">立即创建</el-button>
      <el-button>取消</el-button>
    </el-form-item>
  </el-form>
</template>
<script>
  import { ElMessage } from 'element-plus'

  export default {
    data() {
      return {
        form: {
          name: '',
          region: '',
          date1: '',
          date2: '',
          delivery: false,
          type: [],
          resource: '',
          desc: '',
          email: 'xxx@163.com',
          password: '',
        },
      }
    },
    methods: {
      submitForm(email, password) {
        this.$emit('submit', { email, password })
      },
    },
    emits: {
      click: null,
      submit: ({ email, password }) => {
        if (email && password) {
          return true
        } else {
          ElMessage({
            message: 'Invalid submit event payload!',
            type: 'warning',
          })
          return false
        }
      },
    },
  }
</script>

我们使用email和password进行邮箱和密码输入值的绑定。同时在点击立即创建按钮时调用submit先进行数据校验。待数据校验通过以后,再将数据传递给父组件进行提交操作。

二、v-model参数

接下来我们实现组件上的 v-model 使用 modelValue 作为 prop 和 update:modelValue 作为事件来实现自定义组件v-model参数的配置与传递。页面效果如下:

v-model.png

我们在父组件中引入model-eimits组件,并将v-model参数title、region、type传给model-emits组件。

<model-emits v-model:title="title" v-model:region="region" v-model:type="type"></model-emits>

以下是model-emits组件的详细代码:

<template>
  <div style="margin: 20px"></div>
  <el-form label-width="80px" :model="formLabelAlign">
    <el-form-item label="活动标题">
      <input :value="title" @input="$emit('update:title', $event.target.value)" class="v-input" />
    </el-form-item>
    <el-form-item label="活动区域">
      <input :value="region" @input="$emit('update:region', $event.target.value)" class="v-input" />
    </el-form-item>
    <el-form-item label="活动形式">
      <input :value="type" @input="$emit('update:type', $event.target.value)" class="v-input" />
    </el-form-item>
  </el-form>
</template>
<script>
  export default {
    data() {
      return {
        formLabelAlign: {
          region: '',
          type: '',
        },
      }
    },
    props: {
      title: String,
      region: String,
      type: String,
    },
    emits: ['update:title', 'update:region', 'update:type'],
  }
</script>
<style scoped>
  .v-input {
    border: 1px solid #dcdfe6;
    height: 40px;
    line-height: 40px;
    outline: 0;
    padding: 0 15px;
    width: 100%;
    border-radius: 4px;
  }
</style>

以上我们通过emits自定义update:title、update:region、update:type事件在实现v-model参数的动态变化。

三、v-model修饰符

接下来我们用自定义事件实现v-model修饰符将输入的首字母自动转为大写。页面效果如下:

vModel.png

<model-modifier v-model:letter.capitalize="text"></model-modifier>

在父组件中引入v-model修饰符组件model-modifier,从而用自定义事件实现letter的首字母自动转为大写效果。以下是model-modifier的详细代码:

<template>
  <div style="margin: 20px"></div>
  <el-form label-width="80px">
    <el-form-item label="字母">
      <input :value="letter" @input="emitValue" class="v-input" />
    </el-form-item>
  </el-form>
</template>
<script>
  export default {
    props: {
      letter: String,
      letterModifiers: {
        default: () => ({}),
      },
    },
    emits: ['update:letter'],
    methods: {
      emitValue(e) {
        let value = e.target.value
        if (this.letterModifiers.capitalize) {
          value = value.charAt(0).toUpperCase() + value.slice(1)
        }
        this.$emit('update:letter', value)
      },
    },
    created: function () {
      console.log(this.letterModifiers)
    },
  }
</script>
<style scoped>
  .v-input {
    border: 1px solid #dcdfe6;
    height: 40px;
    line-height: 40px;
    outline: 0;
    padding: 0 15px;
    width: 100%;
    border-radius: 4px;
  }
</style>

通过letterModifiers判断是否需要修饰符,在触发input事件时进行首字母的转换,并触发自定义事件update:letter将处理后的数据传递给父组件letter变量。

以上是关于自定义事件的实际使用场景,希望能帮到您!


high-profile
29 声望2 粉丝

下一篇 »
Vue3.0 teleport