1、常用的父传子,props
// 父组件内
<son-com :props-data="变量"></son-com>
// 子组件内
props: {
propsData:{
type: String,
default: '111'
}
}
// 两种写法
// 数组写法
props: ['count', 'userInfo', 'changeCount']
// 对象写法
props: { count: Number, userInfo: Object, changeCount: Function }
2、常用的子穿父,$emit
// 父组件内
<son-com @sonBtn="父组件内方法名"></son-com>
methods: {
父组件内方法名(子组件内调用方法的传参){}
}
// 子组件内
sonbtn() {
this.$emit('sonBtn', '传给父组件的参数')
}
3、常用的父子或者祖孙,provide和inject
provide和inject是vue提供的两个钩子,和data、methods是同级的。并且provide的书写形式和data一样。
- provide 钩子用来发送数据或方法。
- inject钩子用来接收数据或方法
//父组件
data () {
return {
pimsg: '我是父组件的值',
num: 99999
}
},
provide () {
return {
命名: this
}
},
//子组件
inject: ['命名']
4、父子组件,$ref,$refs
//父组件
<child ref="child"></child>
mounted () {
console.log(this.$refs.child.name); // '我是张三'
this.$refs.child.sayHello(); // 我是李四
}
//子组件
methods: {
sayHello () {
console.log('我是李四')
}
}
5、父子组件,parent、children
//父组件
<template>
<div class="hello_world">
<div>{{msg}}</div>
<child></child>
<button @click="change">点击改变子组件值</button>
</div>
</template>
<script>
import child from './child.vue'
export default {
components: { child },
data() {
return {
msg: 'abc'
}
},
methods: {
change() {
// 获取到子组件
this.$children[0].message = '李四'
}
}
}
</script>
//子组件
<template>
<div>
<span>{{message}}</span>
<p>获取父组件的值为: {{parentVal}}</p>
</div>
</template>
<script>
export default {
data() {
return {
message: '张三'
}
},
computed:{
parentVal(){
return this.$parent.msg;
}
}
}
</script>
通过 $parent 访问到的是上一级父组件的实例,可以使用 $root 来访问根组件的实例
在组件中使用$children拿到的是所有的子组件的实例,它是一个数组,并且是无序的
在根组件 #app 上拿 $parent 得到的是 new Vue()的实例,在这实例上再拿 $parent 得到的是undefined,而在最底层的子组件拿 $children 是个空数组
$children 的值是数组,而 $parent是个对象
6、全局事件总线
// 安装总线
new Vue({
beforeCreate() {
Vue.prototype.$bus = this; // 安装总线
}
}
// 发送数据 在发送数据的组件中,触发事件,传递参数
<button @click="$bus.$emit('receiveParams', 25)">传给组件参数</button>
// 接受数据 在接收数据的组件中,绑定事件,留下回调,接收参数
mounted() {
this.$bus.$on('receiveParams', this.receiveParams)
},
methods: {
receiveParams(params) {
console.log('接收到的参数', params);
}
}
7、父子组件间的数据同步
A:v-model
// 父组件中的子组件标签内绑定
<CustomInput v-model="keyword"> </CustomInput>
data() {
return {
keyword: "abc"
}
}
// 在子组件绑定value和input事件,留下回调触发回调
<input type="text" :value="value" @input="changeValue">
props: ['value'],
methods: {
changeValue(e) {
this.$emit('input', e.target.value);
}
}
注:
条件: 必须实现
1.绑定:value值
2.绑定@input事件
数据的流向:
\1. 通过:value把数据绑定给子组件
\2. 子组件中使用props接收父组件传过来的数据
\3. 修改数据,使用$emit触发自定义事件,把参数传递给父组件
\4. 父组件接收到数据之后,更新keyword的值
\5. keyword值更新之后,又重新通过:value传递给子组件
B:.sync
// 父组件中的子组件标签里props的属性名后面加.sync 绑定数据
<Child1 :msg.sync="string"></Child1>
----------------------------------------------------------------------------------------------------------
data() {
return {
string: "我爱你",
};
}
// 子组件触发的地方使用this.$emit('update:属性名', '改变的值')
<button @click="changeParentMsg">修改父组件传过来的数据</button>
-----------------------------------------------------------------------------------------------------------
props: ['msg'],
methods: {
changeParentMsg() {
this.$emit('update:msg', "666")
}
}
注:
条件: 必须实现
1.props在子组件标签的属性名后加.sync
2.修改时必须是update:属性名
数据的流向:
\1. 通过:msg把数据传给子组件
\2. 子组件修改数据,$emit 触发了事件把参数传给父组件,父组件修改数据
\3. 父组件更改msg,再通过 :msg 传给子组件
8、mixin 混入
// 组件中有公共提取的时候就需要用到mixin
// 首先创建一个mixin.js的文件,
// 暴露一个对象,这个对象就是vue的配置对象( Vue组件中能配置什么,这里就能配置什么 )
export default {
data() {
return {
};
},
computed: {
},
mounted() {
console.log("mixin的挂载");
},
methods: {
},
};
// 在需要混入的组件中,引入并配置
import Mixin from './mixin'
export default {
mixins: [Mixin], // 混入的配置项
}
注:
1.在mixin中配置的内容(内容包括但不限于数据,方法等),都可以混入到组件当中
2.如果在组件中有重复的内容,会发生覆盖,组件中的内容会覆盖混入的内容
3.钩子函数不会被覆盖,先执行mixin中的钩子,再执行组件中的钩子
9、vuex
多个组件依赖同一个数据的时候使用vuex,需npm i vuex
创建store.js
import Vue from "vue";
import Vuex from 'vuex';
Vue.use(Vuex);
export default new Vuex.Store({
state,
mutations,
actions,
getters,
modules //模块化
})
关联store,在main.js中
//暴露
import store from '@/store'
new Vue({
render: h => h(App),
store //关联
}).$mount('#app')
写法
state
$store.state.test.count //普通写法
...mapState({ // 辅助函数 - 往computed中映射
count: state => state.test.count
})
actions
$store.dispath('increment') //普通写法
//actions怎么写,mutaions就怎么写,只改一个地方dispath改成commit即可
...mapActions(['increment']) // 辅助函数 - 往methods中映射
getters
$store.getters.dblCount //普通写法
//辅助函数 - 往compouted中映射
...mapGetters(['dblCount'])
//命名空间
在store当中配置 namespaced: true //加了命名空间,每一个模块都是独立的
state和开启模块化的时候一样,mutations、actions、getters都多加了一层
state - 还是开启模块化的写法
actions
$store.dispatch('test/increment') //普通写法
...mapActions('test', ['increment']) //辅助函数
getters
$store.getters['test/dblCount'] //普通写法
...mapGetters('test', ['dblCount']) // 辅助函数