04、Vue props 属性


本节大纲

版权声明:本文为博主原创文章,未经博主允许不得转载

PS:转载请注明出处
作者: TigerChain
本文出自 TigerChain 手把手教Vue

教程简介

  • 1、阅读对象
    本篇教程适合新手阅读,老手直接略过
  • 2、教程难度
    初级,本人水平有限,文章内容难免会出现问题,如果有问题欢迎指出,谢谢
  • 3、Demo 地址:https://github.com/tigerchain/vue-lesson 请看 03、Vue–props属性这一节

正文

一、v-bind 指令

在说 props 之前,我们先说说 v-bind 这个指令

1、什么是 v-bind?

v-bind 用来动态的绑定一个或多个属性,或一个组件的 prop ,比如绑定图片地址、标签的样式等,v-bind 的缩写是 :

2、v-bind 的用法

比如,我们给 img 一个图片资源地址

<img v-bind:src="imageSrc"/>

再比如,我给一个 div 设置 css 样式,如下

<div v-bind:class="{divstyle:isShowStyle}"></div>

<style>
 .divstyle {
    background-color: red;
 }
</style>

<script>
 var vm = new Vue({
   el:"#root",
   data:{
      // 如果 isShowStyle 为 true 的话,那么 
      // v-bind:class="{divstyle:isShowStyle}" 表示此 div 的 class 就是 divstyle
      isShowStyle:true
   }
 })
</script>

等等,拿官方的举例来说,v-bind 可以绑定属性「以数据驱动」,在绑定 class 或 style「内联样式」 的时候支持数据或对象,以下是官方举例基本上把 v-bind 的使用场景介绍完了,html 的属性只能使用 v-bind 来绑定「除非你使用原生写法,不使用 v-bind」

<!-- 绑定一个属性 -->
<img v-bind:src="imageSrc">

<!-- 缩写 -->
<img :src="imageSrc">

<!-- 内联字符串拼接 -->
<img :src="'/path/to/images/' + fileName">

<!-- class 绑定 -->
<div :class="{ red: isRed }"></div>
<div :class="[classA, classB]"></div>
<div :class="[classA, { classB: isB, classC: isC }]">

<!-- style 绑定 -->
<div :style="{ fontSize: size + 'px' }"></div>
<div :style="[styleObjectA, styleObjectB]"></div>

<!-- 绑定一个有属性的对象 -->
<div v-bind="{ id: someProp, 'other-attr': otherProp }"></div>

<!-- 通过 prop 修饰符绑定 DOM 属性 -->
<div v-bind:text-content.prop="text"></div>

<!-- prop 绑定。“prop”必须在 my-component 中声明。-->
<my-component :prop="someThing"></my-component>

<!-- 通过 $props 将父组件的 props 一起传给子组件 -->
<child-component v-bind="$props"></child-component>

<!-- XLink -->
<svg><a :xlink:special="foo"></a></svg>

3、写个 demo 感受一下吧,这里直接在 script 引入 vue.js 来写

  • 1、核心代码如下:
<body>
  <div id="container">
    <!-- 第一种写法 其中 img 是宽度为 35 的 style 样式-->
    <img v-bind:src="imgSrc" v-bind:class="{'img':show}" >
    <!-- 第二种写法 -->
    <img v-bind:src="'https://tigerchain.oss-cn-hangzhou.aliyuncs.com/vue/imgs/logo.png'" v-bind:style="imgStyle" >
    <p v-bind:style="{color:'red'}">{{msg}}</p>
    <!-- 标签的属性的都可以使用 v-bind 替换 -->
    <input v-bind:type="'text'"  v-bind:placeholder="'输入内容'" v-model="clickBtnText"><!-- :value="''"  和 v-model 同时出现会报错-->
    {{clickBtnText}} <br/>
    <!-- 这里是行内样式 -->
    <input type="button" value="测试" v-bind:style="{'margin-top':'10px'}">
  </div>
  <script>
    // 定义一个样式
    var imgStyle = {
      height: '40px',
      width: '40px'
    }

    var vm = new Vue({
      el: '#container',
      data: {
        msg:"123",
        imgStyle:imgStyle,
        imgSrc:'https://tigerchain.oss-cn-hangzhou.aliyuncs.com/vue/imgs/logo.png',
        show:true,
        clickBtnText:''
      }
    })
  </script>
</body>
  • 2、查看结果

v-bind 结果

我们看到我们使用 v-bind 设置图片,设置样式「行内样式和行外样式」,并且代替 html 原有的属性等,并且成功显示,调试窗口也没有报错

二、props 属性

Vue 和 React 一样,是使用 props「单向数据流」 来传递数据的「父组件的数据传递给后代组件」,props 在本组件中是不能修改的「和 React 也是一毛一样」

1、一般格式

