【VUE组件】

VUE组件

自定义组件

这里我们主要使用局部注册,首先需要在components文件夹中创建vue组件,且<script>name即组件的名称:
在这里插入图片描述
然后在需要使用该组件的vue文件中执行:

  1. <script>中引入该组件;
  2. <compontents>中注册该组件;
  3. <template>中使用该组件;

在这里插入图片描述

另外需要注意的是:自定义组件的数据data必须是一个函数,重复使用的组件间的data是相互独立的。

data: function () {
  return {
    count: 0
  }
}

组件单向数据流

将父组件中的数据传入到子组件中去,这时候我们需要使用props属性,父子prop之间形成一个单向下行绑定:父级的prop的更新会流动到子组件中,反之则不行。

<template>
  <div id="app">
    <!-- 注意!title1 和 title2 是父组件的 data 中定义的数据,title 则是子组件中接收数据时的变量名 -->
    <HelloVue :title="title1"></HelloVue>
    <HelloVue :title="title2"></HelloVue>
  </div>
</template>

需要注意的是:在title前加冒号是因为后面的title1是一个变量,如果不加冒号,则认为后面的是一个字符串。

在子组件中使用props进行数据的接收,且props是一个数组:

<template>
  <div class="hello">
    <!-- 第二步:在页面上显示 title 的值,写法和显示 data 里定义的数据一样 -->
    <h1>{{ title }}</h1>
  </div>
</template>

<script>
  export default {
    name: 'HelloVue',
    // 第一步:在 prop 属性中接收 title
    props: ['title']
  };
</script>

另外如果需要知道传入数据的数据类型,则需要这么使用(类型首字母大写):

props: {
  title: String,
  // 多类型
  likes: [String, Number],
  // 带有默认值
  isPublished: {
    type: Boolean,
    default: true
  },
  // 必填
  commentIds: {
    type: Array,
    required: true
  },
  author: Object,
  callback: Function,
  contactsPromise: Promise
}

如果需要对传入的数据进行处理,则可以使用计算属性对数据进行处理;如果需要将传入的数据保存为本地数据,则可以这么使用:

props: ['initialTitle'],
data: function () {
  return {
    // 要读取 prop 里的 initialTitle,要在前面加 “this.”
    // 将传入的 initialTitle 作为本地属性 title 的初始值
    title: this.initialTitle
  }
}

事件修饰符

在自定义组件的根元素上监听一个原生事件和在html中原生标签上监听一个原生事件是有区别的,即在子组件和父组件的某个标签上分别都设置监听器时,只有子组件的监听器会生效,而父组件的监听器是不会生效的。
在App.vue(父)中:

<!-- 给自定义组件添加点击事件 print -->
<Article
  v-for="article in articleList"
  :key="article.title"
  :article="article"
  @click="print(article)"
></Article>

在Article.vue(子)中:

<div class="article-title" @click="printTitle">{{ article && article.title }}</div>

如果想要父组件中的监听器也生效则需要使用修饰符:.native

<Article
  v-for="article in articleList"
  :key="article.title"
  :article="article"
  @click.native="print(article)"

></Article>

也可改为按键修饰符:@keyup.enter即回车键监听

自定义事件

我们不能在子组件中直接修改props中传入的数据,如果需要修改父组件中的数据,则需要给子组件绑定自定义事件,其功能主要有两个,一是在子组件中调用父组件中的方法;二是把子组件中的数据以参数的方式传入父组件。

  1. 在App.vue(父)中:
<!-- 自定义事件 upVote,调用该事件时会执行 handleLikes 方法 -->
<article
  v-for="article in articleList"
  :key="article.title"
  :article="article"
  v-on:upVote="handleLikes"
></article>
  1. 在Article.vue(子)中:
<!-- 在 template 中直接调用自定义事件 upVote -->
<button @click="$emit('upVote', this.article)">点赞</button>

<!-- 如果需要在调用事件的同时进行其他相关操作 -->
<button @click="childEvent">点赞</button>
methods: {
  childEvent: function() {
    // 调用自定义事件 upVote
    this.$emit('upVote', this.article);
    // do other things
  }
}
自定义事件的参数

