一, props / $emit
Prop 是你可以在组件上注册的一些自定义特性. 当一个值传递给一个 prop 特性的时候, 它就变成了那个组件实例的一个属性. 和 react 的 props 类似.
- // Demo 父组件
- <template>
- <div class="father">
- /** 向子组件传值 */
- <Child :age="age"></Child>
- </div>
- </template>
- <script>
- import Child from './child.vue'
- export default {
- name: 'child',
- components: { Child },
- data() {
- return {
- age: 12
- }
- }
- }
- </script>
- // 子组件中使用 props
- <template>
- <div>
- {{age}}
- </div>
- </template>
- <script>
- export default {
- props: {
- age: {
- type: Number
- }
- }
- }
- </script>
$emit 触发当前实例上的事件. 附加参数都会传给监听器回调.
- <template>
- <div @click="callFatherListener">
- {{age}}
- </div>
- </template>
- <script>
- export default {
- props: {
- age: {
- type: Number
- }
- },
- methods: {
- callFatherListener () {
- // 点击时, 调用父组件的方法, 前提是该方法已被注册
- this.$emit('fatherEvent', 'msg from son')
- }
- }
- }
- </script>
- // --- 父组件中 ---
- <template>
- <div class="hello">
- <h1>{{ msg }}</h1>
- <!-- 父组件注册这个事件监听器, 当被子组件调用后会捕获 -->
- <Son :age="1" @fatherEvent="fatherEvent"></Son>
- </div>
- </template>
- <script>
- import Son from './Son'
- export default {
- components: {Son},
- name: 'Father',
- data () {
- return {
- msg: 'Welcome to Your vue.js App'
- }
- },
- methods: {
- fatherEvent (msg) {
- console.log(msg)
- }
- }
- }
- </script>
二,$parent / $children
指定已创建的实例之父实例, 在两者之间建立父子关系. 子实例可以用 this.$parent 访问父实例, 子实例被推入父实例的 $children 数组中.
- <!-- 父组件中 -->
- <template>
- <div class="hello">
- <h1 @click="changeSonMsg"> 点击改变子组件的值 </h1>
- <Son></Son>
- </div>
- </template>
- <script>
- import Son from './Son'
- export default {
- components: {Son},
- name: 'Father',
- data () {
- return {
- msg: '爸爸的 msg'
- }
- },
- methods: {
- changeSonMsg () {
- // 改变子组件的值
- this.$children[0].msg = 'change from father'
- // 调用父组件的方法
- this.$children[0].sonFunc('儿子你给我嘿嘿嘿')
- },
- fatherFunc () {
- console.log('爸爸你也嘿嘿嘿')
- }
- }
- }
- </script>
- <!-- 子组件中 -->
- <template>
- <div>
- {{msg}}
- <p @click="callFatherFunc"> 获取爸爸组件的值为: {{fatherVal}}</p>
- </div>
- </template>
- <script>
- export default {
- data () {
- return {
- msg: 'default msg'
- }
- },
- methods: {
- sonFunc (msg) {
- console.log(msg)
- },
- callFatherFunc () {
- // 调用父组件的方法
- this.$parent.fatherFunc()
- }
- },
- computed: {
- fatherVal () {
- // 通过 $parent 获取父组件的属性
- return this.$parent.msg
- }
- }
- }
- </script>
要注意边界情况, 如在 #App 上拿 $parent 得到的是 new Vue() 的实例, 在这实例上再拿 $parent 得到的是 undefined, 而在最底层的子组件拿 $children 是个空数组. 也要注意得到 $parent 和 $children 的值不一样,$children 的值是数组, 而 $parent 是个对象, 另外根实例可以通过 $root 拿到.
三, provide / inject
2.2.0 新增
无论嵌套多深, 都能通信
provide 选项应该是一个对象或返回一个对象的函数. 该对象包含可注入其子孙的属性.
inject 选项应该是:
一个字符串数组, 或
一个对象, 对象的 key 是本地的绑定名
- <!-- 父组件中 -->
- <template>
- <div class="hello">
- <Son></Son>
- </div>
- </template>
- <script>
- import Son from './Son'
- export default {
- components: {Son},
- name: 'Father',
- provide: {
- for: 'Father provide msg'
- }
- }
- </script>
- <!-- 子组件中 -->
- <template>
- <div>
父级获取的属性: {{msg}}
- </div>
- </template>
- <script>
- export default {
- data () {
- return {
- msg: this.for
- }
- },
- inject: ['for']
- }
- </script>
provide 和 inject 主要为高阶插件 / 组件库提供用例, 所以这里有个笔者写的一个高级的例子.
四, ref / refs
ref 被用来给元素或子组件注册引用信息. 引用信息将会注册在父组件的 $refs 对象上. 如果在普通的 DOM 元素上使用, 引用指向的就是 DOM 元素; 如果用在子组件上, 引用就指向组件实例.
- <!-- 子组件中 -->
- <template>
- <div>
- {{msg}}
- </div>
- </template>
- <script>
- export default {
- data () {
- return {
- msg: 'son\'s msg'
- }
- }
- }
- </script>
- <!-- 父组件中 -->
- <template>
- <div class="hello">
- <Son ref="son"></Son>
- <p @click="showSonMsg"> 点击打印 son 的 msg</p>
- </div>
- </template>
- <script>
- import Son from './Son'
- export default {
- components: {Son},
- name: 'Father',
- methods: {
- showSonMsg () {
- console.log(this.$refs.son.msg)
- }
- }
- }
- </script>
五, eventBus
eventBus 又称事件总线, 笔者用的很少, 具体可以去官网.
vuex 加入后, 对组件之间的通信有了更加清晰的操作, 对于中大型的项目来说, 一开始就把 vuex 的使用计划在内是明智的选择.
六 ,vuex
组件不允许直接修改属于 store 实例的 state, 而应执行 action 来分发 (dispatch) 事件通知 store 去改变, 我们最终达成了 Flux https://facebook.github.io/flux/ 架构. 这样约定的好处是, 我们能够记录所有 store 中发生的 state 改变
this.$store.commit('selectMenu',"xxx")
总结
父子关系可以用 props-$emit,parent-children 等, 如果是兄弟层级或关联度不高的组件之间的通信, 推荐使用 vuex.
借用官方的说法, 一般简单项目没必要使用 vuex, 中大型项目复制项目建议使用 vuex.
和 redux 相比, react16.8 以后推出 hook, 借用阮一峰老师的话,'这个 api 是 react 的未来'.
七, localstorage 和 sessionStorage
应该说不单是 vue, 凡是前端都可以用这种方式通信, 跨页面跨层级的.
阮一峰 react hook 入门: http://www.ruanyifeng.com/blog/2019/09/react-hooks.html
阮一峰 react 技术栈系列: http://www.ruanyifeng.com/blog/2016/09/react-technology-stack.html
来源: http://www.bubuko.com/infodetail-3446295.html