导航
注意:
参数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"]
注意:
适用于当前路由中的两个非父子组件。不适用于切换路由后的两个组件(e.g. 在movie中监听,home中发广播。组件 movie 的视图不会被更新,因为 <router-view> 本质上实现了一个动态组件,当你导航到 /home 时被切换出去的组件 movie 实际上被销毁了,状态也就没有了。再切换回来,组件 movie 的实例重新被创建,msg 照常被赋为默认值。)
new Vue()
这样一个对象,来 $on('事件名', fn(prop1, prop2))// 封装 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...})
}
为了保证数据的单向流动,便于对数据进行追踪,避免数据混乱。官网有详细的信息 prop
所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外改变父级组件的状态,从而导致你的应用的数据流向难以理解。
设想一个场景,某个父组件下不只使用了一个子组件。而且都使用到了这份 prop 数据,那么一旦某个子组件更改了这个prop数据,会连带着其他子组件的prop数据也被更改。这会导致数据混乱,而且由于修改数据的源头不止一处,在出错后debug时难以定位错误原因。
所以我们需要将修改数据的源头统一为父组件,子组件想要改 prop 只能委托父组件帮它。从而保证数据修改源唯一
另外 props 传入的值如果对象的话,是可以直接在子组件里更改的,因为是同一个引用。
常见使用场景可以分为三类:
$emit
);通过父链 / 子链也可以通信( $parent
/ $children
);ref 也可以访问组件实例;provide / inject API; $attrs/$listeners
$attrs/$listeners