关于Vue中props的详解

本文详细介绍了Vue.js组件的Props机制,包括作用域、基本用法、camelCase与kebab-case的区别、单向数据流、Props验证、$parent的使用及注意事项。通过实例演示了如何在父子组件间传递数据。

看一下官方文档:

组件实例的作用域是孤立的。这意味着不能 (也不应该) 在子组件的模板内直接引用父组件的数据。父组件的数据需要通过 prop 才能下发到子组件中。

也就是props是子组件访问父组件数据的唯一接口。

详细一点解释就是:

一个组件可以直接在模板里面渲染data里面的数据(双大括号)。

子组件不能直接在模板里面渲染父元素的数据。

如果子组件想要引用父元素的数据,那么就在prop里面声明一个变量(比如a),这个变量就可以引用父元素的数据。然后在模板里渲染这个变量(前面的a),这时候渲染出来的就是父元素里面的数据。
 

1. 基本用法

图1-props

    <div id="app1">
        <!-- hello引用父元素的hello,它也可以引用message,greet,world等 -->
        <child :hello='hello'></child>
    </div>
    <script>
        var com1 = Vue.component('child',{
            // 声明在prop中的变量可以引用父元素的数据
            props:['hello'],
           // 这里渲染props中声明的那个hello
            template:'<div><p>{{ hello }}</p></div>',
        })

        var app1 = new Vue ({
            el: '#app1',
            data: {
                greet: {
                    hello:'hello,',
                    world: 'world',
                },
                message: 'message1',
            }
        })
    </script>

2. camelCase vs. kebab-case:js中用驼峰式命名,在html中替换成短横线分隔式命名

<!-- 在 HTML 中使用 kebab-case -->
<child my-message="hello!"></child>

<script>
    Vue.component('child', {
        // 在 JavaScript 中使用 camelCase
        props: ['myMessage'],
        template: '<span>{{ myMessage }}</span>'
    })
</script>

3.单向数据流: props是单向绑定的

当父组件的属性变化时,将传导给子组件,但是反过来不会。

每次父组件更新时,子组件的所有 prop 都会更新为最新值。

不要在子组件内部改变 prop。如果你这么做了,Vue 会在控制台给出警告。

在两种情况下,我们很容易忍不住想去修改 prop 中数据:

  1. Prop 作为初始值传入后,子组件想把它当作局部数据来用;
  2. Prop 作为原始数据传入,由子组件处理成其它数据输出。

对这两种情况,正确的应对方式是:
定义一个局部变量,并用 prop 的值初始化它:

    props: ['initialCounter'],
    data: function () {
      return { counter: this.initialCounter }
    }
    

定义一个计算属性,处理 prop 的值并返回:

    props: ['size'],
    computed: {
      normalizedSize: function () {
        return this.size.trim().toLowerCase()
      }
    }

 
注意在 JavaScript 中对象和数组是引用类型,指向同一个内存空间,如果 prop 是一个对象或数组,在子组件内部改变它会影响父组件的状态。

举个例子:

    <div id="app3">
        <my-component :object='object'></my-component>
    </div>
    <script src="http://vuejs.org/js/vue.min.js"></script>
    <script>
        //
        var mycom = Vue.component('my-component', {
            //添加一个input改变子组件的childOject,那么父元素的object也会被改变,但是Vue没有报错!
            template: '<p>{{ object.name }} is {{ object.age }} years old.<br><input v-model="childObject.name" type="text"></p>',
            props: ['object','school'],
            data: function () {
                // 子组件的childObject 和 父组件的object 指向同一个对象
                return {
                    childObject: this.object
                }
            }
        });
        var app3 = new Vue({
            el: '#app3',
            data: {
                object:{
                    name: 'Xueying',
                    age: '21',
                },
                school:'SCUT',
            },
        })
    </script>

图2-改变childObject.name,object.name也改变

图3-控制台输出app3.object.name

4. props验证

