Skip to content

基础篇(三)

模板引用

访问模板引用的方式

html
<!-- 示例一 -->
<script setup>
import { ref, onMounted } from 'vue'

// 声明一个 ref 来存放该元素的引用
// 必须和模板里的 ref 同名
const input = ref(null)
</script>

<template>
  <input ref="input" />
</template>


<!-- 示例二
 在 v-for 中使用模板引用 
 ref 数组与源数组顺序并不一致
 -->
<script setup>
import { ref, onMounted } from 'vue'

const list = ref([
  /* ... */
])

const itemRefs = ref([])
</script>

<template>
  <ul>
    <li v-for="item in list" ref="itemRefs">
      {{ item }}
    </li>
  </ul>
</template>


<!-- 示例三:使用函数绑定,每次更新 / 卸载时都会执行函数,卸载时 el 为 null -->
<input :ref="(el) => { /* 将 el 赋值给一个数据属性或 ref 变量 */ }">


<!-- 示例四:组件 ref-->
<script setup>
import { ref, onMounted } from 'vue'
import Child from './Child.vue'

const child = ref(null)

onMounted(() => {
  // child.value 是 <Child /> 组件的实例
})
</script>

<template>
  <Child ref="child" />
</template>

使用模板引用访问子组件时,在选项式 API 中与子组件的 this 完全一致

在使用了 <script setup> 的组件内,所有属性 默认私有,无法直接访问,除非通过 defineExpose 宏显示暴露出去

html
<script setup>
import { ref } from 'vue'

const a = 1
const b = ref(2)

// 像 defineExpose 这样的编译器宏不需要导入
defineExpose({
  a,
  b
})
</script>

组件基础

一般会将 Vue 组件定义为一个 .vue 文件中,称之为单文件组件 —— SFC

html
<script setup>
import { ref } from 'vue'

const count = ref(0)
</script>

<template>
  <button @click="count++">You clicked me {{ count }} times.</button>
</template>

也可以通过导出 js 对象的方式定义组件

javascript
import { ref } from 'vue'

export default {
  setup() {
    const count = ref(0)
    return { count }
  },
  template: `
    <button @click="count++">
      You clicked me {{ count }} times.
    </button>`
  // 也可以针对一个 DOM 内联模板:
  // template: '#my-template-element'
}

传递 props

子组件中使用 defineProps 声明接受的 props

html
<!-- BlogPost.vue -->
<script setup>
const props = defineProps(['title'])
</script>

<template>
  <h4>{{ title }}</h4>
</template>

<!-- 父组件传值 -->
<BlogPost
  v-for="post in posts"
  :key="post.id"
  :title="post.title"
 />

监听事件

子组件通过 defineEmits 声明会抛出的事件

html
<!-- BlogPost.vue -->
<script setup>
const emit = defineEmits(['enlarge-text'])
// emit 等同于模板中的 $emit
</script>

<template>
  <div class="blog-post">
    <h4>{{ title }}</h4>
    <button @click="$emit('enlarge-text')">Enlarge text</button>
  </div>
</template>

<!-- 父组件接收事件 -->
<BlogPost
  ...
  @enlarge-text="handler"
 />

插槽

子组件使用 slot 接收父组件传递的内容

html
<AlertBox>
  Something bad happened.
</AlertBox>

<!-- AlertBox.vue -->
<template>
  <div class="alert-box">
    <strong>This is an Error for Demo Purposes</strong>
    <slot />
  </div>
</template>

动态组件

通过 <component> 元素配合 is attribute 实现动态组件

html
<!-- currentTab 改变时组件也改变 -->
<component :is="tabs[currentTab]"></component>

:is 可以是以下几种

  • 被注册的组件名
  • 导入的组件对象
  • 原生 HTML 元素

被切换掉的组件将会被卸载,但可以通过 <KeepAlive> 强制保持存活

DOM 内模板解析

注意事项如下:

  • 大小写区分
  • 闭合标签
  • 元素位置限制