在组件中获取数据
看下面这个例子:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>组件数据的获取</title> <script src="https://cdn.jsdelivr.net/npm/vue"></script> </head> <body> <div id="app"> <cpn1></cpn1> </div> <script type="text/javascript"> const vm = new Vue({ el: '#app', components: { cpn1: { template: `<div>{{msg}}</div>`, data() { return { msg: 'Nanchen' } }, } } }) </script> </body> </html>
打印结果:
在局部组件中添加cpn1标签并且在添加data组件
二、组件中的data为什么必须要是函数?
这里看个例子:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>data必须是函数</title> <script src="https://cdn.jsdelivr.net/npm/vue"></script> <style type="text/css"> h2{ display: inline-block; } button{ width: 35px; height: 35px; line-height: 35px; } </style> </head> <body> <div id="app"> <h2>data不使用函数时:</h2> <cpn1></cpn1> <cpn1></cpn1> <hr> <h2>data使用函数时:</h2> <cpn2></cpn2> <cpn2></cpn2> <hr> </div> <template id="cpn1"> <div> <button @click="message--">-</button> <h2>{{message}}</h2> <button @click="message++">+</button> </div> </template> <template id="cpn2"> <div> <button @click="message--">-</button> <h2>{{message}}</h2> <button @click="message++">+</button> </div> </template> <script type="text/javascript"> const obj = { message: 0 }; const vm = new Vue({ el: '#app', components: { cpn1: { template: '#cpn1', data() { return obj } }, cpn2: { template: '#cpn2', data() { return { message: 0 } } } } }) </script> </body> </html>
实现效果:
可以看到,如果这个例子的return直接返回这个obj,那么上下的+-会同时进行
如果在data中使用函数时,它不会进行联动。显而易见,第二种使用函数的这个具有独立性,用起来更方便
简单的来说:如果 data 直接是一个对象的话,那么一旦修改其中一个组件的数据,其他组件相同数据就会被改变,而 data 是函数的话,每个 vue 组件的 data 都因为函数有了自己的作用域,互不干扰。
也可以这样理解:data没使用函数时把数据放在了栈内存中,data使用函数时把数据放在堆内存里
父组件给子组件传递数据——props属性
使用props属性,父组件向子组件传递数据
props数组写法:
props: ['cmovies', 'cmessage']
对象写法:
props: { cmessage: { type: String, // 类型限制 default: 'zzzzz', // 默认值 required: true //在使用组件必传值 } }
如果其中的类型是Object或者为Array类型,其默认值必须是一个函数
第一种写法:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>父组件给子组件传递数据</title> <script src="https://cdn.jsdelivr.net/npm/vue"></script> </head> <body> <div id="app"> <cpn1 :msg="message"></cpn1> </div> <template id="cpn1"> <div>I·am {{aaa}}</div> </template> <script type="text/javascript"> const vm = new Vue({ el:'#app', data(){ return{ message:'NanChen' } }, components:{ cpn1:{ template:'#cpn1', data(){ return{ aaa:this.msg } }, props:['msg'] //数组写法 } } }) </script> </body> </html>
效果如下:
第二种写法:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>第二种写法</title> <script src="https://cdn.jsdelivr.net/npm/vue"></script> </head> <body> <div id="app"> <cpn1 :msg="message"></cpn1> </div> <script type="text/javascript"> Vue.component('cpn1', { template: `<div>My name is{{msg}}</div>`, props: { msg: { type: String } } }) const vm = new Vue({ el: '#app', data() { return { message: ' NanChen' } }, }) </script> </body> </html>
效果如下:
第三种写法:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>第三种方法</title> <script src="https://cdn.jsdelivr.net/npm/vue"></script> </head> <body> <div id="app"> <cpn1 :msg="message"></cpn1> </div> <script type="text/javascript"> const vm = new Vue({ el: '#app', data() { return { message: ' NanChen' } }, components: { cpn1: { template: `<div>My name is{{msg}}</div>`, props: { msg: { type: String } } } } }) </script> </body> </html>
效果如下:
当然方法还有很多,这里就不一一举例了。
下面演示一下如果父组件传两个及以上的写法:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <script src="https://cdn.jsdelivr.net/npm/vue"></script> </head> <body> <div id="app"> <cpn1 :msg="message" :one="first"></cpn1> </div> <script type="text/javascript"> const vm = new Vue({ el:'#app', data(){ return{ message:'Welcome to', first:" Nanchen's blog" } }, components:{ cpn1:{ template: `<div>Hello everyone,{{msg}}——{{one}}</div>`, props:{ msg:{ type:String }, one:{ type:String } } }, } }) </script> </body> </html>
效果如下:
传默认值 :
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <script src="https://cdn.jsdelivr.net/npm/vue"></script> </head> <body> <div id="app"> <cpn1 :msg="message" ></cpn1> <!--:num="nums"--> </div> <script type="text/javascript"> const vm = new Vue({ el:'#app', data(){ return{ message:"My name is NanChen", // nums:"I'm 50 years old" } }, methods:{ }, components:{ cpn1:{ template: `<div>{{msg}}--{{num}}</div>`, props:{ msg:{ type:String }, num:{ type:String, default:'欢迎来到Nanchen的博客', // 如果上方没有nums值就会显示默认值里的文字 required:true //可以使用required选项来声明这个参数是否必须传入。 } } } } }) </script> </body> </html>
required:声明这个参数是否必须传入。
父组件传子组件数据——引用类型的两种写法
第一种:数组与对象的写法
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <script src="https://cdn.jsdelivr.net/npm/vue"></script> </head> <body> <div id="app"> <cpn1 :msg="message1"></cpn1> <cpn2 :msgs="message2"></cpn2> </div> <script type="text/javascript"> const vm = new Vue({ el:'#app', data(){ return{ message1:['Nan','Chen'], message2:{ name:'NanChen', age:39, sex:'unknown', }, } }, components:{ cpn1:{ template: `<div>这是一个数组,其包含:{{msg}}</div>`, props:{ msg:{ type:Array, }, } }, cpn2:{ template: `<div>My name is {{msgs.name}} I'm {{msgs.age}} years old</div>`, props:{ msgs:{ type:Object } } } }, }) </script> </body> </html>
效果如下图:
第二种Function类型:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>父传子引用类型</title> <script src="https://cdn.jsdelivr.net/npm/vue"></script> </head> <body> <div id="app"> <cpn1 :msg="add"></cpn1> <h2>{{count}}</h2> </div> <script type="text/javascript"> const vm = new Vue({ el:'#app', data:{ count:0 }, methods:{ add:function(){ return this.count++; } }, components:{ cpn1:{ template: `<div> <button @click="sum">+</button> </div>`, props:{ msg:{ type:Function // 引用类型 }, }, methods:{ sum(){ this.msg() } } } } }) </script> </body> </html>
效果: