携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第2天,点击查看活动详情
组件基本使用
-
1.组件的本质就是一个自定义的html标签
- 默认的标签:只有html结构
- 组件 :html结构 + js业务 + css样式
-
2.一个组件相当于一个vue实例
- 组件的作用 : 盒子复用
-
3.在vue项目开发中,组件与页面的关系如下
- 页面 = 盒子 = 组件 = .vue文件 = html+css+js
组件三个组成部分
一个组件(.vue文件)由三个标签组成
<template>
标签,这里写组件的html结构注意点: 一个template只能有一个子元素,vue会自动把
<template>
里面的根元素作为当前组件(vue实例)的挂载点
<script>
标签,这里写组件的js代码注意点: 以前vue实例的代码写在 export default { } 里面。 它的本质是一个ES6模块化语法,作用就是让组件可以实现复用(导入导出到其他组件)
注意点 : 组件里面的data必须是一个函数, 这个函数返回值就是之前vue实例的data对象
<style>
标签,这里写组件的css代码
-
为什么组件中的data必须是一个函数呢?
<!-- 1.html标签: 放模板(html结构)
细节:组件中的最外层父元素只能有一个,不能添加两个平级父元素
正确: <div> <div></div> <div>
错误: <div></div> <div></div>
-->
<template>
<div>
<h1>Hello!</h1>
<div class="box">{{ msg }}</div>
<button @click="doClick">点我试试</button>
<local01></local01>
</div>
</template>
<!-- 2.js代码,写组件js业务逻 -->
<script>
export default {
//之前vue实例的代码写在这里:可以放data,methods,计算属性、侦听器等
//注意哟:组件里面的data是一个函数,返回值就是之前vue实例中的data对象
data(){
return{
msg:'我是dj'
}
},
methods: {
doClick(){
alert('我被点击了')
}
}
}
</script>
<!-- 3.css:写组件样式 -->
<style>
.box{
width: 100px;
height: 100px;
background-color: red;
}
</style>
注册局部组件
官方文档:cn.vuejs.org/v2/guide/co…
注册局部组件
1.导入局部组件 : 在scrip标签中导入
import 组件名 from '组件路径'
2.挂载组件 : 在export default里面写一个属性components
export default {
components: {
"标签名": 组件名
}
}
使用局部组件 : 像标签一样使用即可,组件可以理解为一个自定义标签
<组件名></组件名>
注册全局组件
官方文档:cn.vuejs.org/v2/guide/co…
注册全局组件 : 在main.js文件中
1.导入组件 import 组件名 from '组件文件路径'
2.注册全局组件 Vue.component('标签名', 组件名)
一旦注册全局组件之后,可以在任何组件直接使用,并且不需要导入和挂载
局部组件和全局组件区别:
-
局部组件 : 在哪里用就在哪里注册 (用一次,注册一次)
- 如果一个组件只在一两个页面用到,就可以局部注册(例如商品详情)
-
全局组件 : 在main.js中注册,任何地方都能直接使用 (注册一次,终生可用)
- 如果一个组件需要在很多个页面用到,就可以全局注册(例如,弹框、自定义按钮这些)
//1.导入vue框架
import Vue from 'vue'
//2.导入App.vue根组件
import App from './App.vue'
//3.控制台打印提示开关
Vue.config.productionTip = false
/* 注册全局组件 : 在main.js文件中
1.导入组件
import 组件名 from '组件文件路径'
2.注册全局组件
Vue.component('标签名', 组件名)
一旦注册全局组件之后,可以在任何组件直接使用,并且不需要导入和挂载
*/
//1.导入组件
import global from './components/global.vue'
//2.注册全局组件
//参数1 : 组件的id (id叫什么,自定义标签名就叫什么)
//参数2 : 组件
Vue.component('test', global)
//4.创建vue实例
new Vue({
//默认渲染App.vue组件(根组件)
render: h => h(App),
}).$mount('#app')//设置挂载点,相当于 el:'#app'
组件CSS作用域scoped属性介绍
- scoped属性官方文档:scoped
- 关于scoped介绍: 为组件设置Scoped必要
<style scoped>
/*
1.默认情况下,如果父组件与子组件有相同的css选择器样式,则父组件的样式会覆盖子组件的样式
2.scoped属性作用 : 如果子组件与父组件有相同样式,则优先加载子组件自身的。如果没有则加载父组件的
*/
/* css */
.box{
width: 100px;
height: 100px;
background-color: blue;
}
</style>
组件的name属性介绍
官方文档:cn.vuejs.org/v2/api/#nam…
name属性的作用是给这个组件一个标识符,用于快速查找组件
-
关于name属性更多的作用,将会在后面项目课程有更多的了解
-
-
name属性的作用是给这个组件一个标识符,用于快速查找组件
- 关于name属性更多的作用,将会在后面项目课程有更多的了解
-
name属性特点
- a. 必须是唯一,不能与其他组件name属性冲突
- 建议最好与组件名一致
- b.name属性值不能是中文
vue组件传值
准备工作(新建两个组件, 一个父组件,一个子组件)
- App.vue (父组件)
- goods.vue (子组件)
父组件传值子组件:props
官网文档:cn.vuejs.org/v2/guide/co…
使用步骤
第一步:给子组件添加props属性(与data平级)
作用:类似于声明变量,定义要接收的属性名
第二组:在父组件中使用行内自定义 attribute传值 <子组件 属性名="属性值"></子组件>
注意点: prop中的属性不能有大写字母,不要使用驼峰命名。建议使用-
作为分隔符。
原因:行内自定义属性attribute不支持大写
单向数据流
-
1.单向数据流: vue规定,
父组件
传递给子组件
的数据是只读的
.- 简单说就是:当数据是从父组件的属性中传递过来的时候,子组件不要直接去修改。
-
2.单向数据流原因: 子组件修改了
父组件传递过来的数据
,不会通知父组件。就会造成数据不统一
问题 -
3.细节:
引用类型赋值本质是赋值地址
,一但修改互相影响,非常不便于维护
子组件:给按钮绑定一个事件,去修改价格。发现vue会报错。并且就算修改了子组件的数据,父组件的数据还是不变
,就会造成数据不统一
的问题
子组件传递数据给父组件:$emit
子组件不能直接修改父组件中的数据,但是可以通过emit
来通知父组件修改
1.监听子组件事件:cn.vuejs.org/v2/guide/co…
2.$emit用法:cn.vuejs.org/v2/api/#vm-…
3.使用事件抛出一个值:cn.vuejs.org/v2/guide/co…
使用步骤
-
1.子组件中发出通知:
this.$emit('事件名',参数)
-
2.父组件中接收通知:
<子组件 @事件名="函数名"></子组件>
- 父组件中的事件名要与子组件$emit中的事件名一致
-
3.在父组件的
methods
中实现这个事件处理函数- 一定要搞清楚
事件名
与事件处理函数
区别。别蒙圈了,多屡屡。
- 一定要搞清楚
-
本质:自定义事件
父子组件传值总结
-
父传子: 使用props
- 单向数据流
-
子传父: 使用$emit
- 事件监听