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

我们先从最简单的父子传值开始学习。在Vue和Blazor中,都是通过属性来实现父子组件的数据传递。我们以往都是在html标签上设置属性,属性值可以是字面量,也可以绑定逻辑数据。比如这样<a :href="href">连接</a>。我们现在把a标签换成一个自定义的组件,<Link :href="href">链接</Link>,Link组件会如何对待这个绑定的href值呢?【例子中,大家不要忽略一个事实,无论是a标签也好,还是组件Link也罢,它们都是在另外一个组件中使用的,这个组件我们称为父组件,而a标签或Link组件,称为子组件】

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

1、父子传值的基本使用

Vue在子组件中,通过defineProps(宏命令,不需要import)来定义属性,Blazor在子组件中,通过[Parameter]特性,来标注属性。Vue不断的创造新的API,不看源码,你不会知道这个defineProps是怎么工作的,而Blazor无招胜有招,使用的时候,你就能大概明白是怎么一回事!

//Vue=====================================

//1、子组件Post

//定义两个属性用于接收数据
<script setup>
const props = defineProps(['title','content']) //在代码中,通过props.title来使用属性值
</script> //在模板中使用接收到的两个属性值
<template>
<h1>{{title}}</h1>
<h3>{{content}}</h3>
</template> //2、父组件传递数据
//引入子组件Post
<script setup>
import {ref} from 'vue'
import Post from './components/Post.vue'
const content = ref('美国又来搅局!')
</script> //使用子组件,title属性绑定字面量,content属性绑定逻辑变量
<template>
<Post title="俄乌局事有重大变化" :content="content"></Post>
</template> //3、父组件传递数据-循环渲染
<script setup>
import {ref} from 'vue'
import Post from './components/Post.vue'
const posts = ref([
{title:'标题1',content:'内容1'},
{title:'标题2',content:'内容2'},
])
</script> <template>
<Post v-for="post in posts" :title="post.title" :content="post.content"></Post>
</template>
//Blazor===================================

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

2、传递属性值的类型

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

【有个注意点需要特别小心】:

Vue:当传递数组、对象等引用类型时,仅仅传递了引用地址。所以,在子组件中直接修改传递过来的属性值,父组件的值也会被改变。在Vue中,如果需要修改传递过来的属性值,建议将属性值赋值给一个新变量,再对新变量进行加工处理。

Blazor:不存在Vue的问题,即使传递引用类型,也是传递一个新值给子组件,属性值在父子组件中相互独立。

//Vue=====================================

//子组件,接收对象和数组
<script setup>
const props = defineProps(['value1','value2'])
</script> <template>
<h1>{{value1.name}}-{{value1.age}}</h1>
<h3 v-for="item in value2">{{item.name}}-{{item.age}}</h3>
</template> //父组件,传递对象和数组类型数据
<script setup>
import {ref} from 'vue'
import Post from './components/Post.vue'
const value1 = ref({name:'Fun',age:18})
const value2 = ref([
{name:'Fun',age:18},
{name:'MC',age:19},
])
</script> <template>
<Post :value1="value1" :value2="value2"></Post>
</template>
//Blazor

//子组件,定义了一个PostModel类属性,以及这个类的集合属性
<h1>@($"{PostModel.Title}-{PostModel.Content}")</h1> @foreach (var item in PostModels)
{
<h3>@($"{item.Title}-{item.Content}")</h3>
} @code {
[Parameter]
public PostModel PostModel { get; set; }
[Parameter]
public List<PostModel> PostModels { get; set; }
} //父组件创建了一个PostModel实例,以及PostModel的集合实例
<Post PostModel="@postModel" PostModels="@postModels"></Post> @code {
private PostModel postModel = new PostModel { Title = "标题1", Content = "内容1" }; private List<PostModel> postModels = new List<PostModel>
{
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实现编译时检验 //泛型约束
const props = defineProps<{
foo: string
bar?: number
}>() //使用接口
interface Props {
foo: string
bar?: number
}
const props = defineProps<Props>() //默认值的话,比较麻烦,使用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<PostModel> PostModels { get; set; }
}

Blazor和Vue对比学习(基础1.3):属性和父子传值的更多相关文章

  1. Blazor和Vue对比学习(基础1.8):Blazor中实现计算属性和数据监听

    1.7章<传递UI片断>,需要做几个案例,这部分暂停消化几天.我们先把基础部分相对简单的最后两章学习了. 计算属性和数据监听是Vue当中的概念,本质上都是监听数据的变化,然后做出响应.两者 ...

  2. Blazor和Vue对比学习(基础1.4):事件和子传父

    Blazor和Vue的组件事件,都使用事件订阅者模式.相对于上一章的组件属性,需要多绕一个弯,无论Blazor还是Vue,都是入门的第一个难点.要突破这个难点,一是要熟悉事件订阅模式<其实不难& ...

  3. Blazor和Vue对比学习(基础1.6):祖孙传值,联级和注入

    前面章节,我们实现了父子组件之间的数据传递.大多数时候,我们以组件形式来构建页面的区块,会涉及到组件嵌套的问题,一层套一层.这种情况,很大概率需要将祖先的数据,传递给子孙后代去使用.我们当然可以使用父 ...

  4. Blazor和Vue对比学习(基础1.7):传递UI片断,slot和RenderFragment

    组件开发模式,带来了复用.灵活.性能等优势,但也增加了组件之间数据传递的繁杂.不像传统的页面开发模式,一个ViewModel搞定整个页面数据. 组件之间的数据传递,是学习组件开发,必须要攻克的难关.这 ...

  5. Blazor和Vue对比学习:说在开始前

    1.Vue:现代前端三大框架之一(Vue/React/Angualr),基于HTML.CSS和JavaScript,2014年正式对外发布,目前已发展到3.X版本.值得说道的是,Vue的创始人作者是华 ...

  6. Blazor和Vue对比学习(进阶2.2.4):状态管理之持久化保存(2),Cookie/Session/jwt

    注:本节涉及到前后端,这个系列的对比学习,还是专注在前端Vue和Blazor技术,所以就不撸码了,下面主要学习概念. 我们知道,Http是无状态协议,客户端请求服务端,认证一次后,如果再次请求,又要重 ...

  7. Blazor和Vue对比学习(基础1.9):表单输入绑定和验证,VeeValidate和EditFrom

    这是基础部分的最后一章,内容比较简单,算是为基础部分来个HappyEnding.我们分三个部分来学习: 表单输入绑定 Vue的表单验证:VeeValidate Blazor的表单验证:EditForm ...

  8. Blazor和Vue对比学习(基础1.2):模板语法和Razor语法

    Vue使用模板语法,Blazor使用祖传的Razor语法,从逻辑和方向上看,两者极为相似,比如: 都基于HTML 都通过声明式地将组件实例的状态(数据/方法)绑定到呈现的DOM上 都通过指令实现更加丰 ...

  9. Blazor和Vue对比学习(基础1.5):双向绑定

    这章我们来学习,现代前端框架中最精彩的一部分,双向绑定.除了掌握原生HTML标签的双向绑定使用,我们还要在一个自定义的组件上,手撸实现双向绑定.双向绑定,是前两章知识点的一个综合运用(父传子.子传父) ...

随机推荐

  1. Linux中一切皆文件

    谈一谈Linux中一切皆文件 1. Linux中所有内容都是以文件的形式保存和管理,即:一切皆文件. 普通文件是文件. 目录(在win下称为文件夹)是文件. 硬件设备(键盘.硬盘.打印机)是文件. 套 ...

  2. C与C++的区别之函数调用堆栈

    函数调用栈 1.函数参数带入(入调用方函数的栈,从右向左入栈) int fun(int a); int fun(int a, int b); int fun(int a, int b, int c); ...

  3. react 移动端 兼容性问题和一些小细节

    react 移动端 兼容性问题和一些小细节 使用 ES6 的浏览器兼容性问题 react 对低版本的安卓webview 兼容性 iOS下 fixed与软键盘的问题 onClick 阻止冒泡 meta对 ...

  4. PHP基于Thinkphp5的砍价活动相关设计

    近期我们公司项目里陆陆续续有很多为了招引新用户的活动推出,砍价的活动由我来负责,我们的项目是在微信浏览器里供用户浏览访问. 大概描述:进入砍价活动列表页选择有意向的商品,用户点击商品图片可以看到WEB ...

  5. centos报错:Could not retrieve mirrorlist http://mirrorlist.centos.org/

    检查是否可以上网. ping 114.114.114.114 如果不可以,调试通.通了之后下一步: 然后检查DNS设置是否正常. ping www.baidu.com 不正常的话,设置DNS,如下: ...

  6. 将java的对象或集合转成json形式字符串

    将java的对象或集合转成json形式字符串: json的转换插件是通过java的一些工具,直接将java对象或集合转换成json字符串. 常用的json转换工具有如下几种: 1)jsonlib 需要 ...

  7. AcWing 1050. 鸣人的影分身

    题目链接 题目描述: 在火影忍者的世界里,令敌人捉摸不透是非常关键的. 我们的主角漩涡鸣人所拥有的一个招数--多重影分身之术--就是一个很好的例子. 影分身是由鸣人身体的查克拉能量制造的,使用的查克拉 ...

  8. [ Shell ] 通过 Shell 脚本导出 CDL 网表

    https://www.cnblogs.com/yeungchie/ 通过 si 导出电路网表,实际上在 Virtuoso 中通过 export - cdl 和 Calibre LVS 的步骤中也是通 ...

  9. CPU乱序执行问题

    CPU为了提高执行效率,会在一条指令执行的过程中(比如去内存读数据,读数据的过程相较于CPU的执行速度慢100倍以上,cpu处于等待状态),这个时候cpu会分析接下来的指令是否正在执行的指令相关联,如 ...

  10. 演示默认学习用户scott,默认密码是tiger

    默认学习用户scott,默认密码是tiger oracle@prd:/home/oracle$sqlplus /nolog SQL> conn scott/tiger ERROR: ORA-28 ...