在App.vue(父)中的方法,其中需要传入参数,但是在绑定自定义事件时并没有传入参数:

// 在 `methods` 对象中定义方法
methods: {
  handleLikes(article) {
    article.likes++
  }
}

在Article.vue(子)中,调用自定义事件upVote时会把参数传入:

methods: {
  childEvent: function() {
    // 调用自定义事件 upVote,这里的第二个参数最后会传到父组件中的 handleLikes 方法里
    this.$emit('upVote', this.article);
    // do other things
  }
}
自定义事件的双向绑定

使用修饰符.sync使某个属性在子组件与父组件之间完成双向绑定,在App.vue(父)中:

<MyCount class="count" :count.sync="count"></MyCount>

// 在 `methods` 对象中定义方法
data: function() {
  return {
    count: 0
  }
}

在Article.vue(子)中:

<div class="my-count">
  <button @click="$emit('update:count', count+1)">加一</button>
  {{ count }}
</div>

props: ['count'],

this.$emit('update:visible',false);可以直接改变 visible 的值。

组件函数的调用

调用子组件的方法
  1. 给子组件添加ref属性:
<template>
  <Modal ref="modal"></Modal>
</template>
  1. 在父组件中调用子组件的方法:
<script>
export default {
  methods: {
    showModal() {
      // 调用子组件中的 show 方法
      this.$refs.modal.show();
    }
  }
};
</script>
ref 访问子元素
<template>
  <div id="app">
    <input ref="input" type="text" />
    <button @click="focusInput">点击使输入框获取焦点</button>
  </div>
</template>

<script>
export default {
  name: 'app',
  methods: {
    focusInput() {
      // this.$refs.input 访问输入框元素,并调用 focus() 方法使其获取焦点
      this.$refs.input.focus();
    }
  }
}
</script>

组件 slot(插槽)

slot即一个插槽,相当于在子组件的DOM中留下一个位置,父组件如果有需要,则可以在插槽中添加任何内容。

slot 的基础使用
  1. 在子组件 Modal.vue 中添加插槽,标签中的内容是后备内容,可以为空,如果父组件不插入内容,则默认显示后备内容:
<div class="modal-content">
  <slot>这是个弹框</slot>
  <div class="footer">
    <button @click="close">close</button>
    <button @click="confirm">confirm</button>
  </div>
</div>
  1. 在父组件中使用子组件,并向插槽中添加内容:
<Modal :visible.sync="visible">这是添加在插槽中的内容</Modal>

除此之外还可以在父组件中为子组件添加类名,同时将类名的CSS代码书写在父组件中:

<Modal
      customClassName="textarea-modal"
      title="留言"
      :visible.sync="visible"
      @confirm="confirm"
    >
</Modal>

<style lang="scss">
.textarea-modal {
	//书写其CSS代码
}
</style>
<div :class="['modal', customClassName]" v-if="visible">
   <div class="modal-content">
      <div class="modal-header">
      </div>
      
      <div class="modal-body">
        <slot></slot>
      </div>
      
      <div class="modal-footer">
      </div>
  </div>
</div>
具名插槽

上面我们使用的都是“匿名插槽”,即<slot>标签没有加name属性,则默认为“default”。而如果我们需要在一个组件中插入多个插槽,则需要使用“具名插槽”。

  1. 首先在子组件中的<slot>标签上添加name属性:
<div class="modal" v-if="visible">
  <div class="modal-content">
    <header>
      <slot name="header"></slot>
    </header>
    
    <main>
      <slot></slot>
    </main>
    
    <footer>
      <slot name="footer"></slot>
    </footer>
  </div>
</div>
  1. 在父组件中使用子组件,并在<template>标签中使用v-slot指令,该指令的参数即其名称,如果不使用该方法则默认添加到“匿名插槽”中:
<Modal :visible.sync="visible">
  <template v-slot:header>
    <h1>Modal title</h1>
  </template>

  <div>main content</div>
  <div>main content</div>

  <template v-slot:footer>
    <p>Modal footer</p>
  </template>
</Modal>
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

帕特里克_海星

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值