3.Vue2.x组件(含组件注册使用、组件生命周期函数、组件之间的数据共享)
# 了解组件
vue 中规定:组件的后缀名是 .vue。因此,组件一般是以 .vue 后缀的,比如 App.vue 文件本质上就是一个 vue 的组件。组件化开发,根据封装的思想,把页面上可重用的 UI 结构封装为组件,从而方便项目的开发和维护。
1. 组件的组成
每个 .vue 组件都由 3 部分构成。提示:安装了相关的插件之后按control+<就可以自动生成基本骨架了。
<template>
</template>
<script>
export default {};
</script>
<style lang="less" scoped>
//支持less,scoped表示给每个标签加上属性
</style>
1.1 template节点
- template 是 vue 提供的容器标签,只起到包裹性质的作用,它不会被渲染为真正的 DOM 元素
- template 中只能包含唯一的根节点
1.2 script节点
<script>
//组件相关的data、methods等都要定义到 export default 导出的对象中
export default{ }
</script>
1.3 style节点
//支持less语法,scoped表示给本组件里的每个标签加上统一属性,防止样式冲突
<style lang="less" scoped>
</style>
# 组件的注册使用
1. 私有组件的注册使用
注:一般某个组件只被调用一两次的时候,可以选择注册私有组件。
查看代码
<template>
<!-- APP根组件 -->
<div class="app-container">
<!-- 渲染 Left 组件和 Right 组件 -->
<div class="box">
<!-- 3. 以标签形式,使用注册好的组件 -->
<Left> 这是left组件 </Left>
<Right> 这是right组件 </Right>
</div>
</div>
</template>
<script>
// 1. 导入需要使用的 .vue 组件
import Left from '@/components/Left.vue'
import Right from '@/components/Right.vue'
export default {
// 2. 使用 components 节点注册组件
components: {
Left,
Right,
}
}
</script>
2. 全局组件的注册使用
注:当某个组件被调用的次数多时,选择注册全局组件。
注册方式:
在 vue 项目的 main.js 入口文件中,通过 Vue.component() 方法,可以注册全局组件。示例代码如下代码第3点:
查看代码
// 1 导入 vue
import Vue from 'vue'
// 2 导入 App.vue 组件
import App from './App.vue'
// 3 导入需要被全局注册的那个组件
// Count 是需要注册的组件真实名称,MyCount是自定义名称
import Count from '@/components/Count.vue'
Vue.component('MyCount', Count)
Vue.config.productionTip = false
new Vue({
// render 函数中,渲染的是哪个 .vue 组件,那么这个组件就叫做 “根组件”
render: h => h(App)
}).$mount('#app')
使用方式:
依然是使用标签方式使用
查看代码
<template>
<!-- App 根组件 -->
<div class="app-container">
<div class="box">
<!-- 以标签形式,使用全局注册好的MyCount组件 -->
<MyCount></MyCount>
</div>
</div>
</template>
# 自定义属性props节点
注意:props是只读的,不可以动态修改。需要动态修改的自定义属性,可以将它“绑定”到data数据中,因为data中数据是可读写的。
props 是组件的自定义属性,在封装通用组件的时候,合理地使用 props 可以极大的提高组件的复用性! 它在props节点里定义,有两种语法格式。
1. 数组格式定义的自定义属性
数组格式定义有局限性,不可设置自定义属性的 默认值 和 数据类型
export default {
//组件的自定义属性
props:['自定义属性A','自定义属性B','自定义属性C',...]
}
使用:
1)如组件A(封装者)定义了自定义属性 init
<template>
<div class="left-container">
<p>{{ msg }}</p>
</div>
</template>
<script>
export default {
props: ['msg']
</script>
2)组件B(使用者)使用组件A,并自定义了A组件中的自定义属性 init
<template>
<div class="right-container">
<!--传字符串类型-->
<A msg="我自己来定义我自己的msg"> </A>
<!--传数字类型,需要配合v-bind使用-->
<A :msg="100"> </A>
</div>
</template>
2. 对象格式定义的自定义属性
对象格式定义有局限性,可以设置自定义属性的 默认值 和 数据类型【其使用同上】
export default {
//组件的自定义属性
props{
msg:{
default: '我是默认内容' //自定义属性msg的默认值
type: String //数据类型,有Number/Object/Array/Booleans等
required: true //调用时是否必须传递属性值
}
}
}
# 组件嵌套中样式冲突问题
//scoped表示给本组件里的每个标签加上统一属性,防止样式冲突(使样式在本组件中生效)
//但是不能够穿透样式(父组件不能给子组件设置样式)
<style lang="less" scoped>
//加上 /deep/ 的样式就可以穿透,父组件设置的样式可以在子组件中生效
/deep/ .title{
color:blue;
}
</style>
# 组件的生命周期&生命周期函数
生命周期(Life Cycle):指一个组件从 【创建 -> 运行 -> 销毁】 的整个阶段,强调的是一个时间段。
生命周期函数:是由 vue 框架提供的内置函数,会伴随着组件的生命周期,自动按次序执行。
created()生命周期函数示例:
查看代码
<script>
export default {
created() {
bus.$on('share', val => {
console.log('在 Right 组件中定义的 share 被触发了!', val)
this.msgFromLeft = val
})
}
}
</script>
# 组件之间的数据共享
在项目开发中,组件之间的关系分为两大类: 父子、兄弟。
【它们之间的数据共享,一定要时刻明白是数据的共享,弄清楚数据到底在谁那里。有时候本组件展示的数据不一定属于自己的数据】
1. 父->子 共享数据(自定义属性)
父组件向子组件共享数据使用 自定义属性 方式。步骤如下:
1.父组件传递信息:
查看代码
<template>
<div class="app-container">
//父组件在调用子组件Son的时候 顺便添加自定义属性
//属性内容就是父组件给子组件传递的内容
//加:就是传message下定义的内容,可以是字符串、方法、事件等等,这个例子传的是字符串和对象
//不加:的话,是传输message这个字符串本身
<Son :msg="message" :user="userinfo"></Son>
</div>
</template>
<script>
//导入子组件
import Son from '@/components/Son.vue'
export default {
data(){
return{
message:"我是父组件的信息",
userinfo:{name:'zs', age:20}
</script>
2.子组件接收信息:
查看代码
<template>
<div class="son-container">
<p>父组件传过来的 msg 的内容是:{{ msg }}</p>
<p>父组件传过来的 user 的内容是:{{ user }}</p>
</div>
</template>
<script>
export default {
//用来接收父组件传过来的信息
//自定义属性用props来接收
//props: ['msg', 'user']
props:{
msg:{
type:String, //类型
default:'默认值', //默认值
required:true //代表必须
},
user:{
type:Object, //类型
default:'默认值', //默认值
required:true //代表必须
}
</script>
2. 子->父 共享数据(自定义事件)
子向父组件共享数据通过 自定义事件 方式。步骤如下:
1.子组件传送信息,通过 $emit 方法发送:
查看代码
<template>
<div class="son-container">
<h3>Son 组件的 {{ count }} </h3>
<button @click="add">+1</button>
</div>
</template>
<script>
export default {
data() {
return {
// 子组件自己的数据,将来希望把 count 值传给父组件
count: 0,
}
},
methods: {
// 当触发 click 事件,就触发 add 方法
// 触发 add 方法,就触发 this.$emit 方法
// 触发 this.$emit 方法,就触发 numchange 这个自定义事件,
// 并把 this.count 作为实参传递给 父组件接收的 numchange 这个事件绑定的方法的形参
// 父组件的 numchange 事件绑定的 方法 通过参数可以拿到 this.count
add() {
// 让子组件的 count 值自增 +1
this.count += 1
// 把自增的结果,传给父组件,numchange 是自定义事件名称,this.count 是传输的数据
this.$emit('numchange', this.count)
}
}
}
</script>
2.父组件接收信息,通过 调用自定义事件 接收:
查看代码
<template>
<div class="app-container">
<h1>App 父组件 渲染子组件传过来的 {{ countFromSon }}</h1>
<!--渲染子组件的同时注册 自定义事件-->
<div class="son">
// 注册子组件传过来的自定义事件,给事件绑定getNewCount方法
// 子组件通过一系列操作触发了这个自定义事件,就会调用该函数
// 通过函数参数可以拿到传过来的内容
<Right @numchange="getNewCount"></Right>
</div>
</div>
</template>
<script>
import Son from '@/components/Son.vue'
export default {
data() {
return {
// 定义 countFromSon 来接收子组件传递过来的数据
countFromSon: 0
}
},
methods: {
// 获取子组件传递过来的数据
getNewCount(val) {
console.log('numchange 事件被触发了!', val)
//val就是子组件传过来的内容 this.count
this.countFromSon = val
}
},
}
</script>
3. 兄弟组件间 共享数据(EventBus)
在 vue2.x 中,兄弟组件之间数据共享的方案是 EventBus 。实际上,任何两个组件间都可以用这个方案。步骤如下:
1 创建 eventBus.js 模块,并向外共享一个 Vue 的实例对象
2 在数据发送方,调用 bus.$emit('事件名称', 要发送的数据) 方法触发自定义事件
3 在数据接收方,调用 bus.$on('事件名称', 事件处理函数) 方法注册一个自定义事件
1.创建中间C位角色 EventBus.js 文件,文件代码如下:
import Vue from 'vue'
export default new Vue()
2.兄弟自己A(数据发送方):
查看代码
<template>
<div class="a-container">
<button @click="send">把好诗发给傻 B 兄弟</button>
</div>
</template>
<script>
// 1. 导入 eventBus.js 模块
import bus from './eventBus.js'
export default {
data() {
return {
str: `栏杆拍遍,无人会,登临意!`
}
},
methods: {
// 触发 click 事件,即触发send()方法,进而触发 bus.$emit 方法
// bus.$emit 方法触发了就触发 share 这个 自定义事件
// 并把 this.str 作为实参传递给接收方 share 事件所绑定的函数的形参
send() {
// 2. 通过 eventBus 来发送数据
// share 是自定义事件名称,接下来给B兄弟调用的
bus.$emit('share', this.str)
}
}
}
</script>
3.兄弟自己B(数据接收方):
查看代码
<template>
<div class="b-container">
<p>{{ msgFromA }}</p>
</div>
</template>
<script>
// 1. 导入 eventBus.js 模块
import bus from './eventBus.js'
export default {
data() {
return {
// 用来存储B发过来的信息的
msgFromA: ''
}
},
created() {
// 2. 为 bus 绑定兄弟A组件的自定义事件 share
// A通过一系列操作,触发了 share 事件 val 拿到的就是传过来的东西了
bus.$on('share', val => {
console.log('在 A 组件中定义的 share 被触发了!', val)
this.msgFromA = val
})
}
}
</script>
本文来自博客园,作者:RHCHIK,转载请注明原文链接:https://www.cnblogs.com/suihung/p/16132058.html