Vue props实现组件间数据传输

一:props父组件给子组件传输

App.vue

<template>

  <div id="app">
    <div>
        <!--:age  :就是v-bind 它会读取18 而不是  "18" 字符串 这样不能做数字加减-->
        <school :age="18" stylemodel="good的好学校"></school>
    </div>
  </div>
</template>

<script>
//es6中模块化的引入方式
import school from './components/school.vue'
<script/>

注意:age="18" 这里因为age是int类型,所以age前加 :是为了表示读取的数字18而不是字符串"18"。

school.vue

<template>
  <!--demo为样式准备的-->
  <div class="demo">
    <!--age实现加一-->
    <h2>学校age:{{age+1}}</h2>
    <h2>学校style:{{stylemodel}}</h2>
  </div>
</template>

<script>
//es6中模块化的引入方式
import student from './student.vue'
  //------------------------------------------------------------
  //这样写法更加简洁,这样用的多
  export default {
        //代表组件名称,最好与 school.vue中的school一致
        name:'school',
        data(){
            return{    
            }
        }
 
        //高级格式
        props:{
          age:{
            //对age类型限制,如果传过来类型不一致则报错
            type:Number,
            //required:true  required和default不能同时存在
            default:10 //默认值限制
          },
          stylemodel:{
            type:String,
            required:true //必要值得限制
          }
        }
    }
</script>

props三种方法:

1.最简单格式: props:['age','stylemodel']
2.较复杂格式:

props:{
   age:Number,
   stylemodel:String
 }

3.高级格式:

props:{
    age:{
       //对age类型限制,如果传过来类型不一致则报错
       type:Number,
       //required:true  required和default不能同时存在
       default:10 //默认值限制
     },
     stylemodel:{
       type:String,
       required:true //必要值得限制
     }
}

注意:

  1. props里面属性都是之前组件中传过去的,如果没有传但是props中写了则报错。
  2. props里面声明的属性不要再data中在声明,不然报错,优先级props中的高

App传输list到子组件例子:

App.vue

<template>
  <div id="app">
    <div>
        <!--加: 是因为想解析todos对象并不是字符串    :todos 右边的todos和下面data中的一样   :todos来源于listope.vue中的props:['todos']-->
        <listope :todos="todos"></listope>
    </div>
  </div>
</template>

<script>
//es6中模块化的引入方式
import listope from './components/todos/listope.vue'
export default {
  name: 'App',
  data() {
     return{
         todos:[
            {id:'01',title: '游戏',done:false},
            {id:'02',title: '学习',done:true},
            {id:'03',title: '工作',done:false},
            {id:'04',title: '打悦悦屁屁',done:true}
         ]
     }
   },
  components:{
    listope
  },
  //与headerope.vue呼应
  methods:{}
}
</script>

listope.vue

<template>
   <ul>
      <!--:todo  这里 :必须加因为要读的todoobj 是个对象, 不加 :直接把todoobj当成一个字符串-->
     <itemope v-for="todoobj in todos" 
                     :key="todoobj.id" 
                     :todo="todoobj">
      </itemope>
   </ul>
</template>

<script>
import itemope from './itemope.vue'
export default {
   name:'listope',
   components:{},
   //这里注意不要把props里面的东西改变后传到div中,也就是说不要改props中的东西!!!!
   //如果todos改的是里面对象中的某个元素,这样即使改了也不会报错,但是如果todos下一层级(对象这一层改了)则直接会报错。最好props不要动
   props:['todos']
}
</script>

特别注意:

  1. :todo 这里 :必须加因为要读的todoobj 是个对象, 不加 :直接把todoobj当成一个字符串。
  2. 这里注意不要把props里面的东西改变后传到div中,也就是说不要改props中的东西。如果todos改的是里面某一个对象中的某个元素,这样即使改了也不会报错,但是如果todos下一层级(某个对象这一层改了,比如多了个对象少了个对象)则直接会报错。最好props不要动
  3. 由于2所有最好props中的值不能作为v-model的值,因为props中数据不能改变,v-model双向绑定所以有getter setter 一旦setter改变数据则不适用于props了

图例:
在这里插入图片描述

二:props子组件给父组件传输

子组件给父组件传数据,父组件得给子组件一个方法,供子组件中方法调用。

一个根据id删除的案例(一:图片中的删除)

单条数据的itemope.vue

<template>
   <li>
      <label>
         <span>{{todo.title}}</span>
      </label>
      <button @click="handleDeleteData(todo.id)">删除</button>
   </li>
</template>
<script>
export default {
   name:'itemope',
   props:['todo','deleteData'],
   methods:{
      //删除
      handleDeleteData(id){
         if(confirm('确定删除吗?')){
            this.deleteData(id); 
         }  
      }  
   } 
}
</script>

<style>  
  li:hover{
   background-color: #ddd;
  }
</style>

所调用的方法(父组件App.vue提供的方法):

 this.deleteData(id); 

多条数据list的listope.vue

<template>
   <ul>
      <!--:todo  这里 :必须加因为要读的todoobj 是个对象, 不加 :直接把todoobj当成一个字符串-->
     <itemope v-for="todoobj in todos" 
                     :key="todoobj.id" 
                     :todo="todoobj"
                     :deleteData="deleteData">
      </itemope>
   </ul>
</template>

<script>
import itemope from './itemope.vue'
export default {
   name:'listope',
   components:{itemope},
   props:['todos','deleteData']
}
</script>

注意:

  1. 这里props:['todos','deleteData']拿到todos集合,直接v-for="todoobj in todos" 拿到todoobj 随后在通过:todo="todoobj"往itemope.vue传todoo单个对象。deleteData也往itemope.vue传deleteData方法供其调用。

最终父组件App.vue,App里面写了删除的逻辑,但是最终在itemope.vue中调用

<template>

  <div id="app">
    <div>
        <listope :todos="todos"  :deleteData="deleteData"></listope>
    </div>
  </div>
</template>

<script>
//es6中模块化的引入方式
import listope from './components/todos/listope.vue'
export default {
  name: 'App',
  data() {
     return{
         todos:[
            {id:'01',title: '游戏',done:false},
            {id:'02',title: '学习',done:true},
            {id:'03',title: '工作',done:false},
            {id:'04',title: '打悦悦屁屁',done:true}
         ]
     }
   },
  components:{
    listope
  },
  //与headerope.vue呼应
  methods:{
    //删除一条数据
    deleteData(id){
      // this.todos = this.todos.filter((todo)=>{
      //   return todo.id != id;
      // })
      //上面方式比较复杂点,这种事简写
      this.todos = this.todos.filter(todo=> todo.id != id);
    }
  }
}
</script>

list过滤数据的方式:

方式1:

this.todos = this.todos.filter((todo)=>{
        return todo.id != id;
})

方式2:

//上面方式比较复杂点,这种事简写
 this.todos = this.todos.filter(todo=> todo.id != id);

拓展:
子组件给父组件传数据还有其他方式比如 自定义事件结合emit,和ref结合emit

具体项目:gitee => demo

https://gitee.com/BruthLi/vuedemo.git
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值