从零开始学VUE之组件化开发(父子组件的通信)
父子组件的通信
为什么需要通信
- 在开发中往往一些数据确实需要下面的子组件进行展示
- 比如在一个页面中,我们从服务器请求了很多的数据,其中一部分数据并不是页面的大组件来展示的,而是需要下面的子组件进行展示,这个时候肯定不会让子组件再次调用网络请求,而是直接让大组件(父组件)将数据传递给小组件(子组件)
如何通信
- 父组件通过props属性将数据传递给子组件
- 子组件通过自定义事件向父组件传递数据
父组件向子组件传递数据[props:字符串数组类型]
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="../../../js/vue.js"></script> </head> <body> <div id="app"> <!-- 静态传值--> <cpn ctitle="title" cmovies="movies"></cpn> <!-- 动态传值--> <cpn :ctitle="title" :cmovies="movies"></cpn> </div> </body> <template id="cpn"> <div> {{ctitle}} {{cmovies}} </div> </template> <script> const cpn = { template:'#cpn', // 使用数组进行传值 在里面声明需要传输数据的key,在使用的时候通过属性就可以传递值了 props:[ 'ctitle', 'cmovies' ] } // 创建vue const vue = new Vue({ el: '#app', data: { title:'this is title', movies: ['spring','springboot','springmvc','springData'] }, components:{ // ES6 增强KEY 不写KEY 默认和值 一致 cpn } }) </script> </html>
运行效果
父组件向子组件传递数据[props:对象(带验证)]
组件可以为 props 指定验证要求。
为了定制 prop 的验证方式,你可以为 props 中的值提供一个带有验证需求的对象,而不是一个字符串数组。
props: { // 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证) propA: Number, // 多个可能的类型 propB: [String, Number], // 必填的字符串 propC: { type: String, required: true }, // 带有默认值的数字 propD: { type: Number, default: 100 }, // 带有默认值的对象 propE: { type: Object, // 对象或数组默认值必须从一个工厂函数获取 default: function () { return { message: 'hello' } } }, // 自定义验证函数 propF: { validator: function (value) { // 这个值必须匹配下列字符串中的一个 return ['success', 'warning', 'danger'].indexOf(value) !== -1 } } }
当 prop 验证失败的时候,(开发环境构建版本的) Vue 将会产生一个控制台的警告。
type(验证类型) 可以是下面原生构造器:
String |
Number |
Boolean |
Array |
Object |
Date |
Function |
Symbol |
type 也可以是一个自定义构造器,使用 instanceof 检测
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="../../../js/vue.js"></script> </head> <body> <div id="app"> <cpn :ctitle="title" :cmovies="movies"></cpn> </div> </body> <template id="cpn"> <div> {{ctitle}} {{cmovies}} </div> </template> <script> const cpn = { template:'#cpn', // 使用对象进行传值可以对key的value进行校验 props: { ctitle:{ // 类型为String 如果可能是多个采用 字符串数组 type:String, // 是否必传 required:true, // 默认值 default:'没有传递数据' }, cmovies:{ // 可能是多个值 type:[Array,Object], // 不是必填 required: false, // 数组和对象的默认值必须由函数返回 default(){ return []; } } } } // 创建vue const vue = new Vue({ el: '#app', data: { title:'this is title', movies: ['spring','springboot','springmvc','springData'] }, components:{ // ES6 增强KEY 不写KEY 默认和值 一致 cpn } }) </script> </html>
运行效果
父组件向子组件传递数据[props:驼峰命名问题]
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="../../../js/vue.js"></script> </head> <body> <div id="app"> <!-- 采用大写将接收不到值--> <h2>cTitle</h2> <cpn :cTitle="title"></cpn> <!-- 自动转换 cTitle->c-title--> <h2>c-title</h2> <cpn :c-title="title"></cpn> </div> </body> <template id="cpn"> <div> {{cTitle}} </div> </template> <script> const cpn = { template:'#cpn', // 使用对象进行传值可以对key的value进行校验 props: { // 使用驼峰命名时,在属性传值的时候会自动将驼峰转为中横线+小写 cTitle:{ // 类型为String 如果可能是多个采用 字符串数组 type:String, // 默认值 default:'没有传递数据' } } } // 创建vue const vue = new Vue({ el: '#app', data: { title:'this is title' }, components:{ cpn } }) </script> </html>
运行效果
子组件向父组件传递数据[自定义事件]
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="../../../js/vue.js"></script> </head> <body> <div id="app"> <!--不是cli中 暂时不要写驼峰 因为我写了转 成中横线和小写也不行,暂时就全写小写 --> <!--@querybyitemname 这个事件就是自定义事件 通过子组件使用$.emit发射出来的--> <cpn @querybyitemname="queryByItemName"></cpn> </div> </body> <template id="cpn"> <div> <button v-for="item in categories" @click="itemClick(item)">{{item.name}}</button> </div> </template> <script> const cpn = { template: '#cpn', data() { return { categories: [ {id: 'a', name: '热门推荐'}, {id: 'b', name: '手机数码'}, {id: 'c', name: '家用电器'}, {id: 'd', name: '电脑办公'} ] } }, methods: { itemClick(item) { // 通过自定义事件'querybyitemname'方法并传递参数'item',需要在组件调用的时候通过@也就是v-on监听 this.$emit('querybyitemname', item); } } } // 创建vue const vue = new Vue({ el: '#app', data: {}, methods: { // 用于子组件调用 queryByItemName(item) { console.log(JSON.stringify(item)); } }, components: { cpn } }) </script> </html>
运行结果
作者:彼岸舞
时间:2021\06\02
内容关于:VUE
本文属于作者原创,未经允许,禁止转发