• Blazor和Vue对比学习(基础1.3):属性和父子传值


    组件除了要解决视图层展示、视图层与逻辑层的数据绑定,还需要解决一个重大问题,就是在组件树中实现数据传递,包括了父传子、子传父、祖传孙,以及任意组件之间传值。我们上一章讲到的实现双向绑定的两个指令,Vue的v-model,Blazor的@bind,可以认为是父子组件双向传值的语法糖,后面章节我们再来实现它。

    我们先从最简单的父子传值开始学习。在Vue和Blazor中,都是通过属性来实现父子组件的数据传递。我们以往都是在html标签上设置属性,属性值可以是字面量,也可以绑定逻辑数据。比如这样【连接】。我们现在把a标签换成一个自定义的组件,【链接】,MyLink组件会如何处理这个绑定的href值呢?我们将通过以下几点来学习父传子:

    1. 父子传值的基本使用
    2. 传递属性值的类型
    3. 传递属性值的校验

     

    1、父子传值的基本使用

    ①步骤一:父组件中,定义子组件的标签属性,并给标签属性赋值,即可将数据传递给子组件

    ②步骤二:子组件中,定义用来接受父组件传值的变量(属性),肯定不能是普通的变量。Vue通过defineProps来定义(defineProps是宏命令,不需要import),Blazor通过[Parameter]特性来标注

    复制代码
    //Vue=====================================
    
    //1、子组件Post
    
    //定义两个属性用于接收数据
    
    
    //在模板中使用接收到的两个属性值(可以直接使用)
    
    
    
    
    //2、父组件传递数据
    //引入子组件Post
    
    
    //使用子组件标签,定义title属性---直接赋值字面量,定义content属性---绑定一个逻辑变量
    
    
    
    
    //3、父组件传递数据-结合循环渲染
    
    
    
    复制代码
    复制代码
    //Blazor===================================
    
    //1、子组件Post
    //在模板中使用接收到的两个属性值
    

    @Title

    @Content

    //定义两个属性用于接收数据 @code { [Parameter] public string Title { get; set; } [Parameter] public string Content { get; set; } } //2、父组件传递数据 //使用子组件,定义Title属性---直接赋值字面量,定义content属性---绑定一个逻辑变量 "俄乌局事有重大变化" Content="@content"> @code { private string content = "美国又来搅局"; } //3、父组件循环渲染传递数据 @foreach (var post in posts) { "@post.Title" Content="@post.Content"> } @code { private List posts = new List { new PostModel{Title="标题1",Content="内容1"}, new PostModel{Title="标题2",Content="内容2"} }; }
    复制代码

     

     

    2、传递属性的值类型

    对于HTML原始标签的属性,我们只能传递指定的类型,一般是数值、字符串、布尔等简单类型,但对于自定义组件,我们可以传递任意类型,Vue和Blazor在这方面都没有限制。但【有个坑】,需要特别小心

    • Vue:当传递数组、对象等引用类型时,仅仅传递了引用地址。所以,在子组件中直接修改传递过来的属性值,父组件的值也会改变。如果需要修改传递过来的属性值,建议将属性值赋值给一个新变量,再对新变量进行加工处理
    • Blazor:不存在Vue的问题,即使传递引用类型,也是传递一个新值给子组件,属性值在父子组件中相互独立。
    复制代码
    //Vue=====================================
    
    //子组件,数组方式接收
    
    
    
    
    
    //父组件,传递对象和数组类型数据
    
    
    
    复制代码
    复制代码
    //Blazor
    
    //子组件,定义了一个PostModel类属性,以及这个类的集合属性
    

    @($"{PostModel.Title}-{PostModel.Content}")

    @foreach (var item in PostModels) {

    @($"{item.Title}-{item.Content}")

    } @code { [Parameter] public PostModel PostModel { get; set; } [Parameter] public List PostModels { get; set; } } //父组件创建了一个PostModel实例,以及PostModel的集合实例 "@postModel" PostModels="@postModels"> @code { private PostModel postModel = new PostModel { Title = "标题1", Content = "内容1" }; private List postModels = new List { new PostModel{Title="标题2",Content="内容2"}, new PostModel{Title="标题3",Content="内容3"} }; }
    复制代码

     

     

    3、传递属性值的校验

    Blazor是天生强类型,属性值的校验非常简单。而Vue中的属性值校验也麻烦些,如果不使用TS,只能支持运行时校验,使用TS,结合volar,可以支持编译时校验。

    复制代码
    //Vue=====================================
    
    //运行时校验,对象方式接收
    const props = defineProps({
      // 基础类型检查
      propA: Number,
      // 多种可能的类型
      propB: [String, Number],
      // 必传,且为 String 类型
      propC: {
        type: String,
        required: true
      },
      // Number 类型的默认值
      propD: {
        type: Number,
        default: 100
      },
      // 对象类型的默认值
      propE: {
        type: Object,
        default() {
          return { message: 'hello' }
        }
      }
    }
    
    
    
    //借助TS和volar实现编译时检验,使用起来不是特别顺手
    
    //方法1:泛型约束
    const props = defineProps<{
      foo: string
      bar?: number
    }>()
    
    //方法2:使用接口
    interface Props {
      foo: string
      bar?: number
    }
    const props = defineProps()
    
    //默认值的话,比较麻烦,使用withDefault再包一层
    const props = withDefault(defineProps<{
      foo: string
      bar?: number
    }>(),{
      foo:'hello',
      bar:10,
    })
    复制代码
    复制代码
    //Blazor====================================
    
    //类型、是否必填、默认值,一行搞定,而且都是c#本身的语法,不用借助API,就问你爽不爽!?
    
    @code {
        [Parameter]
        public PostModel? PostModel { get; set; } = new PostModel { Title = "默认标题", Content = "默认内容" };
        [Parameter]
        public List PostModels { get; set; }
    }
    复制代码

     

  • 相关阅读:
    虚拟化+docker基本概念以及安装部署
    数据结构五分钟精通 之 正则表达式(Python)
    JS 流行框架(二):Express
    java面试题之 int和Integer的区别
    为什么要构建垂直切片
    Lambda表达式
    竞赛 深度学习YOLO图像视频足球和人体检测 - python opencv
    10行代码实现RSA公钥解密
    jieba
    运用 Elastic Stack 收集 docker 容器日志
  • 原文地址:https://www.cnblogs.com/functionMC/p/16243824.html