首页 >> js开发 >> js详解vue组件之间的通信js大全
js详解vue组件之间的通信js大全
发布时间: 2021年1月13日 | 浏览:
| 分类:js开发
说明:下面我总结了比较常用的vue组件之前通信的方式,最近准备面试,所以有些总结贴上来分享props和$emitprops和$emitprops和$emit只有父子关系才可以用这种方式,父组件向子组件传递参数用props,子向父传递使用触发$emit自定义事件1.props1.props
...
data () {
return {
name: 'marry'
}
}
post: {
id: 1,
title: 'My Journey with Vue'
}
//等价于下面
v-bind:id="post.id"
v-bind:title="post.title"
>
...
//以字符串数组形式列出的 prop
props: ['name', 'age', 'address']
//prop验证, 当 prop 验证失败的时候,(开发环境构建版本的) Vue 将会产生一个控制台的警告
//注意:以下类型不能写成'String'这种带引号的形式
props: {
// 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证)
propA: Number,
// 多个可能的类型
propB: [String, Number],
// 必填的字符串
propC: {
type: String,
required: true
},
// 带有默认值的数字
propD: {
type: Number,
default: 100
},
// 带有默认值的对象
propE: {
type: Object,
// 对象或数组默认值必须从一个工厂函数获取
default: function () {
return { message: 'hello' }
}
},
// 自定义验证函数
propF: {
validator: function (value) {
// 这个值必须匹配下列字符串中的一个
return ['success', 'warning', 'danger'].indexOf(value) !== -1
}
}
}
//注意那些 prop 会在一个组件实例创建之前进行验证,所以实例的 property (如 data、computed 等) 在 default 或 validator 函数中是不可用的。
...
data () {
return {
name: 'marry'
}
}
post: {
id: 1,
title: 'My Journey with Vue'
}
//等价于下面
v-bind:id="post.id"
v-bind:title="post.title"
>
...
//以字符串数组形式列出的 prop
props: ['name', 'age', 'address']
//prop验证, 当 prop 验证失败的时候,(开发环境构建版本的) Vue 将会产生一个控制台的警告
//注意:以下类型不能写成'String'这种带引号的形式
props: {
// 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证)
propA: Number,
// 多个可能的类型
propB: [String, Number],
// 必填的字符串
propC: {
type: String,
required: true
},
// 带有默认值的数字
propD: {
type: Number,
default: 100
},
// 带有默认值的对象
propE: {
type: Object,
// 对象或数组默认值必须从一个工厂函数获取
default: function () {
return { message: 'hello' }
}
},
// 自定义验证函数
propF: {
validator: function (value) {
// 这个值必须匹配下列字符串中的一个
return ['success', 'warning', 'danger'].indexOf(value) !== -1
}
}
}
//注意那些 prop 会在一个组件实例创建之前进行验证,所以实例的 property (如 data、computed 等) 在 default 或 validator 函数中是不可用的。2.$emit2.$emit
...
methods: {
myEvent(name){
this.name = name
}
}
//使用自定义事件将子组件的值抛给父组件
...
methods: {
myEvent(name){
this.name = name
}
}
//使用自定义事件将子组件的值抛给父组件中央事件总线 bus中央事件总线 bus中央事件总线 bus用于解决跨级和兄弟组件通信问题,巧妙的使用一个公共的vue实例,利用$on, $emit, $off(移除自定义事件监听器)方法一:方法一:可以在main.js中,在Vue的原型上挂载一个公共的Vue实例 $bus,这样全局任何一个地方都可以使用
Vue.prototype.$bus = new Vue()
Vue.prototype.$bus = new Vue()然后在需要的地方注册自定义事件和接收参数的回调函数
this.$bus.$on('changeName', name => {
this.name = name
})
this.$bus.$on('changeName', name => {
this.name = name
})在需要改变的时候触发事件并抛出参数
this.$bus.$emit('changeName', 'wzj')
this.$bus.$emit('changeName', 'wzj')方法二:方法二:定义一个util.js文件
import Vue from 'vue'
const bus = new Vue()
export default bus
import Vue from 'vue'
const bus = new Vue()
export default bus在需要用到bus的文件中引入
import bus from '../util' //文件路径不一定
//在一个文件定义事件
bus.$on('changeName', name => {
this.name = name
})
//另一个文件抛出参数
bus.$emit('changeName', 'wzj')
import bus from '../util' //文件路径不一定
//在一个文件定义事件
bus.$on('changeName', name => {
this.name = name
})
//另一个文件抛出参数
bus.$emit('changeName', 'wzj')vuexvuexvuex对于项目比较复杂,多组件共享状态,不同层级需要通信核心概念:state, getter, mutation, action, module
//store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export dafault new Vuex.Store({
state: {
name: '',
age: 0
},
getters: {
tranName(state){
return 'name: ' + state.name
}
},
mutations: {
changeName(state, name){
state.name = name
}
},
/*Action 函数接受一个与 store 实例具有相同方法和属性的 context 对象,因此你可以调用 context.commit 提交一个 mutation,或者通过 context.state 和 context.getters 来获取 state 和 getters */
actions: { //异步函数,但还是要通过提交commit触发mutations函数操作state
changeName(context, name){
context.commit('changeName', name)
}
},
modules: {}
})
//store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export dafault new Vuex.Store({
state: {
name: '',
age: 0
},
getters: {
tranName(state){
return 'name: ' + state.name
}
},
mutations: {
changeName(state, name){
state.name = name
}
},
/*Action 函数接受一个与 store 实例具有相同方法和属性的 context 对象,因此你可以调用 context.commit 提交一个 mutation,或者通过 context.state 和 context.getters 来获取 state 和 getters */
actions: { //异步函数,但还是要通过提交commit触发mutations函数操作state
changeName(context, name){
context.commit('changeName', name)
}
},
modules: {}
})在组件中使用方法一:方法一:
//访问state属性
this.$store.state.name
//访问getters属性
this.$store.getters.tranName
//访问mutations
this.$store.commit('changeName', 'wzj')
//访问actions
this.$store.dispatch('changeName', 'wzj')
//访问state属性
this.$store.state.name
//访问getters属性
this.$store.getters.tranName
//访问mutations
this.$store.commit('changeName', 'wzj')
//访问actions
this.$store.dispatch('changeName', 'wzj')方法二:使用辅助函数映射到本地,这里只列举了简便的方式,查阅官网吧方法二:使用辅助函数映射到本地,这里只列举了简便的方式,查阅官网吧
import {mapState, mapGetters, mapMutations, mapActions} from 'vuex'
//state 和 getters 映射到本地的computed属性中,作为计算属性使用
computed: {
...mapState(['name', 'age']),
...mapGetters(['tranName'])
}
//mutations 和 actions
methods: {
// 将 `this.changeName()` 映射为 `this.$store.commit('changeName')`
...mapMutations(['changeName'])
// 将 `this.changeName()` 映射为 `this.$store.dispatch('changeName')`
...mapActions(['changeName'])
}
import {mapState, mapGetters, mapMutations, mapActions} from 'vuex'
//state 和 getters 映射到本地的computed属性中,作为计算属性使用
computed: {
...mapState(['name', 'age']),
...mapGetters(['tranName'])
}
//mutations 和 actions
methods: {
// 将 `this.changeName()` 映射为 `this.$store.commit('changeName')`
...mapMutations(['changeName'])
// 将 `this.changeName()` 映射为 `this.$store.dispatch('changeName')`
...mapActions(['changeName'])
}$attrs 和 $listeners
$attrs 和 $listeners
$attrs 和 $listeners
父组件与后代组件,用以上方法有点大材小用或者第一种有些不方便
$attrs 包含了父作用域中不作为 prop 被识别 (且获取) 的 attribute 绑定 ( class 和 style 除外)。当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 ( class 和 style 除外),并且可以通过 v-bind="$attrs" 传入内部组件。
$listeners 包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。它可以通过 v-on="$listeners" 传入内部组件——在创建更高层次的组件时非常有用。
$attrs 包含了父作用域中不作为 prop 被识别 (且获取) 的 attribute 绑定 ( class 和 style 除外)。当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 ( class 和 style 除外),并且可以通过 v-bind="$attrs" 传入内部组件。$listeners 包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。它可以通过 v-on="$listeners" 传入内部组件——在创建更高层次的组件时非常有用。
例子:
//app.vue
...
data(){
return {
age: 10
}
},
methods: {
changeAge(age){
this.age = age
}
}
//one.vue
...
props: ['name', 'age'],
//two.vue
...
props: ['address'], //用$attrs传递到最后的属性,在使用的时候还是要声明props
methods: {
change(){
this.$emit('changeAge', 30)
}
}
//app.vue
...
data(){
return {
age: 10
}
},
methods: {
changeAge(age){
this.age = age
}
}
//one.vue
...
props: ['name', 'age'],
//two.vue
...
props: ['address'], //用$attrs传递到最后的属性,在使用的时候还是要声明props
methods: {
change(){
this.$emit('changeAge', 30)
}
}理解:其实祖先组件的属性和事件还是一层层往下传,不过用$attrs 和 $listeners优化和简便了传递过程中书写,而且在传递的过程中,任何一个声明了 $listeners的组件都可以触发里面的所有事件,而声明了$attrs的组件只能使用之前未用props声明的剩下的属性。以上就是vue组件之间的通信的详细内容,关于vue 组件通信的资料请关注其它相关文章!
...
data () {
return {
name: 'marry'
}
}
post: {
id: 1,
title: 'My Journey with Vue'
}
//等价于下面
v-bind:title="post.title"
>
...
//以字符串数组形式列出的 prop
props: ['name', 'age', 'address']
//prop验证, 当 prop 验证失败的时候,(开发环境构建版本的) Vue 将会产生一个控制台的警告
//注意:以下类型不能写成'String'这种带引号的形式
props: {
// 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证)
propA: Number,
// 多个可能的类型
propB: [String, Number],
// 必填的字符串
propC: {
type: String,
required: true
},
// 带有默认值的数字
propD: {
type: Number,
default: 100
},
// 带有默认值的对象
propE: {
type: Object,
// 对象或数组默认值必须从一个工厂函数获取
default: function () {
return { message: 'hello' }
}
},
// 自定义验证函数
propF: {
validator: function (value) {
// 这个值必须匹配下列字符串中的一个
return ['success', 'warning', 'danger'].indexOf(value) !== -1
}
}
}
//注意那些 prop 会在一个组件实例创建之前进行验证,所以实例的 property (如 data、computed 等) 在 default 或 validator 函数中是不可用的。
...
data () {
return {
name: 'marry'
}
}
post: {
id: 1,
title: 'My Journey with Vue'
}
//等价于下面
v-bind:title="post.title"
>
...
//以字符串数组形式列出的 prop
props: ['name', 'age', 'address']
//prop验证, 当 prop 验证失败的时候,(开发环境构建版本的) Vue 将会产生一个控制台的警告
//注意:以下类型不能写成'String'这种带引号的形式
props: {
// 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证)
propA: Number,
// 多个可能的类型
propB: [String, Number],
// 必填的字符串
propC: {
type: String,
required: true
},
// 带有默认值的数字
propD: {
type: Number,
default: 100
},
// 带有默认值的对象
propE: {
type: Object,
// 对象或数组默认值必须从一个工厂函数获取
default: function () {
return { message: 'hello' }
}
},
// 自定义验证函数
propF: {
validator: function (value) {
// 这个值必须匹配下列字符串中的一个
return ['success', 'warning', 'danger'].indexOf(value) !== -1
}
}
}
//注意那些 prop 会在一个组件实例创建之前进行验证,所以实例的 property (如 data、computed 等) 在 default 或 validator 函数中是不可用的。2.$emit2.$emit
...
methods: {
myEvent(name){
this.name = name
}
}
//使用自定义事件将子组件的值抛给父组件
...
methods: {
myEvent(name){
this.name = name
}
}
//使用自定义事件将子组件的值抛给父组件中央事件总线 bus中央事件总线 bus中央事件总线 bus用于解决跨级和兄弟组件通信问题,巧妙的使用一个公共的vue实例,利用$on, $emit, $off(移除自定义事件监听器)方法一:方法一:可以在main.js中,在Vue的原型上挂载一个公共的Vue实例 $bus,这样全局任何一个地方都可以使用
Vue.prototype.$bus = new Vue()
Vue.prototype.$bus = new Vue()然后在需要的地方注册自定义事件和接收参数的回调函数
this.$bus.$on('changeName', name => {
this.name = name
})
this.$bus.$on('changeName', name => {
this.name = name
})在需要改变的时候触发事件并抛出参数
this.$bus.$emit('changeName', 'wzj')
this.$bus.$emit('changeName', 'wzj')方法二:方法二:定义一个util.js文件
import Vue from 'vue'
const bus = new Vue()
export default bus
import Vue from 'vue'
const bus = new Vue()
export default bus在需要用到bus的文件中引入
import bus from '../util' //文件路径不一定
//在一个文件定义事件
bus.$on('changeName', name => {
this.name = name
})
//另一个文件抛出参数
bus.$emit('changeName', 'wzj')
import bus from '../util' //文件路径不一定
//在一个文件定义事件
bus.$on('changeName', name => {
this.name = name
})
//另一个文件抛出参数
bus.$emit('changeName', 'wzj')vuexvuexvuex对于项目比较复杂,多组件共享状态,不同层级需要通信核心概念:state, getter, mutation, action, module
//store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export dafault new Vuex.Store({
state: {
name: '',
age: 0
},
getters: {
tranName(state){
return 'name: ' + state.name
}
},
mutations: {
changeName(state, name){
state.name = name
}
},
/*Action 函数接受一个与 store 实例具有相同方法和属性的 context 对象,因此你可以调用 context.commit 提交一个 mutation,或者通过 context.state 和 context.getters 来获取 state 和 getters */
actions: { //异步函数,但还是要通过提交commit触发mutations函数操作state
changeName(context, name){
context.commit('changeName', name)
}
},
modules: {}
})
//store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export dafault new Vuex.Store({
state: {
name: '',
age: 0
},
getters: {
tranName(state){
return 'name: ' + state.name
}
},
mutations: {
changeName(state, name){
state.name = name
}
},
/*Action 函数接受一个与 store 实例具有相同方法和属性的 context 对象,因此你可以调用 context.commit 提交一个 mutation,或者通过 context.state 和 context.getters 来获取 state 和 getters */
actions: { //异步函数,但还是要通过提交commit触发mutations函数操作state
changeName(context, name){
context.commit('changeName', name)
}
},
modules: {}
})在组件中使用方法一:方法一:
//访问state属性
this.$store.state.name
//访问getters属性
this.$store.getters.tranName
//访问mutations
this.$store.commit('changeName', 'wzj')
//访问actions
this.$store.dispatch('changeName', 'wzj')
//访问state属性
this.$store.state.name
//访问getters属性
this.$store.getters.tranName
//访问mutations
this.$store.commit('changeName', 'wzj')
//访问actions
this.$store.dispatch('changeName', 'wzj')方法二:使用辅助函数映射到本地,这里只列举了简便的方式,查阅官网吧方法二:使用辅助函数映射到本地,这里只列举了简便的方式,查阅官网吧
import {mapState, mapGetters, mapMutations, mapActions} from 'vuex'
//state 和 getters 映射到本地的computed属性中,作为计算属性使用
computed: {
...mapState(['name', 'age']),
...mapGetters(['tranName'])
}
//mutations 和 actions
methods: {
// 将 `this.changeName()` 映射为 `this.$store.commit('changeName')`
...mapMutations(['changeName'])
// 将 `this.changeName()` 映射为 `this.$store.dispatch('changeName')`
...mapActions(['changeName'])
}
import {mapState, mapGetters, mapMutations, mapActions} from 'vuex'
//state 和 getters 映射到本地的computed属性中,作为计算属性使用
computed: {
...mapState(['name', 'age']),
...mapGetters(['tranName'])
}
//mutations 和 actions
methods: {
// 将 `this.changeName()` 映射为 `this.$store.commit('changeName')`
...mapMutations(['changeName'])
// 将 `this.changeName()` 映射为 `this.$store.dispatch('changeName')`
...mapActions(['changeName'])
}$attrs 和 $listeners
$attrs 和 $listeners
$attrs 和 $listeners
父组件与后代组件,用以上方法有点大材小用或者第一种有些不方便
$attrs 包含了父作用域中不作为 prop 被识别 (且获取) 的 attribute 绑定 ( class 和 style 除外)。当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 ( class 和 style 除外),并且可以通过 v-bind="$attrs" 传入内部组件。
$listeners 包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。它可以通过 v-on="$listeners" 传入内部组件——在创建更高层次的组件时非常有用。
$attrs 包含了父作用域中不作为 prop 被识别 (且获取) 的 attribute 绑定 ( class 和 style 除外)。当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 ( class 和 style 除外),并且可以通过 v-bind="$attrs" 传入内部组件。$listeners 包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。它可以通过 v-on="$listeners" 传入内部组件——在创建更高层次的组件时非常有用。
例子:
//app.vue
...
data(){
return {
age: 10
}
},
methods: {
changeAge(age){
this.age = age
}
}
//one.vue
姓名:{{ name }}
年龄:{{ age }}
...
props: ['name', 'age'],
//two.vue
{{ address }}
...
props: ['address'], //用$attrs传递到最后的属性,在使用的时候还是要声明props
methods: {
change(){
this.$emit('changeAge', 30)
}
}
//app.vue
...
data(){
return {
age: 10
}
},
methods: {
changeAge(age){
this.age = age
}
}
//one.vue
姓名:{{ name }}
年龄:{{ age }}
...
props: ['name', 'age'],
//two.vue
{{ address }}
...
props: ['address'], //用$attrs传递到最后的属性,在使用的时候还是要声明props
methods: {
change(){
this.$emit('changeAge', 30)
}
}理解:其实祖先组件的属性和事件还是一层层往下传,不过用$attrs 和 $listeners优化和简便了传递过程中书写,而且在传递的过程中,任何一个声明了 $listeners的组件都可以触发里面的所有事件,而声明了$attrs的组件只能使用之前未用props声明的剩下的属性。以上就是vue组件之间的通信的详细内容,关于vue 组件通信的资料请关注其它相关文章!
相关文章:
- jsVue路由权限控制解析js大全
- js微信小程序调用后台service教程详解js大全
- js解决VUE项目使用Element-ui 下拉组件的验证失效问题js大全
- js全网小程序接口请求封装实例代码js大全
- jsvue router-link 默认a标签去除下划线的实现js大全
- jsVUE异步更新DOM - 用$nextTick解决DOM视图的问题js大全
- js微信小程序基于ColorUI构建皮皮虾短视频去水印组件js大全
- js解决element-ui的下拉框有值却无法选中的情况js大全
- js解决VueCil代理本地proxytable无效报错404的问题js大全
- js解决Element中el-date-picker组件不回填的情况js大全