Vue--组件间通信

简介: Vue--组件间通信

组件间通信方式


组件间通信方式有三种:

  • props  父组件向子组件传递数据
  • $emit  自定义事件(子组件向父组件传递数据)
  • slot  插槽分发内容

组件间通信要遵循以下的规则:

  • 不要在子组件中直接修改父组件传递的数据
  • 数据初始化时,应当看初始化的数据是否用于多个组件中,如果需要被用于多个组件中,则初始化在父组件中;如果只在 一个组件中使用,那就初始化在这个要使用的组件中。
  • 数据初始化在哪个组件,更新数据的方法(函数) 就应该定义在哪个组件。


props向子组件传递数据


1.在声明组件对象中使用props选项指定

const MyComponent = {
    template: `<div></div>`,
    props: 此处值有以下三种方式,
    components: {
    }
}

方式一:指定传递属性名,注意是数组形式。

props: ['id','name','salary', 'isPublished', 'commentIds', 'author', 'getEmp']

方式二:指定传递属性名和数据类型,注意是对象形式。

props: {
   id: Number,
   name: String,
   salary: Number,
   isPublished: Boolean,
   commentIds: Array,
   author: Object,
   getEmp: Function
}

方式三:指定属性名,数据类型,必要性,默认值

props: {
   name: {
      type: String,
      required: true,
      default: 'zou'
    }
  ......
}

2.在引用组件时,通过v-bind动态赋值

<my-component v-bind:id="2" :name="meng" :salary="9999" :is-published="true" :comment-ids="[1, 2]"
:author="{name: 'alan'}" :get-emp="getEmp" >
</my-component>

先来看看父组件的内容

;(function () {
    const template = `<div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
        // 通过 v-bind把父组件的内容传给子组件 ,:前面的名称可以自定义,为了方便理解,一般和传递的变量名一样
        <dashboard :hobbies="hobbies" @delete_hobby="deleteHobby"></dashboard>
      </div>`
    window.AppHome = {
        template, // template: template,
        data () { // 定义父组件往子组件里传的内容
            return {
                hobbies: ['coding', '睡觉', '打豆豆', '看书'],
            }
        },
        components: { //Dashboard ,HomeList 作为AppHome 的子组件
            Dashboard, // Dashboard: Dashboard
            HomeList // HomeList:HomeList
        }
    }
})()

这样父组件就写好了,在来看看子组件的内容

;(function () {
    const template = `<div class="row placeholders">
    // 在子组件中使用父组件传过来的数据
      <div v-for="(hobby, index) in hobbies" :key="index" class="col-xs-6 col-sm-3 placeholder">
        <h4>{{hobby}}</h4>  
        <span class="text-muted">
          <a href="#" @click="deleteHobby(index)">删除</a>
        </span>
      </div>
  </div>`
    window.Dashboard = {
      // 声明当前子组件接收父组件传递的属性
        props: ['hobbies'],
        template // template: template
    }
})()

上面的是使用方式一的方法传值,接下来看看方式二和方式三

父组件

;(function () {
    const template = `<div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
        // 往子组件home-list里传值
        <home-list :empList="empList" :deleteEmp="deleteEmp"></home-list>
      </div>`
    window.AppHome = {
        template, // template: template,
        data () { // 定义父组件往子组件里传的内容
            return {
                empList: [
                    {id: 1, name: '小1', salary: '80001'},
                    {id: 2, name: '小2', salary: '80002'},
                    {id: 3, name: '小3', salary: '80003'},
                    {id: 4, name: '小4', salary: '80004'},
                    {id: 5, name: '小5', salary: '80005'}
                ]
            }
        },
        components: { //Dashboard,HomeList 作为AppHome 的子组件
            Dashboard, // Dashboard: Dashboard
            HomeList // HomeList:HomeList
        }
    }
})()

子组件HomeList

;(function () {
    const template = `<div class="table-responsive">
    <table class="table table-striped">
      <thead>
        <tr>
          <th>ID</th>
          <th>姓名</th>
          <th>工资</th>
          <th>操作</th>
        </tr>
      </thead>
      <tbody>
          <!-- 这里还有一个子组件Item -->
        <Item v-for="(emp, index) in empList" :key="emp.id" :emp="emp" :deleteEmp="deleteEmp" :index="index"/>
      </tbody>
    </table>
  </div>`
    window.HomeList = {
<!-- 声明当前子组件接收父组件传递的属性 -->
        props: {
          empList: Array,
          deleteEmp: Function
        },
        template, 
        components: { <!-- 子组件Item -->
          Item 
        }
    }
})()

子组件Item

;(function () {
    const template = `<tr>
    <td>{{emp.id}}</td>
    <td>{{emp.name}}</td>
    <td>{{emp.salary}}</td>
  </tr>`
  window.Item = {
      props: {
        emp: { // 指定属性名/数据类型/是否必须 
            type: Object,
            required: true
        },
        deleteEmp: Function,
        index: Number
      },
      template
  }
})()


自定义事件