我们知道组件有四种格式,不管那种格式 props 用法都是相同的,这里以全局组件为例子

Vue.component('customcomponent',{
    // 定义接收的 props 等待父组件传递
    props:['message'],
    template: '{{message}}',
    ... 数据和方法等省略

})

2、直接写代码感受一下

在以下 demo 中,我们使用 props 来传递字符串、对象、样式来感受一下 props

  • 1、直接在上面的代码基础上修改,添加以下代码
<hr>
<h4>以下是 props 例子</h4>
<div id="app2">
<!-- 如果要使用 props 来传递对象,就要使用 v-bind  -->
<mycomponent message="你好" :mydata="{username:'tigerchain',age:28}" name-style="color:red"></mycomponent>
</div>

<script>
// 定义一个组件
var myComponent = Vue.extend({
  // 定义 props 
  props: {
    message:"",
    mydata:{},
    //样式 ,如果这里使用驼峰标识 ,则在标签中使用就要使用 name-style 传递
    nameStyle:{}
  },
  template: '<div>{{ message }} <div> <span v-bind:style="nameStyle">{{ mydata.username}}</span></div> </div>'
})

// 全局注册组件 组件的别名要是小写,否则会报错
Vue.component('mycomponent', myComponent)

var vm2 = new Vue({
  el:'#app2',
})
</script>

为了便于观察,我们重新定义了一个 id 为 app2 的 div 和一个新的 Vue 实例「vm2」 ,我们定义一个组件并且添加如下的 props

添加 props属性

在使用组件的时候就可以传递数据了

props 传递方法

  • 2、运行查看结果

传递 props 结果

我们看到,传递过来的数据完美的接收到并显示出来了,在这里注意以几下几点

  • 如果 props 中声明的是数据是驼峰标识,那么传值的时候就要使用 - 标识

比如 props 中的数据是 myData 那么在组件中传值时就要使用 my-data=”” ,如果没有使用驼峰那不牵扯

  • 在组件中使用 props 传值的时候默认传的是字符串

如果想要传值「比如对象,数据等」那么就要使用 v-bind=”” 来传值,上面的 message 和 mydata 就显示了这两种方式

  • props 中就定义一些默认的值,不能直接修改 props,只能间接的通过 data 来修改「在 data 里面定义数据,值就是 props ,这一点 React 是一样的」,其实 Vue 中的 data 就和 React 中的 state 是一样的

  • props 中的值,我们在 Vue 实例中可以使用 this.props 的值来访问「和仿问 data 是一样的」

三、 props 验证

想要写一个有“良心”的组件,指定 props 的验证规则非常有必要,比如我们在 props 中定义传递过来的 name 必须是字符串否则就发出警告「这对使用插件的人来说是非常友好的」

1、验证规则

直接引用官方的验证规则吧

 props: {
    // 基础类型检测 (`null` 指允许任何类型)
    propA: Number,
    // 可能是多种类型
    propB: [String, Number],
    // 必传且是字符串
    propC: {
      type: String,
      // 必须传
      required: true
    },
    // 数值且有默认值
    propD: {
      type: Number,
      default: 100
    },
    // 数组/对象的默认值应当由一个工厂函数返回
    propE: {
      type: Object,
      default: function () {
        return { message: 'hello' }
      }
    },
    // 自定义验证函数
    propF: {
      validator: function (value) {
        return value > 10
      }
    }
  }

其中 type 有以下几种类型:

  • String:字符串
  • Number:数字
  • Boolean: boolean 类型
  • Function: props 能传递方法,这样的话,组件方法的回调是非常 easy 的
  • Object: 对象
  • Array: 数组
  • Symbol: 原始类型

2、写段代码看一下吧,我们在原有代码基础上添加如下代码「红框所示」

props 中添加规则

在这里我们就可以传递方法「实现了方法的回调」,并且规定了 age 只能传递数字,然后再看 vm2 实例中添加方法,如下所示

props-method

那么我们的 show 方法是如何来的呢,细心的朋友会发现,我们在组件中调用了 props 中声明的方法,这个 show 就是我们在使用组件的时候伟递过来的,我们看看代码

<div id="app2">
    <!-- 如果要使用 props 来传递对象,就要使用 v-bind  -->
    <mycomponent
      message="你好"
      :mydata="{username:'tigerchain',age:28}"
      name-style="color:red"
      age="100"
      :clickme="show()"
      />
</div>

由于 clickme 是 props 中规定的必须是方法,所以这里传递一个方法过去,在 vue 实例中直接实现这个方法就 ok 了「这样我们就可以在多组件开发中使用 props 来传递方法来达到方法回调的作用」,并且我们为了验证 age 故意传了一个字符串,我们在 chrome 调试容器能看到报错了,说 age 要传一个数字「这里就不截图了,大家可以自行实验」,上面的例子虽然把方法回调回来了,但是这在实际开发中还是有缺陷的,回调回来的方法没有带个参数「这肯定不能满足常用的开发呀」,我们修改一下上面的代码来实现回调传参

