这是我参与更文挑战的第8天,活动详情查看: 更文挑战
一、Vue中的组件
Vue视图层的灵魂 — 组件化
组件(Component)是 Vue.js 最强大的功能之一;
组件可以扩展 HTML 元素,封装可重用的代码;
在较高层面上,组件是自定义元素, Vue.js 的编译器为它添加特殊功能。在有些情况下,组件也可以是原生 HTML 元素的形式,以 is 特性扩展。
二、全局组件的创建和注册
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="app">
<my-component></my-component>
</div>
<div id="app1">
<my-component></my-component>
</div>
<script src="js/vue.js"></script>
<script>
var Profile = Vue.extend({
template:'<h1>自定义组件</h1>'
})
Vue.component('my-component',Profile);
new Vue({
el:'#app'
})
new Vue({
el:'#app1'
})
</script>
</body>
</html>
复制代码
调用Vue.extend()创建的是一个组件构造器,构造器有一个选项对象,选项对象的template属性用于定义组件要渲染的HTML
调用Vue.component()注册组件时,需要提供2个参数:组件的标签名 和 组件构造器;注册的组件要挂载到某个Vue实例下,否则它不会生效;
Vue.extend() 和 Vue.component():由于 Vue 本身是一个构造函数,Vue.extend() 是一个类继承方法,它用来创建一个 Vue 的子类并返回其构造函数;
而Vue.component() 的作用在于:建立指定的构造函数与 ID 字符串间的关系,从而让 Vue.js 能在模板中使用它;直接向 Vue.component() 传递 options 时,它会在内部调用 Vue.extend()。
三、局部组件的创建和注册
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="app">
<my-component></my-component>
</div>
<div id="app1">
<my-component></my-component>
</div>
<script src="js/vue.js"></script>
<script>
var Profile = Vue.extend({
template:'<h1>局部组件</h1>'
})
new Vue({
el:'#app',
components:{
'my-compoent':Profile
}
})
new Vue({
el:'#app1'
})
</script>
</body>
</html>
复制代码
四、另一种组件创建和注册方式
直接通过Vue.component注册或获取全局组件,主要体现在以下几种方式:
// 注册组件,传入一个扩展过的构造器
Vue.component(‘my-component’, Vue.extend({ /* … */ }))
// 注册组件,传入一个选项对象(自动调用 Vue.extend)
Vue.component(‘my-component’, { /* … */ })
// 获取注册的组件(始终返回构造器)
var MyComponent = Vue.component(‘my-component’)
4.1 自定义全局组件
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="app">
<my-component></my-component>
</div>
<script src="js/vue.js"></script>
<script>
Vue.component('my-component',{
template:'<h1>自定义全局组件</h1>'
})
new Vue({
el:'#app'
})
</script>
</body>
</html>
复制代码
4.2 自定义局部组件
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="app">
<my-component></my-component>
<my-component1></my-component1>
</div>
<script src="js/vue.js"></script>
<script>
Vue.component('my-component',{
template:'<h1>自定义全局组件</h1>'
})
Vue.component('my-component1',{
template:'<h1>自定义全局组件</h1>'
})
new Vue({
el:'#app',
components:{
'my-component1':{
template:'<h1>自定义全局组件1</h1>'
},
'my-component1':{
template:'<h1>自定义全局组件2</h1>'
}
}
})
</script>
</body>
</html>
复制代码
五、父子组件
组件意味着协同工作,通常父子组件会是这样的关系:组件 A 在它的模版中使用了组件 B 。
最简单的父子组件:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="app">
<parent-component></parent-component>
<parent-component1></parent-component1>
</div>
<script src="js/vue.js"></script>
<script>
//子组件
var Child = Vue.extend({
template:'<img src="https://juejin.cn/post/img/a.jpg">'
})
//父组件
var Parent = Vue.extend({
template:'<div><child-component></child-component><p>这个小姐姐很漂亮</p></div>'
components:{
'child-compoent':Child
}
})
Vue.compoent('parent-compoent',Parent)
new Vue({
el:'#app'
})
</script>
</body>
</html>
复制代码
在父子组件组合使用中要注意以下一些问题:
没有实例化的子组件不能拿出来单独使用!
<div id="app">
<parent-component></parent-component>
<child-component></child-component>
</div>
复制代码
在父标签内部嵌套子标签!
<div id="app">
<parent-component>
<child-component></child-component>
</parent-component>
</div>
复制代码
因为在父标签一旦生成真实的DOM,其内部的子标签就会被解析成为普通的HTML标签来执行,而且不是标准的HTML标签,会被浏览器过滤掉。
六、在组件上绑定Class和Style
数据绑定一个常见需求是操作元素的 class 列表和它的内联样式。因为它们都是属性 ,我们可以用v-bind 处理它们:只需要计算出表达式最终的字符串。
而且,把 v-bind 用于 class 和 style 时,表达式的结果类型除了字符串之外,还可以是对象或数组。
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="app">
<my-component :calss="{'active':isActive}"></my-component>
</div>
<script src="js/vue.js"></script>
<script>
Vue.compoent('my-compoent',{
template:`<div class="font">我是starm,</div>`
})
new Vue({
el:'#app',
data:{
isActive:true
}
})
</script>
</body>
</html>
复制代码
七、template和script标签
尽管在上面组件的组件注册的方式已经很简单,但是在template选项中拼接HTML的标签还是不符合常规的编程习惯,而且HTML元素和js代码混杂在一起造成了很大的耦合性。
那么,template和script标签可以帮助我们将定义在JS中的HTML模板分离出来。
注意: 两种注册方式效果一样,官方建议用第一种。
(1)使用template标签注册组件:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="app">
<my-component></my-component>
<template id="myComponent">
自定义模板
</template>
</div>
<script src="js/vue.js"></script>
<script>
Vue.compoent('my-compoent',{
template:'#myComponent'
})
new Vue({
el:'#app',
})
</script>
</body>
</html>
复制代码
(2)使用script标签注册组件:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="app">
<my-component></my-component>
<script type="text/x-template" id="myCompoent"></script>
</div>
<script src="js/vue.js"></script>
<script>
Vue.compoent('my-compoent',{
template:'#myComponent'
})
new Vue({
el:'#app',
})
</script>
</body>
</html>
复制代码
注意:使用
<script>
标签时,type指定为text/x-template,意在告诉浏览器这不是一段js脚本,浏览器在解析HTML文档时会忽略<script>
标签内定义的内容。
八、挂载选项data必须是函数
使用组件时,大多数可以传入到 Vue 构造器中的选项可以在 Vue.extend() 或Vue.component()中注册组件时使用,但有一个重要前提: data 必须是函数。
Vue.component('my-component', {
template: '#myTemplate',
data: function () {
return {
message: '你好,中国'
}
}
})
复制代码