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

news2024/11/15 9:59:01

一.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>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2134262.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CAD2020安装方法

文章目录 下载安装包打开压缩包打开文件夹打开CAD2020文件夹双击运行Setup.exe点击安装选择我接受 点击下一步路径默认点击安装等待加载完成安装完成点击立即启动点击OK点击输入序列号点击我同意点击激活输入序列号和 产品钥密点击下一步选择我具有 Autodesk 提供的激活码以管理…

【北京迅为】《STM32MP157开发板使用手册》- 第二十八章Cortex-M4外部中断实验

iTOP-STM32MP157开发板采用ST推出的双核cortex-A7单核cortex-M4异构处理器&#xff0c;既可用Linux、又可以用于STM32单片机开发。开发板采用核心板底板结构&#xff0c;主频650M、1G内存、8G存储&#xff0c;核心板采用工业级板对板连接器&#xff0c;高可靠&#xff0c;牢固耐…

SRT3D: A Sparse Region-Based 3D Object Tracking Approach for the Real World

基于区域的方法在基于模型的单目3D跟踪无纹理物体的复杂场景中变得越来越流行。然而&#xff0c;尽管它们能够实现最先进的结果&#xff0c;大多数方法的计算开销很大&#xff0c;需要大量资源来实时运行。在下文中&#xff0c;我们基于之前的工作&#xff0c;开发了SRT3D&…

一、轻松部署的大模型开发平台dify.ai

一、轻松部署的大模型开发平台dify.ai 今天学习了大模型&#xff0c;顺便介绍的是一个名为dify.ai的神奇平台&#xff0c;它能让你轻松部署和使用大模型&#xff0c;即使你是编程小白也不用担心。 官网&#xff1a;https://dify.ai/zh 什么是大模型&#xff1f; 首先&#…

C++ nullptr 和NULL的区别

个人主页&#xff1a;Jason_from_China-CSDN博客 所属栏目&#xff1a;C系统性学习_Jason_from_China的博客-CSDN博客 概念概述&#xff1a; 在C中&#xff0c;nullptr 和 NULL 都是用来表示空指针&#xff0c;但它们之间有一些重要的区别&#xff1a; nullptr和NULL之间的区分…

ceph简介

ceph存储简要概述&#xff1a; 通过将文件分解成固定大小对象&#xff0c;然后存放于pool中&#xff0c;每个pool中 可包含多个pg&#xff0c;每个pg中又可包含多个osd 通过crush算法 最终数据落盘到osd中去。 一、ceph 删除osd 步骤1 修改osd数据操作权重值 ceph osd crush r…

【贪心算法】贪心算法

贪心算法简介 1.什么是贪心算法2.贪心算法的特点3.学习贪心的方向 点赞&#x1f44d;&#x1f44d;收藏&#x1f31f;&#x1f31f;关注&#x1f496;&#x1f496; 你的支持是对我最大的鼓励&#xff0c;我们一起努力吧!&#x1f603;&#x1f603; 1.什么是贪心算法 与其说是…

C++ | Leetcode C++题解之第401题二进制手表

题目&#xff1a; 题解&#xff1a; class Solution { public:vector<string> readBinaryWatch(int turnedOn) {vector<string> ans;for (int i 0; i < 1024; i) {int h i >> 6, m i & 63; // 用位运算取出高 4 位和低 6 位if (h < 12 &&a…

如何在算家云搭建MindSearch(智能搜索)

一、MindSearch简介 MindSearch是一款由上海人工智能实验室书生浦语团队提出了 MindSearch&#xff08;思索&#xff09;框架&#xff0c;旨在提供高效、精准的信息检索服务&#xff0c;能够在 3 分钟内主动从 300 网页中搜集整理有效信息&#xff0c;总结归纳&#xff0c;解决…

[“1“, “2“, “3“].map(parseInt)结果

parseInt 的用法 parseInt 是 JavaScript 中的一个全局函数&#xff0c;用于将字符串转换为整数。它的基本语法如下&#xff1a; parseInt(string, radix);string&#xff1a;要解析的字符串。radix&#xff08;可选&#xff09;&#xff1a;字符串的基数&#xff0c;可以是 …

初级练习[2]:Hive SQL查询汇总分析

