组件最大的优势就是可复用性
通常将组件定义在.vue中,也就是SFC单文件组件
组件的基本组成:
<template>
<h3>基础标签</h3>
</template>
<script>
export default {
name: "MyComponent"
}
</script>
<!-- scoped 让当前样式只在当前组件中生效-->
<style scoped>
</style>
<template>
<!-- 第三步 显示组件-->
<MyComponent/>
<!-- 这样写法也可以-->
<my-component></my-component>
</template>
<script>
//第一步 引入组件
import MyComponent from './components/MyComponent.vue'
export default {
name: 'App',
//第二步 注入组件
components: {
MyComponent
}
}
</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>
组件允许我们将UI划分为独立的、可重用的部分,并且对每个部分单独思考
实际应用中组件常常被组件成层层嵌套的树状结构
Vue组件使用前要注册,注册有两种方式:全局注册和局部注册
全局注册在main.js中注册
import { createApp } from 'vue'
import App from './App.vue'
import MyComponent from "@/components/MyComponent";
const app=createApp(App)
/**
* 在这中间写app的组件注册
* 全局注册的问题:
* 1、组件不管是否使用 都要打包在JS中
* 2、全局在大型项目中使得项目依赖不明确,父组件中使用子组件时,不太容易定位子组件的实现,影响长期的可维护性
*/
app.component("MyComponent",MyComponent)
app.mount('#app')
局部注册按照之前的来就好了
组件之间不是完全独立的,而是有交集的,组件与组件之间可以传递数据
传递数据的解决方案就是props
<template>
<h3>{{title}}</h3>
<h3>{{demo}}</h3>
<!-- 动态传-->
<h3>{{message}}</h3>
<!-- 注意事项 props传递数据 只能从父传给子 不能方向传-->
</template>
<script>
export default {
name: "sonDemo",
props:["title","demo","message"]
}
</script>
<style scoped>
</style>
<template>
<Son title="Parent数据" demo="测试" :message="message"/>
</template>
<script>
import Son from "@/components/sonDemo";
export default {
name: "parentDemo",
components: {Son},
data(){
return{
message:"hello"
}
}
}
</script>
<style scoped>
</style>
props不仅仅可以传字符串 还可以传其他类型 例如数字、对象、数组
任何类型都可以用props传
<template>
<!-- 在这里传值 可以静态传值 也可以动态传值-->
<Son title="Parent数据" demo="测试" :message="message" :age="age" :names="names" :user="user"/>
</template>
<script>
import Son from "@/components/sonDemo";
export default {
name: "parentDemo",
components: {Son},
data(){
return{
message:"hello",
age:18,
names:["zhansgan","lisi"],
user:{
name:"hello",
age:20
}
}
}
}
</script>
<style scoped>
</style>
<template>
<h3>{{title}}</h3>
<h3>{{demo}}</h3>
<!-- 动态传-->
<h3>{{message}}</h3>
<button @click="clickAgain">click</button>
<!-- 注意事项 props传递数据 只能从父传给子 不能方向传-->
</template>
<script>
export default {
name: "sonDemo",
//接受传到的值
props:["title","demo","message","names","age","user"],
methods:{
clickAgain(){
console.log(this.names)
console.log(this.user)
}
}
}
</script>
<style scoped>
</style>
<template>
<!-- 在这里传值 可以静态传值 也可以动态传值-->
<Son title="Parent数据" demo="测试" :message="message" :age="age" :names="names" :user="user"/>
</template>
<script>
import Son from "@/components/sonDemo";
export default {
name: "parentDemo",
components: {Son},
data(){
return{
message:"hello",
age:18,
names:["zhansgan","lisi"],
user:{
name:"hello",
age:20
}
}
}
}
</script>
<style scoped>
</style>
<template>
<h3>{{title}}</h3>
<h3>{{demo}}</h3>
<!-- 动态传-->
<h3>{{message}}</h3>
<h3>{{age}}</h3>
<p v-for="(item,index) of names" v-bind:key="index">{{item}}</p>
<button @click="clickAgain">click</button>
<!-- 注意事项 props传递数据 只能从父传给子 不能方向传-->
<!-- 注意:prop是已读的 不可以修改-->
</template>
<script>
export default {
name: "sonDemo",
//接受传到的值
props: {
title:{
type:String,
//设置这是必选项
required:true
},
names:{
type:[String,Number,Array,Object],
//如果传的是个数组类型或对象类型 则需要通过工厂函数返回默认值
default(){
return ["1",'2']
}
},
age:{
type:Number,
//可以设置默认值
//数字和字符串可以直接default 如果传的是个数组类型或对象类型 则需要通过工厂函数返回默认值
default:0
},
user:{},
demo:{},
message:{}
},
methods:{
clickAgain(){
console.log(this.names)
console.log(this.user)
}
}
}
</script>
<style scoped>
</style>
组件的模板表达式中,可以直接用$emit方法触发自定义事件
触发自定义的目的是组件之间传递数据
<template>
<h3>组件事件</h3>
<son-demo @someEvent="getHandle"></son-demo>
<p>{{message}}</p>
</template>
<script>
import SonDemo from "@/components/sonDemo";
export default {
name: "parentDemo",
components: {SonDemo},
methods:{
getHandle(data){
console.log("触发了",data)
this.message=data
}
},
data(){
return{
message:""
}
}
}
</script>
<style scoped>
</style>
<template>
<h3>Child</h3>
<button @click="clickEventHandle">传递数据</button>
</template>
<!--组件之间传递数据的方案
1、父传子 props
2、子传父 自定义事件$emit
-->
<script>
export default {
name: "sonDemo",
methods:{
clickEventHandle(){
console.log("准备触发")
//自定义事件 还可以传参
this.$emit("someEvent",this.message)
}
},
data(){
return{
message:"child数据123"
}
}
}
</script>
<style scoped>
</style>