Vue--.sync--使用/教程/实例

原文网址:Vue--.sync--使用/教程/实例_IT利刃出鞘的博客-CSDN博客

简介

说明

        本文用示例介绍vue的.sync的用法。

        .sync本质上是语法糖,是对事件的封装。

官网

自定义事件 — Vue.js

Vue的props只能父组件向子组件传值

        有时需要对一个 prop 进行“双向绑定”,也就是:父子组件双向通信。

       但是,vue组件间的传值都是单向数据流:父组件值更新更新会传到子组件,但反过来不行。按官网的 单向数据流 解释:所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。

        vue的prop是单向数据流的原因:真正的双向绑定会带来维护上的问题;若子组件可以变更父组件,且在父组件和子组件都没有明显的变更来源会导致应用的数据流向难以理解。

        最常见的就是在公共组件中(如计数器、单选按钮)中,子组件(计数器)把父组件传来的数字展示出来。在点击子组件的添加按钮时,因为单向数据流的原因,不能直接在子组件中给数字+1。

.sync的用法

本质是个语法糖(一个缩写)

在一个包含 title prop 的子组件中,可以用以下方法表达对其赋新值的意图:

this.$emit('update:title', newTitle)

然后父组件可以监听那个事件并根据需要更新一个本地的数据 property。例如:

<text-document
  v-bind:title="doc.title"
  v-on:update:title="doc.title = $event"
></text-document>

为了方便起见,我们为这种模式提供一个缩写,即 .sync 修饰符:

<text-document v-bind:title.sync="doc.title"></text-document>

一个对象可以设置多个prop

        用一个对象同时设置多个 prop 的时候,也可以将这个 .sync 修饰符和 v-bind 配合使用: 

<text-document v-bind.sync="doc"></text-document>

        这样会把 doc 对象中的每一个 property (如 title) 都作为一个独立的 prop 传进去,然后各自添加用于更新的 v-on 监听器。 

不能与表达式一起用

        带有 .sync 修饰符的 v-bind 不能和表达式一起使用 (例: v-bind:title.sync=”doc.title + ‘!’” 是无效的)。只能提供你想要绑定的 property 名,类似 v-model。 

不能用于字面量对象

        不能将 v-bind.sync 用在一个字面量的对象上,例如 v-bind.sync=”{ title: doc.title }”。因为在解析一个像这样的复杂表达式的时候,有很多边缘情况需要考虑。

示例

        本文以计数器为例,说明子组件给父组件传递数据的方案。

        在公共组件中(如计数器、单选按钮)中,子组件(计数器)把父组件传来的数字展示出来。在点击子组件的添加按钮时,父组件可以给数字+1(间接地)。

代码

Parent.vue

<template>
  <div class="outer">
    <p>Parent</p>
    <p>count: {{ count }}</p>
    <child v-bind:count="count" v-on:update:count="count = $event"></child>
  </div>
</template>

<script>
import Child from "./Child";
export default {
  components: {Child},
  data() {
    return {
      count: 0,
    }
  },
}
</script>

<style scoped>
.outer {
  margin: 20px;
  border: 2px solid red;
  padding: 20px;
}
</style>

Child.vue

<template>
  <div class="outer">
    <p>child</p>
    <button @click="updateCount">You click me {{count}} times</button>
  </div>
</template>

<script>
export default {
  props: ['count'],
  methods: {
    updateCount() {
      this.$emit('update:count', +this.count + 1);
    },
  }
}
</script>

<style scoped>
.outer {
  margin: 20px;
  border: 2px solid blue;
  padding: 20px;
}
</style>

路由(router/index.js)

import Vue from 'vue'
import Router from 'vue-router'
import Parent from "../components/Parent";

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/parent',
      name: 'Parent',
      component: Parent,
    }
  ],
})

测试

访问:http://localhost:8080/#/parent

  • 15
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IT利刃出鞘

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值