单文件组件
官网介绍:https://v3.cn.vuejs.org/guide/single-file-component.html
Vue 单文件组件(又名 *.vue 文件,缩写为 SFC)是一种特殊的文件格式,它允许 将 Vue 组件的模板、逻辑 与 样式封装在单个文件中。
每个 *.vue
文件由三种类型的顶层代码块组成:<template>
、<script>
与 <style>
-
<script>
部分是一个标准的 JavaScript 模块。它应该导出一个 Vue 组件定义作为其默认导出。 -
<template>
部分定义了组件的模板。 -
<style>
部分定义了与此组件关联的 CSS。
编译后的 SFC 是一个标准的 JavaScript(ES)模块——这意味着通过正确的构建配置,可以像模块一样导入 SFC:
import MyComponent from './MyComponent.vue'
export default {
components: {
MyComponent
}
}
使用组件的三步骤
新增组件
src\components\BlogView.vue
修改
src/App.vue
项目入口文件基本三步骤:import引入组件,components 声明组件,然后使用组件
- 显示结果
父组件通过slot给子组件插值
父组件通过props给子组件传值
在子组件中定义独立事件
父组件监听子组件事件
父组件与子组件v-model数据绑定
父组件中使用$ref获取子组件数据
完整代码
- 新增组件
src\components\BlogView.vue
<template>
<div>
<h3>标题:{{ title }} - 作者:{{ author.name }}</h3>
<span>
- 喜欢人数:{{ likes }} - 发布:{{ isPublished }} - commentIds:{{ commentIds }}
- 点赞数:{{ respect_num }} - <button @click="respect">赞一下</button>
</span>
<div v-if="advanced">
<button @click="$emit('enlargeText')"> 子组件向父组件传值1-放大字体</button>
-
<button @click="$emit('enlargeText2',0.01)"> 子组件向父组件传值2-放大字体</button>
- 评论:
<input
:value="modelValue"
@input="$emit('update:modelValue', $event.target.value)">
- 打分:
<input type="text"
:value="scoreValue"
@input="$emit('update:scoreValue', $event.target.value)">
</div>
<h4>
<slot>优秀的小鱼!</slot>
</h4>
</div>
</template>
<script>
export default {
name: "BlogView",
props: {
title: [String, Number], // 字符串类型或数值类型,最简单一种写法
author: { // 使用对象,定义type类型,required必填,default默认值等
type: Object,
required: true, // 必填的字符串
default() { // 对象或数组的默认值必须从一个工厂函数返回
return {name: "Cherish", sex: "Girl"}
}
},
likes: {type: Number, default: 100},
isPublished: Boolean,
commentIds: Array,
advanced: Boolean,
modelValue: String,
scoreValue: Number
},
emits: ["enlargeText", "enlargeText2","update:modelValue","update:scoreValue"],// 非必须
data() {
return {
respect_num: this.likes ? this.likes : 0
}
},
methods: {
respect() {
this.respect_num++
}
}
}
</script>
<style scoped>
</style>
- 修改使用组件
src\App.vue
:
<template>
<!-- 使用组件“BlogView”-->
<BlogView title="组件111" :author="author" is-published>好好学习,天天向上!</BlogView>
<hr>
<blog-view v-for="post in posts"
:key="post.id"
:title="post.title"
:author="post.author"
:likes="post.likes"
:is-published="post.isPublished"
:commentIds="post.commentIds"
advanced="true"
:style="{ fontSize: postFontSize + 'em' }"
@enlargeText="postFontSize += 0.1"
@enlargeText2="onEnlargeText"
:modelValue="commentText"
@update:modelValue="commentText = $event"
v-model:score-value="score"
ref="blog"
></blog-view>
<h4>弹幕:v-model与子组件绑定:
<span style="color: red">{{ commentText }}</span></h4>
<h4>打分:v-model与子组件绑定:
<span style="color: green">{{ score }}</span></h4>
<div>通过$ref获取组件:{{ tips }}</div>
<button @click="this.tips = this.$refs.blog">通过$ref获取组件</button>
</template>
<script>
import BlogView from "@/components/BlogView";// 引入组件
export default {
name: 'App',
components: {BlogView},// (声明)注册组件
data() {// 数据声明
return {
posts: [
{id: 1, title: "组件222", author: {name: "Peter", sex: "Girl"}, likes: 6, isPublished: true, commentIds: [1, 3]},
{id: 3, title: "默认作者", likes: 99, isPublished: false, commentIds: []}
],
postFontSize: 1,
commentText: "",
score: null,
tips: ""
}
},
methods: {
onEnlargeText(enlargeAmount) {
this.postFontSize += enlargeAmount
}
}
}
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。