导航


HTML

CSS

JavaScript

浏览器 & 网络

版本管理

框架

构建工具

TypeScript

性能优化

软实力

算法

UI、组件库

Node

冷门技能

定义

全局定义

注意:

参数1:组件名称
参数2:组件模板对象
Vue.component('myLogin', {
  template: '<div><a href="#">登录</a> | <a href="#">注册</a></div>',
  data() {
    return {
      msg: '大家好!'
    }
  },
  methods:{
    login(){
      alert('点击了登录按钮');
    }
  }
});
// 使用
<my-login></my-login>

定义私有组件

export default {
  components: {
    login: {
      template: '<h1>我是个私有的login组件</h1>'
    }
  }
}

利用 v-if 和 v-else 切换组件

<input type="button" value="toggle" @click="flag=!flag">
<my-com1 v-if="flag"></my-com1>
<my-com2 v-else></my-com2>

data() {
	return {
  	flag: true
  }
}

⭐️ 动态组件

使用component标签,来引用组件,并通过:is属性来指定要加载的组件

<div id="app">
	<a href="#" @click.prevent="comName='login'">登录</a>
  <a href="#" @click.prevent="comName='register'">注册</a>
  <hr>
  <transition mode="out-in">
  <component :is="comName"></component>   <===comName就是组件名
  </transition>
 </div>

父子组件

import 子组件对象 from './components/xxx.vue';
{
	components: {
  	组件名: 子组件对象
  }
}

// 第一种用法 ===> 父组件声明子组件
// App.vue文件
<template>
	<div> <sw-header></sw-header> </div>
</template>

import Header from './components/Header.vue';
  
export default {
	components: {
  	'sw-header': Header,
  }
}
  
// 第二种用法 ===> main.js中全局引用和声明子组件,其他组件可直接使用
// main.js文件
import Header from './components/Header';
Vue.component('sw-header', Header);
new Vue({
    el: '#app',
    render(h) {
        return h(App);
    },
})
 
// App.vue中直接使用,不用引用和在components中声明
<div>
  <sw-header></sw-header>
</div>

⭐️ 父子组件传值

父组件给子组件传值

传值

// 子组件 subComp
<div>
  <h3>我是子组件,{{ parentmsg }}</h3>
</div>
export default {
	props: ['parentmsg']
}

// 父组件 superComp 把msg变量传递给 subComp
<sub-comp :parentmsg="msg"></sub-comp>

传方法

父组件向子组件传递方法,使用的是 事件绑定机制:v-on

// 子组件 subComp 调用父组件传递过来的方法,使用 $emit 触发的形式调用
mounted() {
    this.$emit("fathershow", "233", "777");
},

// 父组件向子组件传递方法
<sub-comp @fathershow="show"></sub-comp>
methods: {
    show(data1, data2) { 
      console.log("我是父组件app.vue方法show————"+data1 + data2);
    }
},

p.s. 如果把传递过去的参数替换为子组件内部的data数据,其实也就是实现了 子组件给父组件 传值

子组件主动获取父组件方法和数据

直接在子组件中调用:
this.$parent.数据
this.$parent.方法

子组件向父组件传值

父组件主动获取子组件方法和数据

1. 调用子组件的时候定义一个ref
	 <v-header ref="header"></v-header>

2. 在父组件里面通过
   this.$refs.header.属性
   this.$refs.header.方法

原理:父组件将方法的引用,传递到子组件,子组件在内部调用父组件传递过来的方法,同时把要发送给父组件的数据,在调用方法的时候当作参数传递进去

// 父组件引用子组件并传方法
<son @func="getMsg"></son>
methods: {
	getMsg(data) { console.log("我是子组件传递给父组件的值:" + data); }
}

// 子组件
data() {
    return { msg: '我是子组件data中的msg' }
},
mounted() { this.$emit("func", this.msg); },
props: ["func"]

⭐️ 非父子组件间传值 EventBus

注意:

适用于当前路由中的两个非父子组件。不适用于切换路由后的两个组件(e.g. 在movie中监听,home中发广播。组件 movie 的视图不会被更新,因为 <router-view> 本质上实现了一个动态组件,当你导航到 /home 时被切换出去的组件 movie 实际上被销毁了,状态也就没有了。再切换回来,组件 movie 的实例重新被创建,msg 照常被赋为默认值。)

// 封装 vueEvent.js
import Vue from 'vue';
var VueEvent = new Vue();
export default VueEvent;

// 使用

// 广播者
import VueEvent from '../model/VueEvent.js';
methods: {
	emitNews() { VueEvent.$emit('to-news', this.msg) }
}

// 监听者
import VueEvent from '../model/VueEvent.js';
mounted() {
  VueEvent.$on('to-news', function(data) {...接收到了data...})
}

⭐️ 在 Vue 中,子组件为何不可以修改父组件传递的 Prop

为了保证数据的单向流动,便于对数据进行追踪,避免数据混乱。官网有详细的信息 prop

所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外改变父级组件的状态,从而导致你的应用的数据流向难以理解。

设想一个场景,某个父组件下不只使用了一个子组件。而且都使用到了这份 prop 数据,那么一旦某个子组件更改了这个prop数据,会连带着其他子组件的prop数据也被更改。这会导致数据混乱,而且由于修改数据的源头不止一处,在出错后debug时难以定位错误原因。

所以我们需要将修改数据的源头统一为父组件,子组件想要改 prop 只能委托父组件帮它。从而保证数据修改源唯一

另外 props 传入的值如果对象的话,是可以直接在子组件里更改的,因为是同一个引用。

总结Vue组件通信方式

Vue 组件间通信六种方式

常见使用场景可以分为三类: