vue 组件通信方式

父子组件通信

绝大部分vue本身提供的通信方式,都是父子组件通信

  • prop 最常见的组件通信方式之一,由父组件传递到子组件。

  • event 最常见的组件通信方式之一,当子组件发生了某些事,可以通过event通知父组件。

  • style 和 classstyleclass通信范围比较窄,是传递样式的,父组件可以向子组件传递styleclass,最终它们会合并到子组件的根元素中。

示例:

父组件

<template>
  <div id="app">
    <HelloWorld
    //父组件身上用到了子组件,在这里写的样式会传递到子组件的根元素身上
      style="color:red"
      class="hello"
      msg="Welcome to follow me!"
    />
  </div>
</template>
<script>
import HelloWorld from "./components/HelloWorld.vue";
export default {
  components: {
    HelloWorld,
  },
};
</script>

子组件

<template>
//如果子组件身上已存在class和style属性,那么会与父组件传过来的样式进行合并
  <div class="world" style="text-align:center">
    <h1>{{msg}}</h1>
  </div>
</template>
<script>
export default {
  name: "HelloWorld",
  props: {
    msg: String,
  },
};
</script>

最终渲染结果:

<div id="app">
  <div class="hello world" style="color:red; text-aling:center">
    <h1>Welcome to follow me!</h1>
  </div>
</div>

attributetattributet在开发中很少会用到,如果父组件传递了一些属性( 属性并不包括styleclass,它们会被特殊处理)到子组件,但子组件并没有声明这些属性,则它们被称为attribute,这些属性会直接附着在子组件的根元素上,而且我们在前端培训学习中了解到可以在子组件中通过this.$attrs拿到

示例

父组件

<template>
  <div id="app">
    <!-- 除 msg 外,其他都是 attribute -->
    <HelloWorld
      data-a="1"
      data-b="2"
      msg="Welcome to Your Vue.js App"
    />
  </div>
</template>
<script>
import HelloWorld from "./components/HelloWorld.vue";
export default {
  components: {
    HelloWorld,
  },
};
</script

子组件

<template>
  <div>
    <h1>{{msg}}</h1>
  </div>
</template>
<script>
export default {
  name: "HelloWorld",
  inheritAttrs: false,//禁止将attribute附着在子组件的根元素上,但不影响通过`$attrs`获取
  props: {
    msg: String,
  },
  created() {
    console.log(this.$attrs); // 得到: { "data-a": "1", "data-b": "2" }
  },
};
</script>

最终渲染结果:

<div id="app">
  <div data-a="1" data-b="2">
    <h1>Welcome to Your Vue.js App</h1>
  </div>
</div>

子组件可以通过inheritAttrs: false配置,禁止将attribute附着在子组件的根元素上,也就是data-a="1" data-b="2"不会出现在子组件的根元素身上,但不影响通过$attrs获取。

natvie 修饰符

在注册事件时,父组件可以使用native修饰符,将事件注册到子组件的根元素上。

示例

父组件

<template>
  <div id="app">
    <HelloWorld @click.native="handleClick" />
  </div>
</template>
<script>
import HelloWorld from "./components/HelloWorld.vue";
export default {
  components: {
    HelloWorld,
  },
  methods: {
    handleClick() {
      console.log(1);
    },
  },
};
</script>

子组件

<template>
  <div>
    <h1>Hello World</h1>
  </div>
</template>

渲染结果

<div id="app">
  <!-- 点击该 div,会输出 1 -->
  <div>
    <h1>Hello World</h1>
  </div>
</div>
  • $listeners

子组件可以通过$listeners获取父组件传递过来的所有事件处理函数。

  • v-model

  • sync 修饰符

v-model的作用类似,都是语法糖,用于双向绑定,不同点在于v-model只能针对一个数据进行双向绑定,而sync修饰符没有限制,在 vue3 中没有 sync 修饰符,它会和 v-model 合并成一个。

示例

下面代码做了这样一件事:父组件给子组件传了两个值num1num2,子组件并没有能力修改,但是子组件有一个触发事件的能力,故触发updata1updata2,并且传了两个新值num1 ± 1num2 ± 1让父组件进行处理

子组件

<template>
  <div>
    <p>
      <button @click="$emit(`update1:num1`, num1 - 1)">-</button>
      {{ num1 }}
      <button @click="$emit(`update1:num1`, num1 + 1)">+</button>
    </p>
    <p>
      <button @click="$emit(`update2:num2`, num2 - 1)">-</button>
      {{ num2 }}
      <button @click="$emit(`update2:num2`, num2 + 1)">+</button>
    </p>
  </div>
</template>
<script>
export default {
  props: ["num1", "num2"],
};
</script>
<template>
  <div id="app">
    <Numbers :num1.sync="n1" :num2.sync="n2" />
    <!-- 上面 Numbers 等同于下面 Numbers  -->
    <Numbers
      :num1="n1"
      @update:num1="n1 = $event"
      :num2="n2"
      @update:num2="n2 = $event"
    />
  </div>
</template>
<script>
import Numbers from "./components/Numbers.vue";
export default {
  components: {
    Numbers,
  },
  data() {
    return {
      n1: 0,
      n2: 0,
    };
  },
};
</script>

效果展示:

 

$parent$children

在组件内部,可以通过$parent$children属性,分别得到当前组件的父组件和子组件实例

示例:

<template>
  <div id="app">
    <h1>法医</h1>
    <A />
    <A />
  </div>
</template>
<script>
import A from "../src/component/A"
export default {
  components: { A },
  mounted(){
    console.log(this.$children);
  }
};
</script>

ref 父组件可以通过ref获取到子组件的实例,也可以用在 dom 身上,拿到当前的 dom 元素

跨组件通信

除了ProvideInject是 vue 提供的通信方式,其余方式都是要依赖第三方间接通信

ProvideInject

这个是 vue 提供的跨组件通信方式,但是兄弟组件是不行,只能是父子组件或者祖先和后代这种关系才能通信。

示例

// 父级组件提供 'foo'
var Provider = {
  provide: {
    foo: 'bar'
  },
  // ...
}
// 子组件注入 'foo'
var Child = {
  inject: ['foo'],
  created () {
    console.log(this.foo) // => "bar"
  }
  // ...
}

router

如果一个组件改变了地址栏,所有监听地址栏的组件都会做出相应反应

最常见的场景就是通过点击router-link组件改变了地址,router-view组件就渲染其他内容

vuex

适用于大型项目的数据仓库

store模式

适用于中小型项目的数据仓库

// store.js
const store = {
  loginUser: ...,
  setting: ...
}
// compA
const compA = {
  data(){
    return {
      loginUser: store.loginUser
    }
  }
}
// compB
const compB = {
  data(){
    return {
      setting: store.setting,
      loginUser: store.loginUser
    }
  }
}
posted @   Linux运维阿铭  阅读(154)  评论(0编辑  收藏  举报
编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示