组件:组件的出现,就是为了拆分vue实例的代码量的,能够让我们以不同组件,来划分不同功能之间的模块,将来我们需要什么样的功能,就去调用什么样的组件。
- 模块块:从代码逻辑的角度进行划分,方便代码分层开发,保证每个模块功能单一
- 组件化:是从
UI
界面的角度进行划分的,前端的组件化,方便UI
组件的复用
组件(Component)是Vue
最强大的功能之一,组件可扩展HTML
元素,封装可重用的代码。
全局组件定义的方法有三种方式:
使用Vue.extend
方法定义组件,使用Vue.commponent
方法
<!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>Document</title>
<script src="vue.js"></script>
</head>
<body>
<div id="app">
<!-- 使用组件 -->
<account></account>
</div>
<script>
//第一步使用 Vue.extend定义组件
var myconn = Vue.extend({
//通过templat属性 指定了组件要展示html的结构 template是vue内置关键字 不可更改
template: `
<div>
<h2>登录页面</h2>
<h2>注册页面</h2>
</div> `
})
//第二步使用Vue.component注册组件
Vue.component('account', myconn); //第一个参数是组件的名称,第二个参数是组件的模板
let vm = new Vue({
el: "#app",
data: {}
})
</script>
</body>
</html>
如果在注册时,组件的名称是驼峰命名比如:
Vue.component('myComponent',myAccount);//第一个参数是组件的名称,第二个参数是模板对象
在标签中使用组件时,需要把大写的驼峰改为小写的字母,同时两个单词用 - 进行连接
<my-component></my-component>
为了避免组件名不一致问题,直接在注册组件的时候使用-进行注册:
Vue.component('my-component',myAccount)
使用template
的时候要用一个大的根元素进行包裹,直接写<template><h2>登录页面</h2><h2><注册压面/h2></template>
会报错
直接使用Vue.component
方法定义、注册组件。一步到位
Vue.component('account', {
template: `
<div>
<h2>登录页面</h2>
<h2>注册页面</h2>
</div>`
})
推荐使用第三种方法这样有利用html
的书写
<!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>Document</title>
<script src="vue.js"></script>
</head>
<body>
<!--定义模板 -->
<template id="myCount">
<div>
<h2>登录组件</h2>
<h2>注册组件</h2>
</div>
</template>
<div id="app">
<!-- 使用组件 -->
<acount></acount>
</div>
<script>
//定义、注册组件
Vue.component('acount', {
template: '#myCount'
})
let vm = new Vue({
el: "#app",
data: {
}
})
</script>
</body>
</html>
<!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>Document</title>
<script src="vue.js"></script>
</head>
<body>
<!--定义模板 -->
<template id="myCount">
<h3>这是私有login组件</h3>
</template>
<div id="app">
<!-- 使用组件 -->
<my-login></my-login>
</div>
<script>
//定义、注册组件
// Vue.component('acount', {
// template: '#myCount'
// })
let vm = new Vue({
el: "#app",
data: {
},
components: { //定义注册Vue实例内部的私有组件
myLogin: {
template: "#myCount"
}
}
})
</script>
</body>
</html>
组件是一个页面,那么就会需要动态的功能
<!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>Document</title>
<script src="vue.js"></script>
</head>
<body>
<!-- 定义组件模板 -->
<template id="myCount">
<div>
{{ myDate}}
<a href="#" @click="login">登录1</a>
<h2>登录页面</h2>
<h3>注册页面</h3>
</div>
</template>
<div id="app">
<!-- 第一次使用组件 -->
<acount></acount>
<!-- 第二次使用组件 -->
<acount></acount>
</div>
<script>
Vue.component('acount', {
template: "#myCount",
data: function () {
return {
myDate: 'Ljfy',
}
},
//组件中的methods
methods: {
login: function () {
document.write(1);
}
}
})
let vm = new Vue({
el: "#app",
})
</script>
</body>
</html>
在为组件添加数组时data
不在是对象了,而是function
,而且要通return
的形式返回,否则页面上无法看到效果的。通过function
返回的兑现的形式来定义data
,作用是:
- 组件中
<account>
被调用了两次(不像根组件那样只能调用一次,每个组件中myData
都是独立的,不产生冲突 - 通过函数返回对象的目的,是为了让每个组件都有自己独立的数据存储,而不是共享一套数据
function Component(){
this.data = this.data
}
Component.prototype.data = {
name:"jack",
age:22
}
实例他们的构造函数内的this内容是不一样的
Component.prototype
这类底下的方法或者值,都是所有实例公开的
function Component(){
}
Component.prototype.data = {
name:"jack",
age:22
}
var componentA = new Component();
var componentB = new Component();
componentA.data.age = 55
console.log(componentA,componentB);
此时componentA
和componentB
data之间指向了同一个内存地址,age变成了55,导致了问题
接下就很好解释vue
组件需要function
function Component(){
this.data = this.data()
}
Component.prototype.data = function(){
return{
name:"jack",
age:22
}
}
var componentA = new Component();
var componentB = new Component();
componentA.data.age = 55
console.log(componentA,componentB);
此时的componentA
和componentA
是相互独立的,data
的age分别是55和22
v-if
和v-else
结合flag
进行切换
<!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>Document</title>
<script src="vue.js"></script>
</head>
<body>
<div id="app">
<!-- .prevent阻止超链接的默认事件 -->
<a href="" @click.prevent="flag=true">登录</a>
<a href="" @click.prevent="flag=false">注册</a>
<!-- 登录组件/注册组件,同时只显示一个 -->
<login v-if="flag"></login>
<register v-else="flag"></register>
</div>
<script>
Vue.component('login', {
template: '<h3>登录组件</h3>'
})
Vue.component('register', {
template: '<h3>注册组件</h3>'
})
let vm = new Vue({
el: "#app",
data: {
flag: false
}
})
</script>
</body>
</html>
v-if..else
只能控制一个,两个切换,那么三个,四个怎么办呢?
Vue内置component
<!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>Document</title>
<script src="vue.js"></script>
</head>
<body>
<div id="app">
<!-- vue提供了component 来展示对象的组件
:is 指定要展示组件的名称
-->
<a href="" @click.prevent="comName='login'">登录</a>
<a href="" @click.prevent="comName='register'">注册</a>
<component :is="comName"></component>
</div>
<script>
Vue.component('login', {
template: '<h3>登录组件</h3>'
})
Vue.component('register', {
template: '<h3>注册组件</h3>'
})
let vm = new Vue({
el: "#app",
data: {
comName: 'login'
}
})
</script>
</body>
</html>