复习Vue12:组件化应用
12.1、组件概述:
在这一小节中,重点要理解的就是组件的编程思想。
组件标识页面中的部分功能(包括自己的逻辑与样式),可以组合多个组件实现完整的页面功能。
如下图所示:
问题是,如何确定页面中那些内容划分到一个组件中呢?
但你如何确定应该将那些部分划分到一个组件中呢?你可以将组件当做一种函数或者是对象来考虑(函数的功能是单一的),根据[单一功能原则
]来判断组件的范围。也就是说,一个组件原则上只能负责一个功能。如果它需要负责更多的功能,这时候就应该将它拆分成更小的组件。
组件有什么特点呢?
可复用、维护、可组合
可复用:每个组件都是具有独立功能的,他可以被使用在多个场景中。
可维护:每个组件仅仅包含自身的逻辑,更容易被理解和维护。
可组合:一个组件可以和其它的组件一起使用或者可以直接嵌套在另一个组件内部。
12.2、组件的基本使用
组件的具体创建过程如下:
Vue.component('index', {
template: '<div>我是首页的组件</div>'
})
第一个参数指定了所创建的组件名字,第二个参数制定了模板。
组件创建好以后,具体的使用方式如下:
<div id="app">
<index></index>
</div>
注意:1、模板template
中只能有一个根节点;2、组件的名字,如果采用驼峰式命名的话,在使用的时候,就要加上-
,比如组件的名称叫indexA
那么在使用的时候就叫index-a
.
例如:
Vue.component('componentA', {
template: "<div>创建一个新的组件</div>"
})
组件使用:
<component-a></component-a>
在Vue
实例中所使用的选项,在组件中都是可以使用的,但是要注意data
,在组件中使用时必须是一个函数。
下面创建一个about
组件。
Vue.component('about', {
template: '<div>{{msg}}<button @click="showMsg">单击</button></div>',
data() {
return {
msg: '大家好'
}
},
methods: {
showMsg() {
this.msg = "关于组件"
}
}
})
组件的使用如下:
<about></about>
在组件中关于data不是一个对象,而是一个函数的原因,官方文档有明确的说明
链接: 组件基础.
组件创建完整的代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>组件创建</title>
<!-- <script src="./vue.js"></script> -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<component-a></component-a>
<index></index>
<index></index>
<about></about>
</div>
<script>
Vue.component('componentA', {
template: "<div>创建一个新的组件</div>"
})
Vue.component('index', {
template: '<div>我是首页的组件</div>'
})
Vue.component('about', {
template: '<div>{{msg}}<button @click="showMsg">单击</button></div>',
data() {
return {
msg: '大家好'
}
},
methods: {
showMsg() {
this.msg = "关于组件"
}
}
})
var vm = new Vue({
el: '#app',
data: {
}
})
</script>
</body>
</html>
在使用组件的时候,需要注意以下几个内容:
第一点:data
必须是一个函数
关于这一点,官方文档说的比较详细清楚:https://cn.vuejs.org/v2/guide/components.html
第二点:组件模板中必须有一个根元素。
第三点:组件模板内容可以使用模板字符串。
Vue.component("about", {
template: `<div>
{{msg}}
<button @click='showMsg'>单击
</button>
</div>`,
data() {
return {
msg: "大家好",
};
},
methods: {
showMsg() {
this.msg = "关于VUE组件";
},
},
});
在上面的代码中,我们在组件的模板中使用类模板字符串,这样就可以调整对应的格式,例如换行等。
第四点:现在我们创建的组件全部都是全局组件,可以在其他组件中使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>组件基本使用</title>
</head>
<body>
<div id="app">
<index></index>
<component-a></component-a>
<about></about>
<!-- 使用HelloWorld组件 -->
<hello-world></hello-world>
</div>
<!-- <script src="./vue.js"></script> -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
Vue.component("index", {
template: "<div>我是Index组件</div>",
});
// 创建了HelloWorld组件
Vue.component("HelloWorld", {
data() {
return {
msg: "Hello World",
};
},
template: "<div>{{ msg}}</div>",
});
// 使用HelloWorld组件
Vue.component("componentA", {
template: "<div>我是一个新的组件:<HelloWorld></HelloWorld></div>",
});
Vue.component("about", {
template: `<div>
{{msg}}
<button @click='showMsg'>单击
</button>
</div>`,
data() {
return {
msg: "大家好",
};
},
methods: {
showMsg() {
this.msg = "关于VUE组件";
},
},
});
const vm = new Vue({
el: "#app",
data: {},
});
</script>
</body>
</html>
在上面的代码中,我们又创建了一个HelloWorld
组件,并且在componentA
组件中去使用了helloworld
组件,这里还需要注意的一点就是,在componentA
这个组件中使用HellowWorld
这个组件的时候,可以使用驼峰命名的方式,但是在<div id="app"></div>
这个普通的标签模板中,必须使用短横线的方式,才能使用组件。
12.3、局部组件注册
我们可以在一个组件中,再次注册另一个组件,这样就构成了父子关系。
我们通过components
来创建对应的子组件。
组件的创建过程如下:
<script>
Vue.component('father', {
template: '<div><p>我是父组件</p><son></son></div>',
components: {
// 创建一个子组件
son: {
template: '<p>我是子组件</p>'
}
}
})
var vm = new Vue({
el: '#app',
data: {
}
})
</script>
组件的使用:
<div id="app">
<father></father>
</div>
完整代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>父子组件创建</title>
<!-- <script src="./vue.js"></script> -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<father></father>
</div>
<script>
Vue.component('father', {
template: '<div><p>我是父组件</p><son></son></div>',
components: {
// 创建一个子组件
son: {
template: '<p>我是子组件</p>'
}
}
})
var vm = new Vue({
el: '#app',
data: {
}
})
</script>
</body>
</html>
在上面的代码中,我们是在全局的father
组件中,又创建了一个子组件son
.
那么son
这个子组件也就是一个局部的组件。也就是它只能在father
组件中使用。
当然,我们在father
中定义子组件son
的时候,直接在其内部构建模板内容,这样如果代码非常多的时候,就不是很直观。
所以这里,我们可以将son
组件,单独进行定义,然后在father
组件中进行注册。
改造后的代码如下所示:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>局部组件</title>
<!-- <script src="./vue.js"></script> -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<father></father>
</div>
<script>
const son = {
data() {
return {
msg: "Hello 我是子组件",
};
},
template: `<div>{{msg}}</div>`,
};
Vue.component("father", {
template: "<div><p>我是父组件</p><son></son></div>",
components: {
// 创建一个子组件
// son: {
// template: "<p>我是子组件</p>",
// },
son: son,
},
});
var vm = new Vue({
el: "#app",
data: {},
});
</script>
</body>
</html>
在上面的代码中,我们将son
组件单独进行了定义,这是注意写法,是一个对象的格式,在对象中包含了关于组件很重要的内容为data
函数与template
属性。
同时在father
组件中通过componrnts
属性完成对son
组件的注册
我们说过son
组件是一个局部的组件,那么只能在其注册的父组件中使用。
现在我们可以测试一下
完整代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>局部组件</title>
<!-- <script src="./vue.js"></script> -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<father></father>
<!-- 使用ComponentA组件 -->
<component-a></component-a>
</div>
<script>
const son = {
data() {
return {
msg: "Hello 我是子组件",
};
},
template: `<div>{{msg}}</div>`,
};
//定义ComponentA组件
Vue.component("ComponentA", {
template: "<div><son></son></div>",
});
Vue.component("father", {
template: "<div><p>我是父组件</p><son></son></div>",
components: {
// 创建一个子组件
// son: {
// template: "<p>我是子组件</p>",
// },
son: son,
},
});
var vm = new Vue({
el: "#app",
data: {},
});
</script>
</body>
</html>
在上面的代码中,我们又创建了一个全局的组件ComponentA
组件,并且在该组件中使用了son
组件,注意这里没有在ComponentA
中使用components
来注册son
组件,而是直接使用。同时在<div id="app"></div>
中使用了ComponentA
组件,这时在浏览器中,打开上面的程序,会出现错误
如下:
如果现在就想在ComponentA
组件中使用son
组件,就需要使用components
来注册。
Vue.component("ComponentA", {
template: "<div><son></son></div>",
components: {
son: son,
},
});
现在在ComponentA
组件中注册了son
组件,这时刷新浏览器就不会出错了。
在上面的案例中,我们是在一个全局的组件中注册了一个局部的组件,其实,我们也可以在Vue
实例中,注册对应的局部组件。因为,我们也可以将Vue
实例作为一个组件。
下次代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>局部组件</title>
<!-- <script src="./vue.js"></script> -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<father></father>
<component-a></component-a>
<hello-msg></hello-msg>
</div>
<script>
const son = {
data() {
return {
msg: "Hello 我是子组件",
};
},
template: `<div>{{msg}}</div>`,
};
// 定义HelloMsg组件
const HelloMsg = {
data() {
return {
msg: "Hello World",
};
},
template: `<div>{{msg}}</div>`,
};
Vue.component("ComponentA", {
template: "<div><son></son></div>",
components: {
son: son,
},
});
Vue.component("father", {
template: "<div><p>我是父组件</p><son></son></div>",
components: {
// 创建一个子组件
// son: {
// template: "<p>我是子组件</p>",
// },
son: son,
},
});
var vm = new Vue({
el: "#app",
data: {},
components: {
"hello-msg": HelloMsg,
},
});
</script>
</body>
</html>
在上面的代码中,我们又创建了一个组件HellwMsg
然后将HelloMsg
组件注册到了Vue
实例中,注意:在进行组件注册的时候的语法格式。
左侧为组件的名称,由于这个组件创建的时候采用的是驼峰命名的方式,所以组件的名称采用短横线的方式。
右侧为组件的内容。
下面就可以在其<div id="app"></div>
中使用了。
同理,在其它的组件中是无法使用HelloMsg
组件的。