zoukankan      html  css  js  c++  java
  • 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的响应系统,这里有更多要了解的东西。

    避免命名冲突

    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 的神奇之处就产生了。

    电脑刺绣绣花厂 http://www.szhdn.com 广州品牌设计公司https://www.houdianzi.com

    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对象。

    由于数据只向下流,这意味着我们必须将数据放在组件树中足够高的位置,以便它可以向下流到需要去的所有位置。

  • 相关阅读:
    Vue项目style样式层下载less-loader时候遇到的坑
    用git上传项目到github遇到的问题和解决方法
    git命令大全
    npm run dev 报错:missing script:dev
    sessionStorage缓存数据
    RTL基本知识:编译命令指定隐性线网类型
    RTL基本知识:线网的隐性声明
    物理综合:关于UDSM后端设计总结
    RTL基本知识:task和function
    物理综合:Timing_budgeting
  • 原文地址:https://www.cnblogs.com/xiaonian8/p/13825903.html
Copyright © 2011-2022 走看看