【问题标题】:VueJS component display other component contentVueJS组件显示其他组件内容
【发布时间】:2020-09-16 16:48:01
【问题描述】:

目标:Vue 组件 input-address 必须在 Vue 组件 ma​​il-composer 中,并且只有在有人点击 通讯录时才显示地址列表/em> 按钮。当有人点击其中一封显示的邮件或手动填写 To 字段时,createdmail.to 必须获取该值,而我必须隐藏地址列表。

Vue 组件 ma​​il-composer。该组件接收地址列表。 (这里一切正常,我认为唯一不能正常工作的部分是 input-address 标签内的 v-model)

Vue.component('mail-composer', {
    props: ['addressesbook'],
    methods: {
      send: function(createmail) {
        this.$emit('send', createmail);
      }


    },
            template:
            `
            <div>
              <input-address :addresses="addressesbook" v-model="createmail.to"></input-address>
              <p><b>Subject: </b><input type="text" v-model="createmail.subject"></input></p>
              <p><b>Body: </b><textarea v-model="createmail.body"></textarea></p>
              <button @click="send(createmail)">Send</button>
            </div>
            `,
            data(){
              return{
                createmail:{
                  to: '',
                  subject: '',
                  body: ''
                }

              }
            }

      });

另一个 Vue 组件就是这个,它在同一个文件中。 (我认为所有的问题都在这里)。

只有当有人点击通讯录按钮时我才需要显示地址列表,当有人再次点击该按钮或列表中的一封电子邮件时我必须隐藏它。当有人单击列表中的邮件时,ma​​il-composer 中的 createmail.to 属性必须获取 mail 的值,如果我决定将邮件放在手它必须发生相同的情况。

Vue.component('input-address',{
        props:["addresses"],
        template:
        `
          <div>
          <label><b>To: </b><input type="text"></input><button @click="!(displayAddressBook)">Address Book</button></label>
          <ul v-if="displayAddressBook">
            <li  v-for="address in addresses">
            {{address}}
            </li>
          </ul>
          </div>
        `,
        data(){
          return{
            displayAddressBook: false
          }
        }


      })

【问题讨论】:

    标签: javascript html vue.js tags vue-component


    【解决方案1】:

    您的代码中有一些错误:

    • @click="!(displayAddressBook)" 应该是 @click="displayAddressBook = !displayAddressBook" - 第一个实际上什么都不做(有趣),第二个(建议)将 displayAddressBook 的值设置为当前的相反值。
    • input-address 组件实际上并没有对输入字段做任何事情(缺少v-model
    • 子组件 (input-address) 中的更改不会发送回父组件(在子组件中添加了 watcher 来执行此操作)
    • 父组件 (mail-composer) 必须处理子组件发出的值(添加了 @address-change 操作处理程序)
    • input-address 组件中的v-for 没有key 集。使用索引添加key(不是最好的解决方案,但很容易做到)。
    • 只需将createmail.to: {{ createmail.to }} 放在MailComposer 的末尾,这样您就可以看到它的变化

    建议

    • 始终使用 CamelCase 作为组件名称 - 如果您习惯了它,那么“为什么它不起作用?!”就更少了时刻
    • 注意拼写错误:createmail 看起来不太好 - createEmail 或者只是 createemail 会更好(好吧,它看起来不太好 - 也许你应该为此选择一个完全不同的名称)

    Vue.component('InputAddress', {
      props: ["addresses"],
      data() {
        return {
          displayAddressBook: false,
          address: null
        }
      },
      template: `
              <div>
              <label><b>To: </b>
                <input
                  type="text"
                  v-model="address"
                />
                <button
                  @click="displayAddressBook = !displayAddressBook"
                >
                  Address Book
                </button>
              </label>
              <ul v-if="displayAddressBook">
                <li
                  v-for="(address, i) in addresses"
                  :key="i"
                  @click="clickAddressHandler(address)"
                 >
                  {{address}}
                </li>
              </ul>
              </div>
            `,
      watch: {
        address(newVal) {
          // emitting value to parent on change of the address
          // data attribute
          this.$emit('address-change', newVal)
        }
      },
      methods: {
        clickAddressHandler(address) {
          // handling click on an address in the address book
          this.address = address
          this.displayAddressBook = false
        }
      }
    })
    
    Vue.component('MailComposer', {
      props: ['addressesbook'],
      data() {
        return {
          createmail: {
            to: '',
            subject: '',
            body: ''
          }
        }
      },
      methods: {
        send: function(createmail) {
          this.$emit('send', createmail);
        },
        addressChangeHandler(value) {
          this.createmail.to = value
        }
      },
      template: `
                <div>
                  <input-address
                    :addresses="addressesbook"
                    v-model="createmail.to"
                    @address-change="addressChangeHandler"
                  />
                  <p>
                    <b>Subject: </b>
                    <input
                      type="text"
                      v-model="createmail.subject"
                    />
                  </p>
                  <p>
                    <b>Body: </b>
                    <textarea v-model="createmail.body"></textarea>
                  </p>
                  <button @click="send(createmail)">Send</button><br />
                  createmail.to: {{ createmail.to }}
                </div>
                `
    });
    
    new Vue({
      el: "#app",
      data: {
        addressesbook: [
          'abcd@abcd.com',
          'fghi@fghi.com'
        ]
      }
    })
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
    <div id="app">
      <mail-composer :addressesbook="addressesbook" />
    </div>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-11-17
      • 1970-01-01
      • 1970-01-01
      • 2021-07-08
      • 2019-05-28
      • 2019-08-01
      • 2019-05-21
      • 1970-01-01
      相关资源
      最近更新 更多