使用组件三大步骤
定义组件(创建组件)
使用 Vue.extend(options)创建,options 中无 el,因为最终所有的组件都要经过一个 vm 的管理,由 vm 中的 el 决定服务于哪个容器,此外 data 必须写成函数,以避免组件被复用时,数据存在引用关系
注册组件
- 局部注册:new Vue({componts})
- 全局注册:Vue.component('组件名',组件)
使用组件
<my-component></my-component>
一些注意点
组件名
- 一个单词组成:school 或者 School
- 多个单词组成:my-school 或者 MySchool (需要手脚架支持)
- 回避 HTML 已有元素,h2 或者 H2 都不可以
- 可以使用 name 配置项指定组件在开发者工具中呈现的名字
组件标签
- 写法 1:
<myc></myc>
- 写法 2:
<myc/>
不使用手脚架时,写法 2 会导致后续组件不能渲染
一个简写方式
const school = Vue.extend(options)
可以简写为 const school = options
关于 VueComponent
- school 组件本质是一个名为 VueComponent 的构造函数,且不是程序员定义的,是 Vue.extend 生成的
- 我们所写的
<school/>
在被 Vue 解析时,会帮我们创建该组件的实例对象,即 Vue 帮我们执行new VueComponent(options)
- 每次调用 Vue.extend,返回的都是一个全新的 VueComponent
- 关于 this 指向,在组件配置中,data 函数、methods 中的函数、watch 中的函数、computed 中的函数中的 this 都是VueComponent 实例对象
- 在 new Vue() 中,data 函数、methods 中的函数、watch 中的函数、computed 中的函数中的 this 都是 Vue 实例对象
第三点源码解析如下,每次返回的 Sub 都是方法内新生成的
Vue.extend = function(ops){
//...
var Sub = function VueComponent(ops){
this._init(ops);
};
//...
return Sub
};
ref 的使用
- 被用来给元素或子组件注册引用信息(id 的替代者)
- 在 html 标签上获取的是真实 DOM 元素,在组件标签上获取的是组件实例对象(vc)
<template>
<div id="app">
<img alt="Vue logo" src="./assets/logo.png">
<HelloWorld msg="Welcome to Your Vue.js App" ref="hello"/>
</div>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'
export default {
name: 'App',
components: {
HelloWorld
},
mounted() {
console.log(this.$refs.hello)
},
}
</script>
props 的使用
简单接受
props:['name','age'...]
限制类型
props:{
name:String,
age:Number
//...
}
完整配置
props: {
name: {
type: String,
required: true,
},
age: {
type: Number,
defalut: 18,
},
},
props 收到的属性不建议修改,可以通过在 data 内定义新的属性作为中间变量来修改。
例如:
myAge:this.age
,后续修改myAge
的值
mixin 使用
功能
把多个组件共用的配置提取成一个 mixin 对象(与 sass 类似)
使用方式
定义混合
{
data(){...}
methods:{...}
}
使用混合
- 全局:
Vue.mixin(xxx)
- 局部:
mixins:['xxx'...]
自定义事件
绑定
子组件向父组件通信,绑定自定义事件有两种方式:
//1
<Demo @myevent="test"/>
//2
<Demo ref="demo">
...
mounted(){
this.$refs.demo.$on('test',this.test)
}
触发
触发自定义事件:this.$emit('test',数据)
若只触发一次,可使用 once 修饰符或者 $once 方法
解绑
this.$off('test')
this.$off(['test1','test2'])
this.$off()//解绑所有
组件绑定原生事件
使用 native 修饰符即可
注意
通过 this.$refs.xxx.$on('test',回调)
绑定自定义事件时,回调要么配置在methods中,要么使用箭头函数,否则this指向会出现问题
全局事件总线(GlobalEventBus)
是一种组件通信方式,适用于任意组件间通信
安装全局事件总线
new Vue({
render: (h) => h(App),
beforeCreate() {
Vue.prototype.$bus = this;//安装全局事件总线
},
}).$mount("#app");
使用全局事件总线
接受数据的组件,则在该组件中给 $bus 绑定自定义事件,事件的回调留在组件自身
mounted() {
this.$bus.$on("hello", (data) => {
console.log("School", data);
});
},
beforeDestroy(){
this.$bus.$off()
}
提供数据的组件:this.$bus.$emit('xxx',data)
最好在 beforeDestroy 钩子中用 $off 解绑当前组件用到的事件
消息订阅与发布
一种组件间通信方式,适用于任意组件间通信
使用步骤
- 安装 pubsub:
npm i pubsub-js
- 引入:
import pubsub from "pubsub-js";
接收数据
mounted() { this.pubId = pubsub.subscribe("hello", (name, data) => { console.log("hello 消息发布了", data); }); }, beforeDestroy() { pubsub.unsubscribe(this.pubId); },
提供数据
sendStudentName() { pubsub.publish('hello',this.name) },