组件化编程
1.单文件组件
一个 Vue 单文件组件 (SFC),通常使用 *.vue 作为文件扩展名,它是一种使用了类似 HTML 语法的自定义文件格式,用于定义 Vue 组件。一个 Vue 单文件组件在语法上是兼容 HTML 的。
每一个 *.vue 文件都由三种顶层语言块构成:<template>、<script> 和 <style>,以及一些其他的自定义块:
<template>
<div class="example">{{ msg }}</div>
</template>
<script>
export default {
data() {
return {
msg: 'Hello world!'
}
}
}
</script>
<style>
.example {
color: red;
}
</style>
<custom1>
This could be e.g. documentation for the component.
</custom1><template>:用于写Html结构,每个*.vue文件最多可以包含一个顶层<template>块。- 语块包裹的内容将会被提取、传递给
@vue/compiler-dom,预编译为 JavaScript 渲染函数,并附在导出的组件上作为其render选项。
- 语块包裹的内容将会被提取、传递给
<script>:用于写js语句,每个*.vue文件最多可以包含一个<script>块。(使用<script setup>的情况除外)- 这个脚本代码块将作为 ES 模块执行。
- 默认导出应该是 Vue 的组件选项对象,可以是一个对象字面量或是
defineComponent()函数的返回值。
<script setup>:每个*.vue文件最多可以包含一个<script setup>。(不包括一般的<script>)- 这个脚本块将被预处理为组件的
setup()函数,这意味着它将为每一个组件实例都执行。<script setup>中的顶层绑定都将自动暴露给模板
- 这个脚本块将被预处理为组件的
<style>:用于写css样式:每个*.vue文件可以包含多个<style>标签。- 一个
<style>标签可以使用scoped或moduleattribute (查看单文件组件样式功能了解更多细节) 来帮助封装当前组件的样式。使用了不同封装模式的多个<style>标签可以被混合入同一个组件。
- 一个
2.src导入
如果你更喜欢将 *.vue 组件分散到多个文件中,可以为一个语块使用 src 这个属性来导入一个外部文件:
<template src="./template.html"></template>
<style src="./style.css"></style>
<script src="./script.js"></script>请注意 src 导入和 JS 模块导入遵循相同的路径解析规则,这意味着:
- 相对路径需要以
./开头 - 你也可以从 npm 依赖中导入资源
<!-- 从所安装的 "todomvc-app-css" npm 包中导入一个文件 -->
<style src="todomvc-app-css/index.css" />src 导入对自定义语块也同样适用:
<unit-test src="./unit-test.js">
</unit-test>3.预处理器
代码块可以使用 lang 这个属性来声明预处理器语言,最常见的用例就是在 <script> 中使用 TypeScript:
<script lang="ts">
// use TypeScript
</script>也可以lang 在任意块上都能使用,比如我们可以在 <style> 标签中使用 Sass 或是 <template> 中使用 Pug:
<template lang="pug">
p {{ msg }}
</template>
<style lang="scss">
$primary-color: #333;
body {
color: $primary-color;
}
</style>4.普通组件
大部分组件都是普通组件
需要使用Es模块导入使用
<template>
<div>
<Child/>
</div>
</template>
<script setup>
import Child from './Child'
</script>5.全局组件
全局注册的组件,不需要导入就能直接使用,例如组件库中的组件
全局注册组件需要在main.js中使用app.component()方法注册,app.component()返回Vue实例,因此可以链式调用
import { createApp } from 'vue'
import myInput from './MyInput'
const app = createApp({})
app.component('MyInput', MyInput)
app.mount('#app')app.component()的参数:
- 第一个:全局注册的组件的名字
- 第二个:组件的内容
app.component()也可以注册一个局部组件,第二个参数为一个对象,其中写选项式Api
app.component('MyButton', {
data() {
return {
num: 111
}
},
template: `<button><slot></slot>{{num}}</button>`
})但是可能会报如下错误
Component provided template option but runtime compilation is not supported in this build of Vue.
解决办法需要在vite.config.js写如下配置
export default defineConfig({
plugins: [vue()],
resolve: {
alias: {
vue: 'vue/dist/vue.esm-bundler.js'
}
}
})6.动态组件
动态组件需要使用一个<component>标签,然后通过动态绑定一个is属性来指定组件
<template>
<div>
<button @click="changeTab">切换</button>
<component :is="tab"></component>
</div>
</template>
<script setup>
import {ref} from 'vue'
import Tab1 from './Tab1'
import Tab2 from './Tab2'
const tab=ref(Tab1)
const changeTab=()=>{
tab.value=Tab2
}
</script>这样可以通过一个tab变量,切换不同的组件
