一、组件的三大组成部分
<template>
里面只能有一个根元素
<style>
全局样式(默认):影响所有组件
局部样式: scoped 下样式,只作用于当前组件
<script>
el根实例独有, data是一个函数,其他配置项一致
二、scoped设置局部样式
默认情况:写在组件中的样式会全局生效→因此很容易造成多个组件之间的样式冲突问题。
1.全局样式:默认组件中的样式会作用到全局
2.局部样式:可以给组件加上scoped属性,可以让样式只作用于当前组件
scoped原理?
1.当前组件内标签都被添加data-v-hash值的属性
2. css选择器都被添加[data-v-hash值]的属性选择器
最终效果:必须是当前组件的元素,才会有这个自定义属性,才会被这个样式作用到
三、data函数
一个组件的data选项必须是一个函数。→保证每个组件实例,维护独立的一份数据对象。
每次创建新的组件实例,都会新执行一次data函数,得到一个新对象。
组件内提供数据的是data函数,每个组件实例都会开辟新的一个空间存储这个数据,组件实例之间互不影响,也就是说data数据作用域只在组件实例范围内。
四、组件通信
组件关系:父子关系使用props&$emit
父传子props:
①父中给子添加属性传值②子props接收③使用
子传父$emit:
①子$emit发送消息②父中给子添加消息监听③父中实现处理函数
案例如下:父组件中有个数据myTitle传给子组件,子组件将数据接受并展示到页面上;子组件上加个按钮,按钮加个点击事件,点了以后会将通知和一个myTitle的新值传给父组件,父组件监听到通知后将myTitle更新。因为使用v-bind动态传递数据,父组件中数据更新,单向数据流,子组件接受的数据也更新并展示。
父组件代码
<template> <div class="App"> 父组件 <AlongHeader :title="myTitle" :hobby="hobby" @newTitle="newTitleFn"></AlongHeader> </div> </template> <script> import AlongHeader from './components/AlongHeader.vue' export default{ components:{ AlongHeader, }, data(){ return { myTitle:'阿龙学前端', hobby:['唱','跳','rap','篮球'] } }, methods:{ newTitleFn(newValue){ this.myTitle = newValue } } } </script> <style> .App{ border: 2px solid black; margin: 10px; } </style>View Code
子组件代码
<template> <div class="AlongHeader"> 子组件 {{title}} <button @click="changeTitle"></button> <p>{{hobby[0]}}、{{hobby[1]}}、{{hobby[2]}}、{{hobby[3]}}</p> </div> </template> 、 <script> export default{ props:['title','hobby'], methods:{ changeTitle(){ this.$emit('newTitle','好好学习') } } } </script> <style scoped> .AlongHeader{ border: 1px solid black; margin: 10px; } </style>View Code
prop
Prop定义:组件上注册的一些 自定义属性(结合v-bind成为动态属性)
Prop作用:向子组件传递数据
特点:
●可以传递任意数量的prop
●可以传递任意类型的prop
props校验
作用:为组件的prop指定验证要求,不符合要求,控制台就会有错误提示→帮助开发者,快速发现错误
语法
props:{ 校验的属性名:{ type:类型, required:true,//是否必填 default:默认值, validator(){ //自定义校验逻辑 return 是否通过校验 } } }
prop & data.单向数据流
共同点:都可以给组件提供数据。
区别:
●data 的数据是自己的→随便改
●prop 的数据是外部的→不能直接改, 要遵循单向数据流
单向数据流:父级prop的数据更新,会向下流动,影响子组件。这个数据流动是单向的。