在父组件中定义事件监听函数,并引用子组件标签上 v-on 绑定事件监听。

<!-- 通过  v-on 绑定 -->
<!-- @自定义事件名=事件监听函数 -->
<!-- 在子组件 dashboard中触发 delete_hobby 事件来调用 deleteHobby函数 -->
<dashboard @delete_hobby ="deleteHobby"></dashboard>

在子组件中触发父组件的监听事件函数调用

<!-- 子组件触发事件函数调用 -->
<!-- this.$emit(自定义事件名,data) -->
this.$emit("delete_hobby",name)

注意:

自定义事件只用于子组件向父组件发送数据

隔代组件或兄弟组件间通信此种方式不合适,使用 props

案例

父组件

<!-- 父组件,其余的代码省略-->
<!-- @自定义事件名=事件监听函数 -->
<!-- 在子组件 dashboard 中触发了 delete_hobby 事件来调用 deleteHobby 函数  -->
<dashboard @delete_hobby="deleteHobby" :hobbies="hobbies"></dashboard>
<script>
  new Vue({
        data(){
            return {
                hobbies: ["吃饭","睡觉","打豆豆"]
                }
        },
        methods: {
            deleteHobby(){
            }
        }
   })
</script>

子组件

<!-- 子组件,其余的代码省略-->
<div @click="deleteHobby(index)"></div>
<script>
  new Vue({
        data(){
            return {
                }
        },
        prrops: ["hobbies"]
        methods: {
            deleteHobby(index){
            <!-- 触发父组件 delete_hobby 事件进行删除操作-->
                this.$emit('delete_hobby',index)
            }
        }
   })
</script>

相关文章
|
1天前
|
JavaScript
如何在 Vue 项目中选择合适的模块格式
【10月更文挑战第20天】选择合适的模块格式需要综合考虑多个因素,没有一种绝对正确的选择。需要根据项目的具体情况进行权衡和分析。在实际选择过程中,要保持灵活性,根据项目的发展和变化适时调整模块格式。
14 7
|
1天前
|
JavaScript 前端开发 编译器
在 Vue 项目中使用 ES 模块格式的优点
【10月更文挑战第20天】在 Vue 项目中使用 ES 模块格式具有众多优点,这些优点共同作用,使得项目能够更高效、更可靠地开发和运行。当然,在实际应用中,还需要根据项目的具体情况和需求进行合理的选择和配置。
14 6
|
1天前
|
JavaScript 前端开发 开发者
Vue 的优缺点
【10月更文挑战第16天】Vue 具有众多优点,使其成为前端开发中备受青睐的框架之一。尽管它也存在一些局限性,但通过合理的应用和技术选型,这些问题可以得到一定程度的解决。在实际项目中,开发者可以根据项目的需求和特点,权衡 Vue 的优缺点,选择最适合的技术方案。同时,随着 Vue 不断的发展和完善,相信它将在前端开发领域继续发挥重要作用。
11 6
|
1天前
|
前端开发 UED
vue3知识点:Suspense组件
vue3知识点:Suspense组件
11 4
|
1天前
|
JavaScript 前端开发 Java
《vue3第五章》新的组件,包含:Fragment、Teleport、Suspense
《vue3第五章》新的组件,包含:Fragment、Teleport、Suspense
10 2
|
1天前
|
Java
vue3知识点:Teleport组件
vue3知识点:Teleport组件
10 1
|
3天前
|
JavaScript
在 Vue 中处理组件选项与 Mixin 选项冲突的详细解决方案
【10月更文挑战第18天】通过以上的分析和探讨,相信你对在 Vue 中使用 Mixin 时遇到组件选项与 Mixin 选项冲突的解决方法有了更深入的理解。在实际开发中,要根据具体情况灵活选择合适的解决方案,以确保代码的质量和可维护性。
27 7
|
3天前
|
存储 JavaScript
vue——store全局存储
【10月更文挑战第18天】Vuex 是 Vue.js 应用中非常重要的一个工具,它为我们提供了一种有效的状态管理方式。通过合理地使用 Vuex,我们可以更好地组织和管理应用的状态,提高应用的开发效率和质量。
15 1
|
2天前
|
缓存 JavaScript UED
Vue 的动态组件与 keep-alive
【10月更文挑战第19天】总的来说,动态组件和 `keep-alive` 是 Vue.js 中非常实用的特性,它们为我们提供了更灵活和高效的组件管理方式,使我们能够更好地构建复杂的应用界面。深入理解和掌握它们,以便在实际开发中能够充分发挥它们的优势,提升我们的开发效率和应用性能。
29 18
|
1天前
|
JavaScript 索引
vue 在 v-for 时给每项元素绑定事件
在 Vue 中使用 v-for 渲染列表时,可以通过给每项元素绑定事件来实现交互功能。通常使用 `@click` 等事件修饰符,结合方法或内联表达式来处理事件。例如:`&lt;li v-for=&quot;item in items&quot; @click=&quot;handleClick(item)&quot;&gt;{{ item }}&lt;/li&gt;`。