欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 健康 > 美食 > 组件上的v-model(数据传递),props验证,自定义事件,计算属性

组件上的v-model(数据传递),props验证,自定义事件,计算属性

2024/10/25 8:17:19 来源:https://blog.csdn.net/2301_79568779/article/details/142214939  浏览:    关键词:组件上的v-model(数据传递),props验证,自定义事件,计算属性

一.props验证

在封装组件时对外界传递过来的props数据进行合法性校验,从而防止数据不合法问题。

1.基础类型检查

String,Number,Boolean,Array,Object,Date,Function,Symbol

2.多个可能的类型
3.必须项校验
4.属性默认值
5.自定义验证函数
<template><div>父组件</div><DemoSon :msg="msg" :title="title" type="abc"></DemoSon>
</template>
<script>
import DemoSon from './son.vue'
export default {name:'demo',components:{DemoSon},data(){return{msg:'111',title:'abc'}}
}
</script><template><div>子组件</div><p>{{ msg }}{{ title }}</p>
</template>
<script>
export default {name:'demo-son',props:{msg:{type:[Number,String],required:true,default:10},title:String,type:{validator(value){// true成功,false失败return ['success','warning','danger'].indexOf(value)!==-1}}}
}
</script>

二.计算属性computed

计算属性本质上是一个function函数,可以监听data中数据的变化,并return一个计算后的值,供组件渲染dom时使用。

计算属性会缓存计算的结果,只有在计算属性的依赖项发生变化时,才会重新计算。

计算属性只能当作普通数据项使用,不能当作方法调用(不能使用括号调用)。

<template><div><input type="text" v-model.number="num"></div><div>{{ plus }}</div>
</template><script>export default {name:'demo',data(){return{num:111}},computed:{plus(){return  this.num*2}}}</script>
<template><div><table border><tr><td class="goodState">状态</td><td class="goodId">#</td><td class="goodName">名称</td><td class="goodPrice">单价</td><td class="goodNum">数量</td><td class="goodTime">价格</td><td class="goodAction">操作</td></tr><tr v-for="(item,index) in goods.data" :key="item.id"><td class="goodState"><input type="checkbox" v-model="item.state" :id="item.id"><label :for="item.id">{{item.state===true?"上架":"下架"}}</label></td><td class="goodId">{{index+1}}</td><td class="goodName">{{item.name}}</td><td class="goodNum">{{item.price}}</td><td class="goodNum">{{item.num}}</td><td class="goodTime">{{item.num*item.price}}</td><td class="goodAction"><b @click="addFn(item.id,item.num)">+</b><b @click="minusFn(item.id,item.num)">-</b></td></tr><tr><td>总数:{{ number }}</td><td>总计:{{ total }}</td></tr></table></div>
</template><script setup>
import { ref,reactive, computed } from "vue"
const goods=reactive({data:[{id:'1',name:'苹果',state:true,price:2,num:0,time:'2020-11-03 11:00:00'},{id:'2',name:'梨',state:true,price:2,num:0,time:'2020-11-03 11:00:00'},{id:'3',name:'香蕉',state:true,price:2,num:0,time:'2020-11-03 11:00:00'}]
})
const minusFn=(id,num)=>{if(num>0){for(let i=0;i<goods.data.length;i++){if(goods.data[i].id===id){goods.data[i].num= num-1}}
}
}
const addFn=(id,num)=>{for(let i=0;i<goods.data.length;i++){if(goods.data[i].id===id){goods.data[i].num= num+1}}
}
const number = computed(()=>{let n=0;goods.data.forEach((item)=>{if(item.state){n+=item.num}})return n;
})
const total = computed(()=>{let sum=0;goods.data.forEach((item)=>{if(item.state){sum+=item.num*item.price}})return sum;
})</script><style scoped lang="scss">td{width: 200px;height: 40px;}b{margin-right: 20px;}
</style>

三.自定义事件

1.声明自定义事件
2.触发自定义事件
3.监听自定义事件
<template><div class="card">{{ count }}<Son @changeCount="changeCount"></Son></div>
</template>
<script >
import Son from './son.vue'
export default{name:'index',components: {Son},data(){return{count:0}},methods:{changeCount(str){this.count = str}}
}
</script><template><button type="button" @click="clickFn">按钮</button>
</template>
<script>
export default{name:'son',emits:['changeCount'],methods:{clickFn(){this.$emit('changeCount',1)}}
}
</script>
<template><div class="card">{{ count }}<Son @changeCount="changeCount"></Son></div>
</template>
<script setup>
import { ref } from 'vue'
import Son from './son.vue'
const count = ref(0)
const changeCount = (str)=>{count.value = str
}
</script><template><button type="button" @click="clickFn">按钮</button>
</template>
<script setup>
const emit = defineEmits('changeCount')
const clickFn = () => {emit('changeCount',1)
}
</script>

四.组件上v-model

1.父传子

a.父组件通过v-bind属性绑定的形式,把数据传递给子组件

b.子组件中,通过props接受子组件传递过来的数据

<template><div>父组件</div><DemoSon :msg="msg"></DemoSon>
</template>
<script>
import DemoSon from './son.vue'
export default {name:'demo',components:{DemoSon},data(){return{msg:'111'}}
}
</script><template><div>子组件</div><p>{{ msg }}</p>
</template>
<script>
export default {name:'demo-son',props:{msg:{type:[Number,String],required:true,default:10}}
}
</script>
2.子传父

a.在v-bind指令前添加v-model指令

b.在子组件中声明emits自定义事件,格式为update:xxx

c.调用$emit()触发自定义事件,更新父组件中的数据

<template><div class="card">{{ count }}<Son v-model:number="count"></Son></div>
</template>
<script >
import Son from './son.vue'
export default{name:'index',components: {Son},data(){return{count:0}}
}
</script><template>{{ number }}<button type="button" @click="clickFn">按钮</button>
</template>
<script>
export default{name:'son',props:['number'],emits:['update:number'],methods:{clickFn(){this.$emit('update:number',this.number+1)}}
}
</script>

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com