1、props + $ emit
适用于父子组件子组件使用;
props 接收来自父组件的数据父组件绑定, v-on:事件名 监听事件, 子组件使用 this.$emit(‘事件名’) 派发事件;
缺点:如果组件嵌套的比较深就比较麻烦;
// Parent.vue
<div class="parent">
<Child :num="num" @addNum="handleAddNumber"></Child>
</div>
<script>
import Child from './Child.vue'
export default {
name: 'parent',
components: {
Child
},
data() {
return {
num: 1
}
},
methods: {
handleAddNumber(n) {
this.num += n
}
}
}
</script>
// Child.vue 组件
<div class="child">
<div @click="increamentNum">{{num}}</div>
</div>
<script>
export default {
name: 'child',
methods: {
increamentNum() {
this.$emit('addNum', 3)
}
}
}
</script>
2、.sync 修饰符
当子组件改变一个 prop 时,这个变化也会同步到父组件中的绑定。这个有点类似于 v-model 的功能;
.sync.prop=“newProp” 是 :prop 和 @update:prop=“val => newProp = val” 的语法糖,当 prop 改变时,会触发一个更新事件(this.$emit(‘update:prop’, newValue))
// parent.vue
<div>
<p>{{num}}</p>
<Child :n.sync="num"></Child>
</div>
export default{
name: 'parent',
data(){
return {
num: 1111
}
}
}
// child.vue
<div>
<p>{{n}}</p>
<button @click="addN">n + 1</button>
</div>
export default{
props: {
n: Number
},
methods: {
addN() {
this.n += 1
this.$emit('update:n', this.n)
}
}
}
3、vuex: 状态管理器
优点:响应式、可以实现项目中所有共享状态的管理;
缺点:适用于大型复杂的状态管理,如果太小型就有点多余了;
// main.js 入口文件
import Vue from 'vue'
import App from './App.vue'
import store from './store.js'
new Vue({
el: '#app',
store,
render: h => h(App)
})
// store.js
import Vuex from 'vuex'
export const store = new Vuex.Store({
state: {
num: 1,
userArr: [{id: 1}, {id: 2}]
},
getters: {
a: (state, getters) => {
return state.num + 'aaa'
},
userId: (state) => (id) => {
return state.userArr.find(item.id === id)
}
},
mutions: {
ADD_NUM(state, payload) { // payload 为传递进来的数据 ,可以通过 this.$store.commit('add', { n: 10 }) 触发该 mutions
state.num = state.num + payload.n
}
},
actions: {
addNum({commit, dsipatch}, payload) { // payload 为传递进来的数据 ,可以通过 this.$store.dispatch('addNum') 调用该 action
commit('ADD_NUM', { n: 10 })
}
},
modules: {
aaa: {
state: {},
getters: {},
mutions: {},
actions: {}
},
bb: {
state: {},
getters: {},
mutions: {},
actions: {}
}
}
})
4、inject & provide
适用于祖先关系的组件;
在后代组件中增加 inject 属性, 用来接收数据,可以是一个字符串数组,也可以是一个对象;
在祖先组件中使用 provide 属性存放要传递的数据;
优点:祖先组件不需要知道那些后代使用了这些属性,后代组件也不需要知道属性的来源是哪个祖先;
缺点:因为不知道属性的来源是哪里,所以很难进行追踪,后续维护困难;属性是非响应式的;
// 祖先组件
<div>
<Child></Child>
</div>
export default {
name: 'grandParent',
data() {
return {
name: 'bob',
age: 11,
num: 20
}
},
provide(){
return {
name: this.name,
age: this.age,
n: this.num
}
}
}
// 后代组件
<div>
{{name}} {{age}} {{n}}
</div>
export default{
name: 'child',
inject: ['name', 'age', 'n']
}
5、$ root $ parent $ children $ refs
通过 $ root 访问根实例 new Vue();
通过 $ parent 访问父组件的实例;
通过 $ children 访问 当前组件的直接子组件。注意获取的子组件没有顺序,非响应式;
通过 $ refs 访问 指定 ref 属性的实例: this.$ refs[‘tree’] 可以获取 < 标签名/组件名 ref=“tree” >…</ 标签名/组件名>。$refs 在组件渲染完后可以使用,非响应式;
6、event bus 事件总线(vue1.x 版本用的比较多,现在基本不使用)
使用一个空的 Vue 实例作为事件中心,用来派发和监听事件,实现各个组件(兄弟、父子、祖先、跨级不相干组件)的通信。非响应式
eventBus.js 文件
import Vue from 'vue'
export const eventBus = new Vue()
user.vue 组件
import eventBus from 'eventBus.js'
// 派发事件
eventBus.$emit('close', false)
role.vue 组件
import eventBus from 'eventBus.js'
// 监听事件
eventBus.$on('close', isTrue => {
console.log(isTrue)
})