IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> vue2组件通信 -> 正文阅读

[JavaScript知识库]vue2组件通信

1. props/$emit:

父组件A通过props向子组件B传数据,B向A传递数据通过在B中$emit触发A中的自定义事件,在B中v-on监听。

适用场景:父子通信。

代码实例:
Parent.vue:

<template>
    <div>
        Parent
        <h2>{{name}}</h2>
        <children :name="name" v-on:ChildrenToParent="func1"></children>
    </div>
</template>

<script>
import Children from './Children'
export default {
  name: 'Parent',
  components: {
    Children
  },
  data () {
    return {
      name: 'Lily'
    }
  },
  methods: {
    func1 (name, age) {
      this.name = name
      console.log('父组件', name, age)
    }
  }
}
</script>

Children.vue:

<template>
  <div>
    Children
    <button @click="btnClick1">打印父传到子的数据</button>
    <button @click="btnClick2">子向父传数据</button>
  </div>
</template>

<script>
export default {
  name: 'Children',
  props: {
    name: String
  },
  methods: {
    btnClick1 () {
      console.log('子组件', this.name)
    },
    btnClick2 () {
      this.$emit('ChildrenToParent', 'yue', 12)
    }
  }
}
</script>

2. $emit/$on:

通过一个空的Vue实例作为中央事件总线,用它来触发和监听事件,要通信的组件共用同一个事件机制。传递数据用emit,接受数据方用on。

适用场景:父子,兄弟,跨级通信。

代码实例:组件BrotherC接受兄弟组件BrotherA和兄弟组件BrotherB传递的数据。
emptyVue.js:

//创建一个空的Vue实例,将通信事件挂载到该实例上。
import Vue from "vue"
export default new Vue()

BrotherA.vue:

<template>
  <div>
    <button @click="send">按下按钮,A向C传数据</button>
  </div>
</template>

<script>
import emptyVue from '../../util/emptyVue.js'
export default {
  name: 'BrotherA',
  data () {
    return {
      name: 'A组件'
    }
  },
  methods: {
    send () {
      emptyVue.$emit('data-a', this.name)
    }
  }
}
</script>

BrotherB.vue:

<template>
  <div>
    <button @click="send">按下按钮,B向C传数据</button>
  </div>
</template>

<script>
import emptyVue from '../../util/emptyVue.js'
export default {
  name: 'BrotherB',
  data () {
    return {
      name: 'B组件'
    }
  },
  methods: {
    send () {
      emptyVue.$emit('data-b', this.name)
    }
  }
}
</script>

BrotherC.vue:

<template>
  <div>
  </div>
</template>
<script>
import emptyVue from '../../util/emptyVue.js'
export default {
  name: 'BrotherC',
  mounted () {
    emptyVue.$on('data-a', (data) => {
      console.log('C接收到A的数据:', data)
    })
    emptyVue.$on('data-b', (data) => {
      console.log('C接收到B的数据:', data)
    })
  }
}
</script>

App.vue:

<template>
  <div id="app">
   <brother-a></brother-a>
   <brother-b></brother-b>
   <brother-c></brother-c>
  </div>
</template>
<script>
import BrotherA from '@/components/emit和on/BrotherA'
import BrotherB from '@/components/emit和on/BrotherB'
import BrotherC from '@/components/emit和on/BrotherC'
export default {
  name: 'App',
  components:{
    BrotherA,
    BrotherB,
    BrotherC
  }
}
</script>

3.$attrs/$listeners

$attrs:包含父作用域中的不被认为是props的属性(class和style不为props属性),可以通过v-bind=’$attrs"传入其内部组件。
$listeners:包含父组件作用域中的(不包含.native修饰)v-on事件监听器,可以通过v-on="$listeners"传入内部组件,相当于子组件继承了父组件的事件。

适用场景:父子,跨级通信。组件嵌套层级深的不必用props,项目较小的不必用vuex,此时可以用$attrs/$listeners。

例子:
Father.vue:

<template>
  <div>
    <son name="Lilt" age="12" @func1="func1" @func2="func2" class="id1"></son>
  </div>
</template>

<script>
import Son from './Son'
export default {
  name: 'Father',
  components: {
    Son
  },
  methods: {
    func1 () {
      console.log('执行func1')
    },
    func2 () {
      console.log('执行func2')
    }
  }
}
</script>

Son.vue:

<template>
  <div>
    <grand-son height="1.7" weight="11" @func3="func3" v-bind='$attrs' v-on="$listeners"></grand-son>
  </div>
</template>

<script>
import GrandSon from './GrandSon'
export default {
  name: 'Son',
  components: {
    GrandSon
  },
  props: ['name'],
  methods: {
    func3 () {
      console.log('执行func3')
    }
  },
  created () {
    console.log('Son', this.$attrs, this.$listeners)// 输出:Son {age: '12'} {func1: ?, func2: ?}
  }
}
</script>

