VueJS组件显示其他组件内容

Posted

技术标签:

【中文标题】VueJS组件显示其他组件内容【英文标题】:VueJS component display other component content 【发布时间】: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
          
        


      )

【问题讨论】:

【参考方案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>

【讨论】:

以上是关于VueJS组件显示其他组件内容的主要内容,如果未能解决你的问题,请参考以下文章

测试包含我自己编写的其他组件的 VueJS 组件

使用 VueJS 中的插槽访问其他组件中的组件数据

单击按钮后隐藏组件(登录)并显示其他组件

即使移动到其他组件后,Router View 仍会继续显示组件信息

Vue 组件未在其他刀片中显示

Vuejs webpack 中 App.vue 与其他组件的关系