表单和$listener

v-model:  双向数据绑定语法糖:1.input标签的值根据data里的name确定,所以用:value='name',  2.input标签的值变化,会修改name值,用input事件

<template>
  <div class="son-container">
    name:
    <!-- <input
      type="text"
      :value="name"
      @input="name = $event.target.value"
      placeholder="请输入名字"
    /> -->
       <input
      type="text"
      v-model="name"
      placeholder="请输入名字"
    />
    <button @click="changename">changename</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      name: '',
    };
  },
  methods: {
    changename() {
      this.name = '张三';
    },
  },
  watch: {
    name(val) {
      console.log(val);
    },
  },
};
</script>

单选框 /复选框: :在<input>上写v-model,  v-model的值等于value,就会选中;

 <p>
      sex:
      <input type="radio" v-model="sex" value="man" /> 
      <input type="radio" v-model="sex" value="femal" />
    </p>
    <p>
      爱好:
      <input type="checkbox" v-model="loves" value="football" />football 
      <input type="checkbox" v-model="loves" value="basketball" />basketball
      <input type="checkbox" v-model="loves" value="pingpang" />pingpang
    </p>

loves是数组

选择框: 单选复选都写在select上;

<p>
      家乡:
      <select name="province" v-model="provice">
        <option disabled value="">请选择家乡</option>
        <option value="北京">北京</option>
        <option value="天津">天津</option>
        <option value="河北">河北</option>
      </select>
    </p>
    <p>
      家乡:
      <select name="provinces" v-model="loveProvices" multiple>
        <option disabled value="">请选择喜欢的城市</option>
        <option value="北京">北京</option>
        <option value="天津">天津</option>
        <option value="河北">河北</option>
      </select>
    </p>

provinces是数组;

$listeners: 父组件传给子组件的事件函数;

//父组件中
<template>
  <div class="father-container">
    <Son @submit='sendMessage' />
  </div>
</template>

子组件中的$listeners就是submit,可以在子组件中调用父组件的这个函数。

这个函数也可以用props传值传过来,

也可以用$emit来触发。

v-model修饰符:

  • .numver
  • .lazy
  • .trim

多重事件传递

comment组件引用了messageArea组件,messageArea组件引用了formdata组件;messageArea组件是公共组件,具体怎么发送ajax,它不知道,必须由引入它的父组件来决定,这就造成了formdata组件填写的数据,必须传给comment,应用事件传值,$emit触发父组件事件的形式,传递两次才可以。

在comment组件中

<template>
  <div class="comment-container">
    <MessageArea title="评论列表" :subtitle='`(${data.total})`' :list='data.rows' @submit='submitMessage'/>
  </div>
</template>
export default {
  components: {
    MessageArea,
  },
  methods: {
    async submitMessage(config, cb){//提交评论
       const res =  await postComment(config);
       cb(res);
    }
  },
  ...

在messageArea组件中

 <!-- 消息区域组件,用于文章详情页下的评论和消息页的消息留言 -->
<template>
  <div class="message-area-container">
    <!-- 表单组件 -->
    <!-- <DataForm v-on="{ submit: submit }" /> -->//第一种形式是v-on={事件属性名:函数,...}
    <DataForm v-on="$listeners" /> //第二种利用了$listeners正好是绑定的事件对象,{submit: fn}注意,这个fn是父元素的methods中的函数,不需要在本组件中的methods中写函数。
  </div>
</template>

import DataForm from './DataForm';
 
export default {
 
  // methods: {
  //   submit(config,cb){
  //     console.log(111);
  //     console.log(this.$listeners);
  //     this.$emit('submit',config,cb)
  //   }
  // },
  components: {
    DataForm,
  },

formdata

<template>
  <div class="data-form-container">
    <div class="nickname">
      <div>
        <input
          type="text"
          v-model.trim="nickname"
          placeholder="输入用户昵称"
          maxlength="10"
        />
        <span class="tip">{{ nickname.length + tip.nickname }}</span>
      </div>
...
    <div class="submit">
      <button :class="{ disabled: isSubmiting }" @click="submit">
        {{ isSubmiting ? '提交中...' : '提交' }}
      </button>
    </div>
  </div>
</template>
<script>
export default {
  data() {
    return {
      nickname: '',
      content: '',
     
  },
  methods: {
    submit() {
      if(this.nickname.length == 0){
        this.error.nickname = '昵称不能为空';
        return
      }
...      
      this.isSubmiting = true;
      this.$emit("submit",{
        content: this.content,
        nickname: this.nickname,
        blogId: this.$route.params.blogId 
      },(res)=>{
        this.isSubmiting = false;
        this.content = '';
        this.nickname = '';
        console.log(res);
      })
    },
  },
};
</script>
原文地址:https://www.cnblogs.com/dangdanghepingping/p/14825534.html