MENU

Vue组件相关笔记

July 5, 2022 • vue

使用组件三大步骤

定义组件(创建组件)

使用 Vue.extend(options)创建,options 中无 el,因为最终所有的组件都要经过一个 vm 的管理,由 vm 中的 el 决定服务于哪个容器,此外 data 必须写成函数,以避免组件被复用时,数据存在引用关系

注册组件

  1. 局部注册:new Vue({componts})
  2. 全局注册: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

  1. school 组件本质是一个名为 VueComponent 的构造函数,且不是程序员定义的,是 Vue.extend 生成的
  2. 我们所写的 <school/> 在被 Vue 解析时,会帮我们创建该组件的实例对象,即 Vue 帮我们执行 new VueComponent(options)
  3. 每次调用 Vue.extend,返回的都是一个全新的 VueComponent
  4. 关于 this 指向,在组件配置中,data 函数、methods 中的函数、watch 中的函数、computed 中的函数中的 this 都是VueComponent 实例对象
  5. new Vue() 中,data 函数、methods 中的函数、watch 中的函数、computed 中的函数中的 this 都是 Vue 实例对象

第三点源码解析如下,每次返回的 Sub 都是方法内新生成的

Vue.extend = function(ops){
    //...
    var Sub = function VueComponent(ops){
        this._init(ops);
    };
    //...
    return Sub
};

ref 的使用

  1. 被用来给元素或子组件注册引用信息(id 的替代者)
  2. 在 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:{...}
}

使用混合

  1. 全局:Vue.mixin(xxx)
  2. 局部: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 解绑当前组件用到的事件

消息订阅与发布

一种组件间通信方式,适用于任意组件间通信

使用步骤

  1. 安装 pubsub:npm i pubsub-js
  2. 引入:import pubsub from "pubsub-js";
  3. 接收数据

    mounted() {
        this.pubId = pubsub.subscribe("hello", (name, data) => {
          console.log("hello 消息发布了", data);
        });
      },
      beforeDestroy() {
        pubsub.unsubscribe(this.pubId);
      },
  4. 提供数据

    sendStudentName() {
          pubsub.publish('hello',this.name)
        },
Last Modified: July 7, 2022