可以为prop指定验证规则,如果传入的数据不符合要求,Vue会发出警告。

具体验证规则见官方文档:Prop验证规则
 

5. $parent

$parent 也可以用来访问父组件的数据。

而且子组件可以通过$parent 来直接修改父组件的数据,不会报错!

可以使用props的时候,尽量使用props显式地传递数据(可以很清楚很快速地看出子组件引用了父组件的哪些数据)。

另外在一方面,直接在子组件中修改父组件的数据是很糟糕的做法,props单向数据流就没有这种顾虑了。

### Vue.jsProps 的详细用法与解析 #### 1. Props 的基本概念 在 Vue.js 中,组件之间的通信是通过 `props` 实现的。`props` 是子组件接收父组件数据的一种方式,可以看作是组件的参数[^1]。这些参数由父组件传递给子组件,并且在子组件中通过 `props` 选项进行定义和接收。 #### 2. Props 的定义与使用 `props` 的定义可以通过以下几种方式进行: - **基础类型检查**: 子组件可以通过简单的类型声明来验证传入的数据类型。例如: ```javascript props: { propA: Number } ``` 这里 `propA` 被定义为一个 `Number` 类型的数据[^3]。 - **多种可能的类型**: 如果某个 `prop` 可以接受多种类型的值,则可以将其定义为一个数组: ```javascript props: { propB: [String, Number] } ``` 这表示 `propB` 可以是字符串或数字[^2]。 - **必填的属性**: 如果某个 `prop` 是必须的,可以通过设置 `required` 属性为 `true` 来强制要求: ```javascript props: { propC: { type: String, required: true } } ``` 这样,如果父组件没有传递 `propC`,Vue 会抛出警告[^3]。 - **带有默认值的属性**: 如果某个 `prop` 没有被父组件传递,可以为其设置默认值: ```javascript props: { propD: { type: Number, default: 100 } } ``` 当 `propD` 没有被传递时,其默认值为 `100`。 - **对象或数组的默认值**: 对于对象或数组类型的 `prop`,默认值必须通过工厂函数返回: ```javascript props: { propE: { type: Object, default: function () { return { message: 'hello' } } } } ``` 这是为了避免多个实例共享同一个默认对象或数组。 - **自定义验证函数**: 可以为 `prop` 定义一个验证函数,确保传入的值符合特定规则: ```javascript props: { propF: { validator: function (value) { return ['success', 'warning', 'danger'].indexOf(value) !== -1; } } } ``` 这里 `propF` 的值必须是 `'success'`、`'warning'` 或 `'danger'` 中的一个[^2]。 #### 3. Props 的校验机制 Vue 在组件初始化时会对 `props` 进行校验。校验过程包括遍历 `propsOptions` 并调用 `validateProp(key, propsOptions, propsData, vm)` 方法来确认传入的数据是否符合定义的规范[^5]。如果校验失败,Vue 会在开发环境中输出警告信息。 #### 4. 示例代码 以下是一个完整的父子组件通信示例: ```html <div id="app"> <parent></parent> </div> <script> var childNode = { template: `<div>{{ forChildMsg }}</div>`, props: { forChildMsg: { type: Number, required: true } } }; var parentNode = { template: ` <div class="parent"> <child :for-child-msg="msg"></child> </div> `, components: { child: childNode }, data() { return { msg: 123456 }; } }; new Vue({ el: "#app", components: { parent: parentNode } }); </script> ``` 在这个例子中,`parentNode` 将 `msg` 作为 `prop` 传递给 `childNode`,并且 `childNode` 对 `forChildMsg` 进行了类型和必填性的校验[^4]。 #### 5. 注意事项 - 父组件传递的 `props` 是单向绑定的,这意味着父组件的数据变化会触发子组件更新,但子组件不能直接修改 `props` 的值[^1]。 - 如果需要在子组件中修改 `props` 的值,应该创建一个局部变量并将其与 `props` 值同步[^3]。 --- ###
评论 12
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值