vue 提供了两种不同的存储变量: props 和 data. 那么 Vue 中 Props 和 Data 之间有什么区别? 下面本篇文章给大家介绍一下 Vue 中的 Props 与 Data 细微差别, 希望对大家有所帮助.
Vue 提供了两种不同的存储变量: props 和 data.
这些方法一开始可能会让人感到困惑, 因为它们做的事情很相似, 而且也不清楚什何时使用 props, 何时使用 data.
那么 props 和 data 有什么区别呢?
data 是每个组件的私有内存, 可以在其中存储需要的任何变量. props 是将数据从父组件传递到子组件的方式.
在本文中, 我们将学习到:
什么是 props, 为什么这些数据只向下流动, 而不是向上
data 选项的用途
响应式是什么
如何避免 props 和 data 之间的命名冲突
如何将 props 和 data 结合使用
什么是 props
在 Vue 中, props(或 properties)是我们将数据从父组件向下传递到其子组件的方式.
当我们使用组件构建应用程序时, 最终会构建一个称为树的数据结构. 类似于家谱, 具有:
父母
孩子
祖先
子孙
数据从根组件 (位于最顶端的组件) 沿着树向下流动. 就像基因是如何代代相传的一样, 父组件也会将自己的 props 传给了他们的孩子.
在 Vue 中, 我们在代码的 < template > 中向组件添加了一些 props
- <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 的响应系统, 这里 https://vuejs.org/v2/guide/reactivity.html 有更多要了解的东西.
避免命名冲突
Vue 所做的另一件事是, 使开发工作变得更好一点.
我们在组件上定义一些 props 和 data
- export default {
- props: ['propA', 'propB'],
- data() {
- return {
- dataA: 'hello',
- dataB: 'world',
- };
- },
- };
如果要在方法内部访问它们, 则不必使用 this.props.propA 或 this.data.dataA. Vue 让我们完全省略了 props 和 dasta, 只剩下了更整洁的代码.
我们可以使用 this.propA 或 this.dataA 访问它们:
- methods: {
- coolMethod() {
- // Access a prop
- console.log(this.propA);
- // Access our data
- console.log(this.dataA);
- }
- }
因此, 如果我们不小心在 data 和 props 中使用相同的名称, 则会遇到问题.
如果发生这种情况, Vue 会给你一个警告, 因为它不知道你想访问哪个.
- export default {
- props: ['secret'],
- data() {
- return {
- secret: '1234',
- };
- },
- methods: {
- printSecret() {
- // 我们想要哪一个?
- console.log(this.secret);
- }
- }
- };
当我们同时使用 props 和 data 时, Vue 的神奇之处就产生了.
props 和 data 一起使用
既然我们已经看到了 props 和 data 的不同之处, 让我们来看看为什么我们需要两个, 通过建立一个基本的应用程序.
我们将使用名为 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:emailAddress,twitterHandle 和 instagram, 并将其显示在页面上.
我们的个人资料页面组件 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 对象.
由于数据只向下流, 这意味着我们必须将数据放在组件树中足够高的位置, 以便它可以向下流到需要去的所有位置.
本文转载自: https://segmentfault.com/a/1190000021651417
更多 web 前端开发 https://www.html.cn/ 知识, 请查阅 HTML 中文网 !!
来源: http://www.css88.com/web/vue-js/17249.html