Vue 中的 Props 与 Data 细微差异,你知道吗?

做者:Michael Thiessen
译者:前端小智
来源:medium
点赞再看,养成习惯

本文 GitHub https://github.com/qq44924588... 上已经收录,更多往期高赞文章的分类,也整理了不少个人文档,和教程资料。欢迎Star和完善,你们面试能够参照考点复习,但愿咱们一块儿有点东西。html

Vue提供了两种不一样的存储变量:propsdata前端

这些方法一开始可能会让人感到困惑,由于它们作的事情很类似,并且也不清楚什什么时候使用props,什么时候使用datavue

那么propsdata有什么区别呢?react

data是每一个组件的私有内存,能够在其中存储须要的任何变量。props是将数据从父组件传递到子组件的方式。git

在本文中,咱们将学习到:github

  • 什么是props,为何这些数据只向下流动,而不是向上
  • data 选项的用途
  • 响应式是什么
  • 如何避免 propsdata 之间的命名冲突
  • 如何将 propsdata 结合使用

什么是 props

在Vue中,props(或properties)是咱们将数据从父组件向下传递到其子组件的方式。面试

当咱们使用组件构建应用程序时,最终会构建一个称为树的数据结构。 相似于家谱,具备:微信

  • 父母
  • 孩子
  • 祖先
  • 子孙

数据从根组件(位于最顶端的组件)沿着树向下流动。就像基因是如何代代相传的同样,父组件也会将本身的props传给了他们的孩子。数据结构

在Vue中,咱们在代码的<template>中向组件添加了一些propsapp

<template>
  <my-component cool-prop="hello world"></my-component>
</template>

在这个例子中,咱们传递一个名为color-prop prop,其值为“hello world”。咱们可以从my-component内部访问这个值。

然而,当咱们从组件内部访问props时,咱们并不拥有它们,因此咱们不能更改它们(就像你不能改变你父母给你的基因同样)。

注意:虽然能够更改组件中的属性,但这是一个很是糟糕的主意。最终还会更改父类正在使用的值,这可能会致使不少混淆。

可是有些状况咱们须要改变变量,因此 data 就派上用场了。

什么是 data ?

data是每一个组件的内存,这是存储数据和但愿跟踪的任何其余变量的地方。

若是咱们正在构建一个计数器应用程序,咱们将须要跟踪计数,所以咱们将向咱们的data添加一个count:

<template>
  <div>
    {{ count }}
    <button @click="increment">+</button>
    <button @click="decrement">-</button>
  </div>
</template>
------------------------------------------
export default {
  name: 'Counter',
  data() {
    return {
      // Initialized to zero to begin
      count: 0,
    }
  },
  methods: {
    increment() {
      this.count += 1;
    },
    decrement() {
      this.count -= 1;
    }
  }
}

此处的data是私有的,仅供组件自己使用,其余组件不能访问它。

注意:理论上是其它组件是不能访问这些数据,但实际是能够的。可是出于一样的缘由,这样作是很是糟糕的

若是须要向组件传递数据,可使用props向下传递数据(传递给子组件),或者使用事件向上传递数据(传递给父组件)。

props 和 data 都是响应式的

使用 Vue,咱们不须要过多地考虑组件何时会更新,Vue 会自动帮咱们作好,由于 Vue 是响应式的。

咱们没必要每次更改 data 都调用setState,只需更改data便可! 只要要更新具备响应式的属性(props,computed 及 data 中的任何值),Vue 就会知道它什么时候发生变化。

回到计数器应用程序,咱们仔细看看这里面的方法

methods: {
  increment() {
    this.count += 1;
  },
  decrement() {
    this.count -= 1;
  }
}

咱们所要作的就是更新count,Vue 会检测到这个变化,而后用新值从新渲染咱们的应用程序

Vue 的响应系统有不少细微的差异,若是你想要高效地使用Vue,理解它是很是重要的。若是你想更深刻地了解Vue的响应系统,这里有更多要了解的东西。

避免命名冲突

Vue所作的另外一件事是,使开发工做变得更好一点。

咱们在组件上定义一些 propsdata

export default {
  props: ['propA', 'propB'],
  data() {
    return {
      dataA: 'hello',
      dataB: 'world',
    };
  },
};

