目录
在组件中获取数据
看下面这个例子:
<!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>
效果: