三北防护林体系建设网站,北京市网站设计公司网址,wordpress kleo,个人网站对应网站网址文章目录1.引言2.定义全局组件3.组件的复用4.局部注册5.组件通信5.1.父向子传递props5.2.传递复杂数据5.3.子向父的通信1.引言
在大型应用开发的时候#xff0c;页面可以划分成很多部分。往往不同的页面#xff0c;也会有相同的部分。例如可能会有相同的头部导航。
但是如果…
文章目录1.引言2.定义全局组件3.组件的复用4.局部注册5.组件通信5.1.父向子传递props5.2.传递复杂数据5.3.子向父的通信1.引言
在大型应用开发的时候页面可以划分成很多部分。往往不同的页面也会有相同的部分。例如可能会有相同的头部导航。
但是如果每个页面都独自开发这无疑增加了开发的成本。所以会把页面的不同部分拆分成独立的组件然后在不同页面就可以共享这些组件避免重复开发。
2.定义全局组件
通过Vue的component方法来定义一个全局组件。
!DOCTYPE html
html langen
headmeta charsetUTF-8titlevuejs测试/title
/head
bodydiv idapp!--使用定义好的全局组件--counter/counter
/div
script srcnode_modules/vue/dist/vue.js/script
script typetext/javascript//定义组件const counter {template: button clicknum你点击了{{num}}次我记住了/button,data() {return {num: 0}}};//全局注册组件参数1组件名称参数2组件Vue.component(counter, counter);var app new Vue({el: #app});/script
/body
/html组件其实也是一个Vue实例因此它在定义时也会接收data、methods、生命周期函数等不同的是组件不会与页面的元素绑定否则就无法复用了因此没有el属性。但是组件渲染需要html模板所以增加了template属性值就是HTML模板全局组件定义完毕任何vue实例都可以直接在HTML中通过组件名称来使用组件了data的定义方式比较特殊必须是一个函数。
效果
3.组件的复用
定义好的组件可以任意复用多次
!DOCTYPE html
html langen
headmeta charsetUTF-8titlevuejs测试/title
/head
bodydiv idapp!--使用定义好的全局组件--counter/countercounter/countercounter/counter
/div
script srcnode_modules/vue/dist/vue.js/script
script typetext/javascript//定义组件const counter {template: button clicknum你点击了{{num}}次我记住了/button,data() {return {num: 0}}};//全局注册组件参数1组件名称参数2组件Vue.component(counter, counter);var app new Vue({el: #app});/script
/body
/html你会发现每个组件互不干扰都有自己的num值。怎么实现的 组件的data属性必须是函数 当定义这个 counter 组件时它的data 并不是像这样直接提供一个对象
data: {num: 0
}取而代之的是一个组件的 data 选项必须是一个函数因此每个实例可以维护一份被返回对象的独立的拷贝
data: function () {return {num: 0}
}如果 Vue 没有这条规则点击一个按钮就会影响到其它所有实例
4.局部注册
一旦全局注册就意味着即便以后你不再使用这个组件它依然会随着Vue的加载而加载。
因此对于一些并不频繁使用的组件会采用局部注册。
在外部定义一个对象结构与创建组件时传递的第二个参数一致
然后在Vue中使用它
!DOCTYPE html
html langen
headmeta charsetUTF-8titlevuejs测试/title
/head
body
div idapp!--使用定义好的全局组件--counter/countercounter/countercounter/counter
/div
script srcnode_modules/vue/dist/vue.js/script
script//定义组件const counter {template: button clicknum你点击了{{num}}次我记住了/button,data() {return {num: 0}}};//全局注册组件参数1组件名称参数2组件//Vue.component(counter, counter);var app new Vue({el: #app,//局部注册组件components: {counter: counter}});
/script
/body
/htmlcomponents就是当前vue对象子组件集合。 其key就是子组件名称其值就是组件对象的属性 效果与刚才的全局注册是类似的不同的是这个counter组件只能在当前的Vue实例中使用
5.组件通信
通常一个单页应用会以一棵嵌套的组件树的形式来组织
页面首先分成了顶部导航、左侧内容区、右侧边栏三部分左侧内容区又分为上下两个组件右侧边栏中又包含了3个子组件
各个组件之间以嵌套的关系组合在一起那么这个时候不可避免的会有组件间通信的需求。
5.1.父向子传递props
比如有一个子组件 Vue.component(introduce,{// 直接使用props接收到的属性来渲染页面template:h3{{title}}/h3,props:[title] // 通过props来接收一个父组件传递的属性
})这个子组件中要使用title属性渲染页面但是自己并没有title属性通过props来接收父组件属性名为title
父组件使用子组件同时传递title属性
!DOCTYPE html
html langen
headmeta charsetUTF-8titlevuejs测试/title
/head
body
div idapp!--使用定义好的全局组件--introduce :titlemsg/introduce
/div
script srcnode_modules/vue/dist/vue.js/script
script//定义组件const introduce {//使用props属性title的值渲染模版template: h2{{title}}/h2,//定义接收来自父组件的属性props: [title]};//全局注册组件参数1组件名称参数2组件Vue.component(introduce, introduce);var app new Vue({el: #app,data: {msg: 父组件中的msg属性的内容}});
/script
/body
/html效果 5.2.传递复杂数据
定义一个子组件 const myList {template: \ul\li v-foritem in items :keyitem.id{{item.id}} : {{item.name}}/li\/ul\,props: { // 通过props来接收父组件传递来的属性items: {// 这里定义items属性type: Array,// 要求必须是Array类型default: [] // 如果父组件没有传那么给定默认值是[]}}};这个子组件可以对 items 进行迭代并输出到页面。但是组件中并未定义items属性。通过props来定义需要从父组件中接收的属性 items是要接收的属性名称 type限定父组件传递来的必须是数组否则报错type的值可以是Array或者Object传递对象的 时候使用default默认值
default如果是对象则需要写成方法的方式返回默认值。如
default(){return {xxx:默认值};
}页面内容
!DOCTYPE html
html langen
headmeta charsetUTF-8titlevuejs测试/title
/head
body
div idapph2学习的课程有/h2!-- 接受来自父组件的属性值使用v-bind指向父组件的属性lessons注意使用my-list --my-list :itemslessons/my-list
/div
script srcnode_modules/vue/dist/vue.js/script
script//定义组件const myList {//可以使用双引号、单引号或者如下使用的 飘号template: ulli v-foritem in items :keyitem.id{{item.id}}--{{item.name}}/li/ul,//定义接收来自父组件的属性props: {//定义模版中使用的属性items: {//必须为数组类型type: Array,//默认为空数组default: []}}};var app new Vue({el: #app,data: {msg: 父组件中的msg属性的内容,lessons: [{id: 1, name: Java},{id: 2, name: PHP},{id: 3, name: 前端}]},//注册组件components: {//如果组件key和value一致可以简写如下myList}});
/script
/body
/html效果
5.3.子向父的通信
来看这样的一个案例
!DOCTYPE html
html langen
headmeta charsetUTF-8titlevuejs测试/title
/head
body
div idapph2num {{num}}/h2!--使用定义好的全局组件--counter :snumnum/counter
/div
script srcnode_modules/vue/dist/vue.js/script
script//定义组件const counter {//组件只能是一个元素里面包裹其他元素如下面一个div包含两个按钮template: divbutton clicksnum/buttonbutton clicksnum---/button/div,props: [snum]};//全局注册组件参数1组件名称参数2组件Vue.component(counter, counter);var app new Vue({el: #app,data: {num: 0}});
/script
/body
/html子组件接收父组件的num属性子组件定义点击按钮点击后对num进行加或减操作
尝试运行好像没问题点击按钮试试 子组件接收到父组件属性后默认是不允许修改的。怎么办 既然只有父组件能修改那么加和减的操作一定是放在父组件
var app new Vue({el: #app,data: {num: 0},methods: {//父组件中定义操作num的方法numPlus() {this.num;},numReduce() {this.num--;}}});但是点击按钮是在子组件中那就是说需要子组件来调用父组件的函数怎么做 可以通过v-on指令将父组件的函数绑定到子组件上
div idapph2num {{num}}/h2!--使用定义好的全局组件--counter plusnumPlus reducenumReduce :snumnum/counter
/div然后当子组件中按钮被点击时调用绑定的函数
//定义组件const counter {//组件只能是一个元素里面包裹其他元素如下面一个div包含两个按钮template: divbutton clickincrNum/buttonbutton clickdecrNum-/button/div,props: [snum],methods: {//点击模板中使用的方法incrNum() {return this.$emit(plus);},decrNum() {return this.$emit(reduce);}}};完成页面如下
!DOCTYPE html
html langen
headmeta charsetUTF-8titlevuejs测试/title
/head
body
div idapph2num {{num}}/h2!--使用定义好的全局组件--counter plusnumPlus reducenumReduce :snumnum/counter
/div
script srcnode_modules/vue/dist/vue.js/script
script//定义组件const counter {
//组件只能是一个元素里面包裹其他元素如下面一个div包含两个按钮template:
div
button clickincrNum/button
button clickdecrNum-/button
/div
,props: [snum],methods: {
//点击模板中使用的方法incrNum() {return this.$emit(plus);},decrNum() {return this.$emit(reduce);}}};//全局注册组件参数1组件名称参数2组件Vue.component(counter, counter);var app new Vue({el: #app,data: {num: 0},methods: {
//父组件中定义操作num的方法numPlus() {this.num;},numReduce() {this.num--;}}});
/script
/body
/htmlvue提供了一个内置的this.$emit函数用来调用父组件绑定的函数
效果 子组件不能直接修改父组件传递参数的引用或者基本类型参数值。