若是要在方法内部访问它们,则没必要使用this.props.propAthis.data.dataA。 Vue 让咱们彻底省略了 propsdasta,只剩下了更整洁的代码。

咱们可使用this.propAthis.dataA访问它们:

methods: {
  coolMethod() {
    // Access a prop
    console.log(this.propA);

    // Access our data
    console.log(this.dataA);
  }
}

所以,若是咱们不当心在dataprops中使用相同的名称,则会遇到问题。

若是发生这种状况,Vue 会给你一个警告,由于它不知道你想访问哪一个。

export default {
  props: ['secret'],
  data() {
    return {
      secret: '1234',
    };
  },
  methods: {
    printSecret() {
      // 咱们想要哪个?
      console.log(this.secret);
    }
  }
};

当咱们同时使用propsdata时,Vue 的神奇之处就产生了。

props 和 data 一块儿使用

既然咱们已经看到了 propsdata 的不一样之处,让咱们来看看为何咱们须要两个,经过创建一个基本的应用程序。

咱们将使用名为ContactInfo的组件显示此信息:

// ContactInfo
<template>
  <div class="container">
    <div class="row">
      Email: {{ emailAddress }}
      Twitter: {{ twitterHandle }}
      Instagram: {{ instagram }}
    </div>
  </div>
</template>
-------------------------------------
export default {
  name: 'ContactInfo',
  props: ['emailAddress', 'twitterHandle', 'instagram'],
};

ContactInfo组件接受 props:emailAddresstwitterHandleinstagram,并将其显示在页面上。

咱们的我的资料页面组件ProfilePage以下所示:

// ProfilePage
<template>
  <div class="profile-page">
    <div class="avatar">
      <img src="user.profilePicture" />
      {{ user.name }}
    </div>
  </div>
</template>
-------------------------------------------------
export default {
  name: 'ProfilePage',
  data() {
    return {
      // In a real app we would get this data from a server
      user: {
        name: 'John Smith',
        profilePicture: './profile-pic.jpg',
        emailAddress: 'john@smith.com',
        twitterHandle: 'johnsmith',
        instagram: 'johnsmith345',
      },
    }
  }
};

咱们的ProfilePage组件目前显示用户的配置文件图片及其名称,它还有用户数据对象。

咱们如何从父组件(ProfilePage)向下获取数据到子组件(ContactInfo)

咱们必须使用 props 传递数据。

首先,咱们须要将ContactInfo组件导入ProfilePage组件

// Import the component
import ContactInfo from './ContactInfo.vue';

export default {
  name: 'ProfilePage',

  // Add it as a dependency
  components: {
    ContactInfo,
  },

  data() {
    return {
      user: {
        name: 'John Smith',
        profilePicture: './profile-pic.jpg',
        emailAddress: 'john@smith.com',
        twitterHandle: 'johnsmith',
        instagram: 'johnsmith345',
      },
    }
  }
};

其次,咱们必须在<template>中添加组件:

// ProfilePage
<template>
  <div class="profile-page">
    <div class="avatar">
      <img src="user.profilePicture" />
      {{ user.name }}
    </div>

    <!-- Add component in with props -->
    <contact-info
      :email-address="emailAddress"
      :twitter-handle="twitterHandle"
      :instagram="instagram"
    />

  </div>
</template>

如今ContactInfo须要的全部用户数据都将沿着组件树向下流动,并从ProfilePage进入ContactInfo

咱们将数据保存在ProfilePage而不是ContactInfo中的缘由是ProfilePage页面的其余部分须要访问user对象。

因为数据只向下流,这意味着咱们必须将数据放在组件树中足够高的位置,以便它能够向下流到须要去的全部位置。


代码部署后可能存在的BUG无法实时知道,过后为了解决这些BUG,花了大量的时间进行log 调试,这边顺便给你们推荐一个好用的BUG监控工具 Fundebug

原文:https://medium.com/js-dojo/vu...


交流

文章每周持续更新,能够微信搜索「 大迁世界 」第一时间阅读和催更(比博客早一到两篇哟),本文 GitHub https://github.com/qq449245884/xiaozhi 已经收录,整理了不少个人文档,欢迎Star和完善,你们面试能够参照考点复习,另外关注公众号,后台回复福利,便可看到福利,你懂的。

相关文章
相关标签/搜索