组件化开发介绍
-
1.组件本质:一个自定义的标签
-
普通标签:只有html结构
-
组件:有html结构,css样式,js业务逻辑
-
-
2.组件作用:
复用
-
把页面上
可重用的部分
封装为组件
,从而方便项目的 开发 和 维护 -
==一个组件相当于一个vue实例
组件三个组成部分
组件 == .vue文件(代码) == vue实例 (内存中) == 页面盒子(html+css+js一起) == 自定义html标签
一个组件(.vue文件)由三个标签组成
-
<template>标签,这里写组件的html结构
注意点: 一个template只能有一个子元素,vue会自动把<template>里面的根元素作为当前组件(vue实例)的挂载点
-
<script>标签,这里写组件的js代码
注意点: 以前vue实例的代码写在 export default { } 里面。 它的本质是一个ES6模块化语法,作用就是让组件可以实现复用(导入导出到其他组件)
注意点 : 组件里面的data必须是一个函数, 这个函数返回值就是之前vue实例的data对象
原因: 组件基础 — Vue.js
-
<style>标签,这里写组件的css代码
-
-
为什么组件中的data必须是一个函数呢?
-
1.
单文件组件
: 把每一个组件放到一个独立的文件里-
好处:(1)便于维护 (2)便于复用
-
之前的学习中,当一个页面非常复杂的时候,我们需要把所有的结构都写在一个html中,非常的不便于维护
-
vue提供了一个专业的工具来帮我们将每一个组件放到一个独立的文件中管理
-
-
-
2.组件文件的后缀名是
.vue
文件 -
3.这个
.vue
文件主要由三个部分组成-
template
-
这里写组件的HTML结构模板
-
-
script
-
这里写组件的js业务逻辑。组件中的data、methods、计算属性,声明周期钩子等都写在这里
-
-
style
-
这里写组件的css样式
-
-
-
4.小提示 : 快速生成组件三大部分的快捷键:
<vue>
-
App.vue代码参考
-
<!-- 1.html标签: 放模板(html结构) 细节:组件中的最外层父元素只能有一个,不能添加两个平级父元素 正确: <div> <div></div> <div> 错误: <div></div> <div></div> --> <template> <div class="box"> <h1>我是根组件</h1> </div> </template> <!-- 2.js代码,写组件js业务逻 --> <script> export default { //之前vue实例的代码写在这里:可以放data,methods,计算属性、侦听器等 //注意哟,组件里面的data是一个函数,返回值就是之前vue实例中的data对象 data(){ return{ msg:'我是坤坤!' } }, } </script> <!-- 3.css:写组件样式 --> <style> h1{ color: red } </style>
注册局部组件
-
官方文档:组件注册 — Vue.js
-
组件 == .vue文件 == vue实例 == 页面盒子(html+css+js一起) == 自定义html标签
组件名命名规范 : 在进行组件的注册时,定义组件名的方式有两种
官方文档:组件命名规范
(1) 短横线命名法,例如 hm-header 和 hm-main
使用时: <hm-button> </hm-button>
(2)大驼峰命名法(推荐),例如 HmHeader 和 HmMain
使用时
<HmButton> </HmButton>
和<hm-button> </hm-button>
都可以注意:组件名不能与原生的HTML标签重名,例如你的组件名不能是 button、div、等已存在的原生HTML标签
注册局部组件
1.导入局部组件 : 在scrip标签中导入
import 组件名 from '组件路径'
2.挂载组件 : 在export default里面写一个属性components
export default {
components: {
"标签名": 组件名
}
}
3.使用组件 : 像标签一样使用即可,组件可以理解为一个自定义标签
<组件名></组件名>
注册全局组件
-
官方文档:组件注册 — Vue.js
-
局部组件和全局组件区别
-
局部组件 : 在哪里用就在哪里注册 (用一次,注册一次)
-
如果一个组件只在一两个页面用到,就可以局部注册(例如商品详情)
-
-
全局组件 : 在main.js中注册,任何地方都能直接使用 (注册一次,终生可用)
-
如果一个组件需要在很多个页面用到,就可以全局注册(例如,弹框、自定义按钮这些)
-
-
-
/* 注册全局组件 : 在main.js文件中
1.导入组件 import 组件名 from '组件文件路径'
2.注册全局组件 Vue.component('标签名', 组件名)
3.一旦注册全局组件之后,可以在任何组件直接使用,并且不需要导入和挂载 */
组件CSS作用域scoped属性
-
-
scoped属性官方文档:scoped
-
关于scoped介绍: 为组件设置Scoped必要
-
scoped作用是什么?
-
专业术语: 子组件的css作用域
-
说人话: 避免子组件选择器样式被父组件覆盖
-
-
scoped原理是什么?
-
属性选择器
:本质是给子组件添加一个唯一的
行内自定义属性,然后通过[data-v-xxx]
属性选择器避免样式被父组件覆盖 -
组件的name属性介绍
-
官方文档:API — Vue.js
-
name属性的作用是给这个组件一个标识符,用于快速查找组件
-
关于name属性更多的作用,将会在后面项目课程有更多的了解
-
-
2.name属性特点
-
a. 必须是唯一,不能与其他组件name属性冲突
-
建议最好与组件名一致
-
-
b.name属性值不能是中文
-
-
组件通讯:父件子props
-
官网文档:组件基础 — Vue.js
使用步骤
第一步:给子组件添加props属性
(与data平级)
作用:类似于声明变量,定义要接收的属性名
第二组:在父组件中使用行内自定义 attribute传值
<子组件 属性名="属性值"></子组件>
注意点: prop中的属性不能有大写字母,不要使用驼峰命名。建议使用
-
作为分隔符。原因:行内自定义属性attribute不支持大写
子组件
<template>
<div class="son">
<h3>我是子组件</h3>
<!-- 使用props中的数据,就像使用data数据一样 -->
<h4>商品名称:{{ name }}</h4>
<h4>商品名称:{{ price }}</h4>
<h4>商品编号:{{ id }}</h4>
</div>
</template>
<script>
export default {
name:'goods',
//子组件中声明props
props:["name","price","id"],
data(){
return{
}
},
methods: {
},
}
</script>
<style scoped>
.son{
border: 1px solid red;
}
</style>
父组件
<template>
<div id="app">
<h1>我是父组件</h1>
<!-- 父组件:通过行内自定义属性 来 传递数据给 props -->
<goods name="苹果手机" price="5888" id="1"></goods>
<goods name="小米手机" price="1888" id="2"></goods>
</div>
</template>
<script>
//导入局部组件
import goods from './goods.vue'
export default {
data(){
return{
}
},
components:{
goods
}
}
</script>
<style>
#app{
border: 1px solid #000;
}
</style>
props类型验证
props 是父传子, 传递给子组件的数据, 为了提高 子组件被使用时 的稳定性, 可以进行props校验, 验证传递的数据是否符合要求
默认的数组形式, 不会进行校验, 如果希望校验, 需要提供对象形式的 props
风格指南:https://cn.vuejs.org/v2/style-guide/#Prop-%E5%AE%9A%E4%B9%89%E5%BF%85%E8%A6%81
props: { ... }
props 提供了多种数据验证方案,例如:
-
基础的类型检查 Number
-
多个可能的类型 [String, Number]
-
必填项校验 required: true
-
默认值 default: 100
-
自定义验证函数
官网语法: 地址
组件通讯:单向数据流
-
官方文档:Prop — Vue.js
-
1.单向数据流: vue规定,
父组件
传递给子组件
的数据是只读的
.-
说人话:当数据是从父组件的属性中传递过来的时候,子组件不要直接去修改。
-
-
2.单向数据流原因: 子组件修改了
父组件传递过来的数据
,不会通知父组件。就会造成数据不统一
问题 -
3.细节:
引用类型赋值本质是赋值地址
,如果在子组件修改则父组件也会变化。
-组件通讯:子传父$emit
子组件不能直接修改父组件中的数据,但是可以通过
emit
来通知父组件修改1.监听子组件事件:组件基础 — Vue.js
2.$emit用法:API — Vue.js
3.使用事件抛出一个值:组件基础 — Vue.js
-
使用步骤
-
1.子组件中发出通知:
this.$emit('事件名',事件对象)
-
2.父组件中接收通知:
<子组件 @事件名="函数名"></子组件>
-
父组件中的事件名要与子组件$emit中的事件名一致
-
-
3.在父组件的
methods
中实现这个事件处理函数-
一定要搞清楚
事件名
与事件处理函数
区别。别蒙圈了,多屡屡。
-
-
本质:自定义事件
-
-
子组件中通过哪个
方法
向父组件传递事件?-
this.$emit()
-
-
父组件注册的事件名需要和谁
对应
?-
子组件中$emit('事件名')
-
-