组件的概念
组件封装的是完整的页面功能(包括了html、css、js)
组件是自定义标签,vue提供方法让程序员自定义标签,对页面进行模块化
Vue的组件就是一个Vue对象,组件的配置项没有el属性
组件的使用
定义组件
let 组件名=Vue.extend({
template:`<div>
<p>书籍名称:{{name}}</p>
</div>`,
data(){
return {
name:"三国演义"
}
}
})
定义组件的简写方式
let 组件名 = {
template:`<div>
<p>书籍名称:{{name}}</p>
</div>`,
data(){
return {
name:"三国演义"
}
}
}
注册组件
全局注册
Vue.component("自定义标签名",组件名)
局部注册
let vm =new Vue({
el:"#box",
components:{
"bookt":Book
}
});
使用组件
组件就是自定义标签,在html中使用此标签
<自定义标签名></自定义标签名>
案例
<div id="box">
聊天室:
<chat></chat>
</div>let chatObj = {
template: `
<div>
<div style="width:200px;height:300px;border:1px solid black" v-html="msg"></div><br/>
<input type="text" v-model="str" />
<input type="button" value="发送" @click="send" />
</div>`,
data: function() {
return {
str: "",
msg: ""
}
},
methods: {
send() {
this.msg += this.str + "<br/>"
this.str = "";
}
}
};
let vm = new Vue({
el: "div",
data: {},
components: {
"chat": chatObj
}
})
组件的嵌套
把一个组件的自定义标签写到另外一个组件的template中,就是组件嵌套
案例
<div id="box">
聊天室:
<chat></chat>
</div>let zujian = {
template: `<div>
<h5>常用语</h5>
<span v-for="item in words">{{item}} </span>
</div>`,
data() {
return {
words: ["你好", "吃了没"]
}
}
}
let chatObj = {
template: `
<div>
<div style="width:200px;height:300px;border:1px solid black" v-html="msg"></div><br/>
<input type="text" v-model="str" />
<input type="button" value="发送" @click="send" />
<common-words></common-words>
</div>
`,
data: function() {
return {
str: "",
msg: ""
}
},
methods: {
send() {
this.msg += this.str + "<br/>"
this.str = "";
}
},
components: {
"commonWords": zujian
}
};
let vm = new Vue({
el: "div",
components: {
"chat": chatObj
}
})
组件编写方式与Vue实例的区别
- 自定义标签名不可以和html官方标签名同名,自定义标签名如果是小驼峰,那么使用时,用短横线写法
- 组件的定义对象中没有el属性,只有根实例存在el属性,组件里使用template定义模板(html)
- 组件模板只能有一个根标签
- data配置项必须是个函数 原因:如果不是函数,那么,复用组件的data共享一块内存空间
组件的属性
使用props来完成组件属性的声明,props是外部给组件传入的数据,而data是组件内部的数据
使用props传递静态数据
<div id="box">
<!-- 相当于调用函数时传的实参 -->
<book name="三体" author="刘慈欣" price="152.8"></book>
</div>let book = {
//表示给当前组件声明属性,相对函数的形参。
props: ["name", "author", "price"],
template: `
<div>
<h1>{{title}}</h1>
<p>书名:{{name}}</p>
<p>作者:{{author}}</p>
<p>价格:{{price}}</p>
</div>
`,
data() {
return {
title: "书籍"
}
}
}
let vm = new Vue({
el: "#box",
components: {
"book": book
},
data: {
}
})
使用props传递动态数据
<div id="box">
<a href=""></a>
<!-- 相当于调用函数时传的实参 -->
<book v-bind:name="n" author="佚名" price="51.2"></book>
</div>let book = {
//表示给当前组件声明属性,相对函数的形参。
props: ["name", "author", "price"],
template: `
<div>
<h1>{{title}}</h1>
<p>书名:{{name}}</p>
<p>作者:{{author}}</p>
<p>价格:{{price}}</p>
</div>
`,
data() {
return {
title: "书籍"
}
}
}
let vm = new Vue({
el: "#box",
components: {
"book": book
},
data: {
n: "heihei"
}
})
当组件的属性是引用类型时(属性的简写)
<div id="">
<book :name="bookObj.name" :author="bookObj.author" :price="bookObj.price">或者: <book v-bind="bookObj"></book>相当于上面的写法,自动会展开全部传递
</book>
</div>let book = {
props: ["name", "author", "price"],
template: `<div>
<h1>{{title}}</h1>
<p>书名:{{name}}</P>
<p>作者:{{author}}</p>
<p>价格:{{price}}</p>
</div>`,
data() {
return {
title: "书籍信息"
}
}
}let vm = new Vue({
el: "div",
components: {
"book": book
},
data: {
bookObj: {
name: "三国",
author: "嘿嘿",
price: 25
}
}
})
属性形参是个对象时(注意传的是地址,在子组件改值,父数据也会改)
<div id="box">
<book :bookobj="bookObj"></book>
</div>let book = {
//传的是地址
props: ["bookobj"],
template: `
<div>
<h1>{{title}}</h1>
<p>{{bookobj.name}}</p>
<p>{{bookobj.author}}</p>
<p>{{bookobj.price}}</p>
<input type="button" value="修改" @click="changeName" />
</div>,
`,
data() {
return {
title: "书籍详情"
}
},
methods:{
//改了父组件的值
changeName(){
this.bookobj.name="haha"
}
}
}
let vm =new Vue({
el:"#box",
components:{
"book":book
},
data:{
bookObj:{
name:"三国",
author:" 132",
price:25
}
}
});
Prop验证
使用props可以对属性类型进行验证,属性默认值,属性是否必须等,这时props不是数组,而是对象
<book :name="bookObj.name" :author="bookObj.author" class="box"></book>
let book = {
props: {
name: {
type: String,
required: true
},
author: String,
price: {
type: Number,
default: 10
}
},
template: `<div>
<h1>{{title}}</h1>
<p>书名:{{name}}</p>
<p>作者:{{author}}</p>
<p>价格:{{price}}</p>
</div>`,
data(){
return {
title:"书籍"
}
}
}
let vm = new Vue({
el: 'div',
components: {
"book": book
},
data: {
bookObj: {
name: "hehie",
author:123,
price: 12
}
}
})
单向数据流
Prop是单向绑定的,当父组件的数据变化时,会传导给子组件,反过来不会,这是为了防止组件无意间修改了父组件的数据,但是如果props接收的是一个对象,传的就是地址,子组件进行操作会改变父组件的数据