#author("2022-09-03T09:12:48+08:00","default:Admin","Admin")
#author("2022-09-30T13:27:16+08:00","default:Admin","Admin")
[[Vue]]

&color(red){※前提条件:本情報はVue 2.0を基づいて説明してる};

#contents

* 概要 [#u0117145]

props主要用于组件的传值,他的工作就是为了接收外面传过来的数据,与data、el、ref是一个级别的配置项。

“prop” 是组件数据的一个字段,期望从父组件传下来。&color(red){子组件需要显式地用 props 选项 声明 props(父组件不需要)};:
#codeprettify{{
Vue.component('child', {
 // 声明 props
 props: ['msg'],
 // prop 可以用在模板内
 // 可以用 `this.msg` 设置
 template: '<span>\{\{ msg \}\}</span>'
})
}}

props在接收数据的同时,对数据进行了类型限制+默认值的指定+必要性的限制
- 类型属性:type:xx
- 必传属性:required:true
- 默认属性:default:xx

props是只读的,vue底层会检测你对props的修改,如果进行了修改,控制台会报错,必须修改,就复制一份到data中,通过data去修改数据。

#codeprettify{{
props:{
    "name":{
        type:String,
        required:true
    },
    "age":{
        type:Number,
        default:18
    },
    "sex":{
        type:String,
        default:'男'
    },
},
}}

type
- Number
- String
- Object
- Boolean

* 示例 [#i107a006]

下面的例子通过 formData 演示了,父组件的值如何传递到子组件里面去了。

父组件

#codeprettify{{
<lForm ref="form" :formData="formData"></lForm>
//通过绑定来进行值的传递

<script>
export default {
  components: { lForm },
  data() {
    return {
      formData:{}
    };
  },
}}

子组件
#codeprettify{{
<template>
  <el-dialog @open="openForm">
    <el-form ref="form" :model="localForm" size="small" label-width="100px" :disabled="disForm">
      <el-form-item label="部门名" prop="label" :rules="$filter_rules({ required: true })">
        <el-input v-model="localForm.label" style="width: 300px;" />
      </el-form-item>

export default {
  props: {
    formData: {
      type: Object,
      default: {},
    },
  },
...

 methods: {
    openForm() {
      this.$nextTick(() => {
        this.localForm = this.formData;
        //不要直接使用 formData ,而是通过其他的变量传递后使用
}}

* $emit [#r462bf6a]

- 父组件可以使用 props 把数据传给子组件。
- 子组件可以使用 $emit,让父组件监听到自定义事件 。
- 父组件可以使用 $ref 调用子组件的方法

 vm.$emit( event, arg ) //触发当前实例上的事件
 vm.$on( event, fn );//监听event事件后运行 fn; 

子组件
#codeprettify{{
<el-select v-model="" :placeholder="" @chenge="doSelect"></select>

methods:{
  doSelect(type){
      var label = this.options.filter(v=>v.value==type)[0].label;
      this.$emit('getLabel',label);
  }  
}
}}

父组件

#codeprettify{{
<ISelect :url="'/comm/com/listAllCompany'"  v-model="" @getLabel="getName">
<ISelect :url="'/comm/com/listAllCompany'"  v-model="" @getLabel="getName" ref="child">

methods{
    getName(data){
       alert(data);//此时的data就是封装的方法中传过来的label
       this.$refs.child.doSelect(xxx); //父组件也可通过这样调用子组件的方法
    }
}
}}

* 注意 [#acef8d88]


** [vue warn][Invalid default value for prop xx: Props with type Object/Array] [#u1429dd0]

props传递数据的时候,默认值如果是数组或者对象,应该使用一个函数返回默认值

#codeprettify{{
formData: {
  type: Object,
  //default: { value: '', label: '', del_flg:1, pid: ''},
  default: ()=> {return { value: '', label: '', del_flg:1, pid: ''} },
},
}}

* 应用场景 [#ya3f3ac7]

** 第二次打开Dialog才能接收到值 [#aaae388d]

***问题描述 [#bed9cae7]

父控件绑定动态值到[[+Vue+el-dialog]],Dialog第一次展示未能接收到值,第二次打开Dialog才能接收到值。

*** 解决方案 [#qcb27d13]

针对不需要动态更新的数据,可采用将绑定值设置为props。并且 default 必须设置

#codeprettify{{
 props: {
    formData: {
      type: Object,
      default: null,
    }
  },
}}

** The data property "value" is already declared as a prop. Use prop default value instead [#rfa0c484]

需要吧子组件接收的的参数变为本地数据。

#codeprettify{{
// 将 prop 数据转换为本地数据
computed: {
  initData: function () {
    return this.fList = this.list;
    //如果子组件接收的是对象或者数组数据,或者说对象里面会有数组数据,因为在我操作过程中打印上面那个本地数据打印出来的是一个数组形式的object,
    //后来发现了问题,需要对本地数据还要进行一个转化。
    //利用 JSON.stringify 和 JSON.parse() 来进行隔离,相当于深度copy。
    return this.fList = JSON.parse(JSON.stringify(this.list));
  }
}
}}

#hr();
コメント:
#comment_kcaptcha

トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS