vue父子组件传值及单向数据流 vue父子组件传值以及单向数据流问题详解
丶Serendipity丶 人气:0想了解vue父子组件传值以及单向数据流问题详解的相关内容吗,丶Serendipity丶在本文为您仔细讲解vue父子组件传值及单向数据流的相关知识和一些Code实例,欢迎阅读和指正,我们先划重点:vue父子组件传值,vue,组件之间传值,vue单向数据流,下面大家一起来学习吧。
前言
我们知道 vue 中父子组件的核心概念是单向数据流问题,props 是单向传递的。那究竟什么是单向数据流问题,这篇文章来总结一下关于这个知识点的学习笔记。
1.父组件传值给子组件
<div id="app"> <blog-item :title="title"></blog-item> </div> // 定义子组件 Vue.component("blog-item", { props: ['title'], data() { return { } }, template: "<p>{{title}}</p>" }) // 定义父组件 new Vue({ el: "#app", data() { return { title: "msg", } }, })
父组件通过 :title = "title" 将值传递给子组件,子组件中通过 props 来接收父组件的值,然后通过插值表达式渲染在页面中。
2.子组件的 props 类型约束问题
常见的类型约束如下:
props: { title: String, likes: Number, isPublished: Boolean, commentIds: Array, author: Object, callback: Function, contactsPromise: Promise // or any other constructor }
除了上面常见的类型外,vue 还提供了构造函数和自定义函数来自定义子组件 props 的类型。
(1)构造函数自定义类型
//两个组件公共的自定义函数 function Person (firstName, lastName) { this.firstName = firstName this.lastName = lastName } //子组件中使用 Vue.component('blog-post', { props: { author: Person } //父组件中使用 var obj = new Person("1","2") <blog-post :author='obj'></blog-post>
上面的代码中,首先定义一个公共的自定义构造函数,通过该构造函数来可以来创建一个对象,该实例对象有两个属性,分别是 firstName 和 lastName,在父组件中调用该构造函数创建一个 obj 实例并传递给子组件,子组件定义类型为构造函数的 prop 接收该对象。
(2)自定义函数自定义类型
// 自定义函数 Vue.component('blog-post', { props: { propsA: String,//必须是字符串类型 propsB: [String,Number],//多个可选的类型 propsC: {type:Number,default:100},//定义类型并设置默认值 // 自定义验证函数 propsD:{ validator: function (value) { // 这个值必须匹配下列字符串中的一个 return ['success', 'warning', 'danger'].indexOf(value) !== -1 } } }
vue 中提供了非常灵活的来自定义子组件接收参数的类型,上面的代码中通过自定义了验证函数来约束父组件中的传值类型。
3.单向数据流问题
单向数据流是vue 中父子组件的核心概念,props 是单向绑定的。当父组件的属性值发生变化的时候,会传递给子组件发生相应的变化,从而形成一个单向下行的绑定,父组件的属性改变会流向下行子组件中,但是反之,为了防止子组件无意间修改了父组件中的数据而影响到了其他的子组件的状态,vue 规定了从下往上的数据流是不允许的。
当父组件的属性改变,会传递给子组件,而子组件的属性改变不会影响父组件,这样的话可能会觉得 props 有点鸡肋了,只能初始化组件的时候使用,在子组件内不能进行操作,因此我们在使用的时候经常有两种板房去操作props:(1)定义一个局部变量,并用props 初始化它,以后操作这个局部变量。(2)定义一个计算属性,处理props并返回。
<div id="app"> <blog-item :title="title1"></blog-item> <blog-item :title="title2"></blog-item> <blog-item :title="title3"></blog-item> <hr> <button @click='toclick'>点我</button> </div> // 定义子组件 Vue.component("blog-item", { props: ['title'], data() { return { } }, template: "<p>{{title}}</p>" }) // 父组件 new Vue({ el: "#app", data() { return { title1: "111", title2: "222", title3: "333" } }, methods: { toclick() { this.title3 = "000" } } })
<div id="app"> <blog-item :title="title"></blog-item> </div> // 定义子组件 Vue.component("blog-item", { props: ['title'], computed: { computedTitle() { return "computedTitle" + this.title } }, data() { return { subTitle: "subTitle" + this.title } }, template: "<p>{{title}}==={{subTitle}}==={{computedTitle}}</p>" }) // 父组件 new Vue({ el: "#app", data() { return { title: "111", } }, })
总结
加载全部内容