目录 SQL查询汇总分析 成绩查询 查询编号为“02”的课程的总成绩 查询参加考试的学生个数 分组查询 查询各科成绩最高和最低的分 查询每门课程有多少学生参加了考试(有考试成绩) 查询男生、女生人数 分组结果的条件 查询平均成绩大于60分的学生的学号和平均成绩 查询至少…

学习笔记 韩顺平 零基础30天学会Java(2024.9.13)

P545 TreeMap源码解读 TreeSet的k-v其中的v是一个静态的对象&#xff0c;但是TreeMap的v是可以变化的 TreeMap使用默认构造器取出的顺序和添加的顺序是不一样的&#xff0c;但是有构造器实现了Comparator接口的匿名内部类&#xff0c;可以按顺序排序 P546 Collections工具类1 P…

不入耳蓝牙耳机排行榜第一名是哪个品牌?解密最值得购买的五大品牌!

​到了2024年&#xff0c;开放式耳机无疑成为了耳机市场的宠儿。它们的优势在于&#xff0c;不仅佩戴舒适&#xff0c;还能在保护听力的同时&#xff0c;让你保持对周围环境的警觉&#xff0c;这对于爱好户外探险的朋友来说&#xff0c;无疑是一个巨大的安全加分项。作为一名资…

【初识Linux】Linux下基本指令

01. ls 指令 语法&#xff1a; ls [选项][目录或文件] 功能&#xff1a;对于目录&#xff0c;该命令列出该目录下的所有子目录与文件。对于文件&#xff0c;将列出文件名以及其他信息。 常用选项&#xff1a; -a 列出目录下的所有文件&#xff0c;包括以 . 开头的隐含文件。 -…

AI与艺术的碰撞:当机器开始创作,创造力何在?

一、引言 艺术与创造力的定义及重要性 艺术&#xff0c;作为人类情感和思想的表达形式&#xff0c;涵盖了绘画、音乐、文学等多种领域。它不仅是文化传承的载体&#xff0c;更是人类想象力和创造力的结晶。创造力&#xff0c;则是推动艺术发展和社会进步的关键力量&#xff0…

高性能编程:无锁队列----MsgQueue代码实践

目录 概述 代码结构 1. 头文件解析 (msgqueue.h) 2. 实现文件解析 (msgqueue.c) 核心功能解析 2.1 创建队列 (msgqueue_create) 2.2 放入消息 (msgqueue_put) 2.3 获取消息 (msgqueue_get) 2.4 交换队列 (__msgqueue_swap) 2.5 阻塞与非阻塞模式 2.6 销毁队列 (msgq…

GPT Prompt

Reference https://help.openai.com/en/articles/6654000-best-practices-for-prompt-engineering-with-the-openai-apihttps://platform.openai.com/docs/guides/prompt-engineeringbilibili 8分钟系统学习提示工程,别再说大模型还不够聪明!Prompt Engineering,提示词,Few…

深兰科技董事长陈海波应出席“香港大学国际科创大赛”

近日&#xff0c;以“人工智能与智能制造”为主题的“香港大学国际科创大赛——知识转化论坛(沪港场)”在上海市普陀区隆重举行&#xff0c;众多来自人工智能与智能制造领域的专家学者与企业高管齐聚一堂&#xff0c;共话人工智能、智能制造与新质生产力的深度融合、最新进展以…

第 11篇 Helm 部署 RabbitMQ

文章目录 RabbitMQ 简介Helm ChartChart 版本选择自定义 values.yaml部署效果 参考相关博文 &#x1f680; 本文内容&#xff1a;在 Helm 中部署 RabbitMQ。 RabbitMQ 简介 ⭐ RabbitMQ&#xff1a;开源、通用消息代理&#xff0c;为一致性、高可用消息场景设计&#xff0c;包…

想引领潮流,得保持动销方案创新!

在竞争激烈的市场中&#xff0c;动销方案创新至关重要。 创新动销方案能提升品牌知名度与美誉度&#xff0c;吸引消费者关注&#xff0c;提高曝光度&#xff1b;还可增加销售额与市场份额&#xff0c;激发购买兴趣&#xff1b;更能增强企业竞争力&#xff0c;在同质化竞争中脱…