修改一:props 传递方法处

props-pass-funvalue

修改二:调用 props 传参方法

props-pass-vaule-call

修改三:回调方法实现

props-callback-fun

经过以上三处修改,我们就使用 props 来回调子组件的方法「并且带参数」完美实现了

3、显示结果如下
props-pass-fun-callback

我们可以看到,使用 props 传递方法,并且把子组件中的”你好”当作方法参数回传回来

以上我们就把 props 基本上介绍完了,细心的朋友可以发现,我们在 props 中传递方法的时候,未修改之前的方法是带括号的,后面的方法没有带括号,那么这有什么区别呢?再给大家赠送一些 Vue 中的方法的一些知识

四、Vue 中的方法

Vue 中的方法可以定义在 methods 中「这不废话吗」,也可以定义在 data 中,针对于无参数方法可以带括号,也可以不带括号来说明「有参数方法则必须带括号」,那么这些到底有什么区别呢?我们实际写一个例子来总结一下吧

  • 1、新建一个 vue-method.html 文件「并引入 vue.js」

核心代码如下

<h3>Vue 中的方法</h3>
  <div id="container">
    <button v-bind:class="{bg:isShowbgStyle}" @click="testDataFun">在 data 调用 testDataFun 方法</button>
    <button v-bind:class="{bg:isShowbgStyle}" @click="testDataFun()">在 data 调用 testDataFun() 方法</button>
    <button v-bind:class="{bg:isShowbgStyle}" @click="testInMethodsFun">在 methods 调用 testInMethodsFun 方法</button>
    <button v-bind:class="{bg:isShowbgStyle}" @click="testInMethodsFun()">在 data 调用 testInMethodsFun() 方法</button>
  </div>

  <script>
    var vm = new Vue({
      el:"#container",
      data:{
        isShowbgStyle:true,
        testDataFun(){
          console.log(this,arguments)
        }
      },
      methods: {
        testInMethodsFun() {
          console.log(this,arguments)
        }
      }
    })
  </script>
  • 运行查看结果

vue-method

通过 Demo 我们清楚的知道以下结论

  • 1、在 data 或是 methods 中调用无参方法,那么默认会把 Event 对象传递进去,比如上面的 1、3 方法
  • 2、如果想让 this 指向 Vue 实例化的对象,如果在 data 方法调用就必须加上括号
  • 3、在 Vue methods 中的方法不管加参数还是不加参数「带括号或是不带括号」,this 都指向 Vue 的实例化对象
  • 4、综上所术,我们把 Vue 中的方法都放在 methods 中是最好的选择,如果想要想绑定事件,那么不加括号是最好的选择。

有的朋友可能会问了,那我想在 data/methods 中声明方法,既绑定事件又传参数如何搞呢?可以做到吗,肯定可以,我们添加测试代码如下

我们可以使用 $event 显示的把原生事件传递过去,查看一下输出结果

Vue$3 {_uid: 0, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: Vue$3, …} 

Arguments(2) ["msg", MouseEvent, callee: ƒ, Symbol(Symbol.iterator): ƒ]

怎么样,Arguments 参数中第一个是方法参数,第二个就是传递过来的事件,在 data 方法是同理

到此为止,我们把 vue props 就说完了,请大家动手写写感受一下

五、回顾一下

  • v-bind 是用来绑定属性的和 props 传递对象或值使用的「props 默认传递的是字符串,如果想要传值、对象,那么就要使用 v-bind」

  • 如果 props 中声明的是数据是驼峰标识,那么传值的时候就要使用 - 标识

    如:props 中的数据是 myData 那么在组件中传值时就要使用 my-data=”” ,如果没有使用驼峰那不牵扯

  • props 用来定义一些默认值,我们不能直接修改 props 的值,只能通过 data 来间接修改

  • 要写一个”合格”的 vue 组件,那么 props 最好加上验证

  • props 也可以用来传递方法,达到父组件调用子组件方法并且回调的目标

  • vue 中的方法建议写在 methods 中,无参方法调用时就不要加括号

怎么样,说了这么多就这么几个知识点,再次提示一定支动手写一写「感受一下」

作者: TigerChain 公号同名,订阅查看更多内容

本文出自 TigerChain 手把手教Vue

我将源码发布到了 手把手教 Vue 方便大家查看,欢迎大家 fork,喜欢的话给个 star

阅读原文


交个朋友

如果觉得本篇对你有帮助,那么请你完成以下几件小事情

1、动动你的小手关注一下以下公众号「TigerChain」查看更多精彩分享

2、更多视频关注的我的 B站:https://space.bilibili.com/44242327/


文章作者: TigerChain
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 TigerChain !
评论
  目录