GrandSon.vue:

<template>
  <div></div>
</template>

<script>
export default {
  name: 'GrandSon',
  props: ['height'],
  created () {
    console.log('GrandSon', this.$attrs, this.$listeners)// 输出:GrandSon {weight: '11', age: '12'} {func3: ?, func1: ?, func2: ?}
    this.$emit('func1')// 可触发Father的func1
  }
}
</script>

4. $parent/$children/ref:

$parent/$children:访问父子实例。
ref:用在普通DOM元素,引用当前的DOM元素;用在子组件上,引用指向组件实例。
这三种都是直接得到组件实例,使用后可以直接调用组件的方法和数据。

适用场景:父子通信。

例如:
Parent.vue:

<template>
  <div>
    <children ref="ref1"></children>
    <button @click="btnClick">按钮</button>
  </div>
</template>
<script>
import Children from './Children'
export default {
  name: 'Parent',
  components: {
    Children
  },
  methods: {
    btnClick () {
      const ref1 = this.$refs.ref1
      // 可以拿到子组件的数据和方法
      console.log(ref1.name)
      ref1.func1()
      console.log('this.$children', this.$children)//打印Children组件的相关信息
    }
  }
}
</script>

Children.vue:

<template>
  <div>
    Children
  </div>
</template>
<script>
export default {
  name: 'Children',
  data () {
    return {
      name: 'Lily'
    }
  },
  methods: {
    func1 () {
      console.log('执行func1')
      console.log('this.$parent:', this.$parent)//打印Parent组件的相关信息
    }
  }
}
</script>

5. provide和inject

祖先组件通过provider来提供变量,然后在子孙组件中通过inject来注入变量,非响应式。

适用场景:父子,跨级通信。

例如:
Parent.vue:

<template>
  <son></son>
</template>
<script>
import Son from './Son'
export default {
  name: 'Parent',
  components: {
    Son
  },
  provide () {
    return {
      msg: '玛卡巴卡'
    }
  }
}
</script>

Son.vue:

<template>
  <grand-son></grand-son>
</template>
<script>
import GrandSon from './GrandSon'
export default {
  name: 'Son',
  components: {
    GrandSon
  }
}
</script>

GrandSon.vue:

<template>
  <div>
    这是GrandSon
  </div>
</template>
<script>
export default {
  name: 'GrandSon',
  inject: ['msg'],
  mounted () {
    console.log('GrandSon接收到来自Parent的msg:', this.msg)
  }
}
</script>

6. vuex

vuex提出单一状态树的概念,如果我们的状态信息是保存到多个Store对象中的,那么之后的管理和维护等等都会变得特别困难,所以vuex推荐单一状态树来管理应用层级的全部状态,即只有一个Store实例。

在全局用一个State存放数据,当使用vuex数据的组件需要修改某些共享数据时,要通过Mutations来修改。(虽然Vue Components直接操作Vuex的State也是可以的,都是所有组件都这么直接改,出了bug不太容易定位到是哪个组件修改的。Devtools是一个浏览器插件,可以帮助我们记录那个组件修改的State,当前提是通过Mutations修改数据的)。
这里附上官网的vuex流程图:
在这里插入图片描述
异步操作时必须从经过Actions。

适用场景:均可。

代码实例:
store/index.js:

import Vue from 'vue'
import Vuex from 'vuex'

// 1. 安装插件
Vue.use(Vuex)// 好像是自动执行vuex.install

// 2.创建对象
const store = new Vuex.Store({
  state: {
    counter: 1000
  },
  mutations: {
    additon (state) {
      state.counter++
    },
    subtraction (state) {
      state.counter--
    }
  }
})

// 3.导出store对象
export default store

TestCpn.vue:

<template>
  <div>
    <h2>{{$store.state.counter}}</h2>
    <!-- <button @click="$store.state.counter++">按钮</button> -->
    <button @click="add">+1</button>
    <button @click="sub">-1</button>
  </div>
</template>
<script>
export default {
  methods: {
    add () {
      this.$store.commit('additon')
    },
    sub () {
      this.$store.commit('subtraction')
    }
  }
}
</script>

main.js

import Vue from 'vue'
import App from './App'
import router from './router'
import store from './store'//导入store

Vue.config.productionTip = false

/* eslint-disable no-new */

// 塞入store相当于Vue.prototype.$store=store
new Vue({
  el: '#app',
  router,
  store,
  components: { App },
  template: '<App/>'
})
  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-03-08 22:20:01  更:2022-03-08 22:24:16 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 8:03:45-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码