1、组件中的data
1.1、组件中的data介绍
- 组件可以有自己的data数据;
- 组件的data和实例的data有点不一样,实例中的data可以为一个对象,但是组件的data必须是一个方法;
- 组件中的data除了必须为一个方法以外,这个方法内部,还必须返回一个对象才行;
- 组件中的data数据使用方式和实例中的data使用方式完全一样;
组件中的data可以在组件中使用,组件的data是一个函数,那么我们就可以在data函数中定义逻辑代码,组件的数据是每个组件实例独有的(隔离),Vue对象本质其实也是一个组件,我们认为它就是父组件,自己定义的组件就是子组件,父子组件各自的数据也是隔离的(子组件无法直接使用父组件的data中的属性,父组件也无法直接访问子组件data中的属性)。
1.2、组件中的data使用实例
<style type="text/css">
.main-nav ul{
list-style: none;
}
.main-nav ul li{
float: left;
padding: 10px;
}
</style>
<div id="app">
<main-nav class="main-nav"></main-nav>
</div>
<!-- 定义组件模板 -->
<template id="main-nav">
<div>
<h4>{{name}}公司的网站</h4>
<ul>
<li v-for="(item,index) in navList" :key="index">
<a :href="item.url">{{item.name}}</a>
</li>
</ul>
</div>
</template>
<script src="../lib/vue.js"></script>
<script>
let main_nav = {
template: '#main-nav',
data(){
//逻辑代码
return {
name: '张三',
navList:[
{name: '首页', url: '/home'},
{name: '公司简介', url: '/about'},
{name: '产品列表', url: '/products'},
{name: '新闻资讯', url: '/news'},
{name: '在线留言', url: '/feedback'},
{name: '联系方式', url: '/contact'},
]
}
}
};
Vue.component('main-nav', main_nav);
const vm = new Vue({
el: '#app',
data:{},
//components配置项用来定义局部组件
components:{
}
});
</script>
运行结果:

1.3、组件实例之间的数据是独立的
定义一个组件,将该组件使用2次,虽然使用的是同一个组件,但是两次使用,实际上是创建了两个组件实例,两个组件实例之间的数据互不影响。
<div id="app">
<!-- 使用2次 -->
<btn-tpl></btn-tpl>
<btn-tpl></btn-tpl>
</div>
<template id="btn-tpl">
<div>
<p>当前数字是:{{count}}</p>
<button type="button" @click="add">点击计数+1</button>
</div>
</template>
<script src="../lib/vue.js"></script>
<script>
let btn_tpl = {
template: '#btn-tpl',
data(){
//逻辑代码
return {
count: 0
}
},
methods: {
add(){
this.count ++;
}
},
};
Vue.component('btn-tpl', btn_tpl);
const vm = new Vue({
el: '#app',
data:{},
});
</script>
运行测试:

2、切换组件
定义两个组件(登录、注册)用来测试组件切换:
<!-- 登录组件模板 -->
<template id="login-tpl">
<div>
<div class="col-lg-6 offset-lg-3">
<h4 class="text-center my-3">用户登录</h4>
<div class="mb-3">
<label for="email" class="form-label">邮箱:</label>
<input type="email" class="form-control" id="email" v-model="email">
<div id="emailHelp" class="form-text">输入登录使用的邮箱.</div>
</div>
<div class="mb-3">
<label for="password" class="form-label">密码:</label>
<input type="password" class="form-control" id="password" v-model="password">
</div>
<div class="mb-3 form-check">
<input type="checkbox" class="form-check-input" id="remember" v-model="remember">
<label class="form-check-label" for="remember">记住</label>
</div>
<button type="submit" class="btn btn-primary" @click="login">登 录</button>
</div>
</div>
</template>
<!-- 注册组件模板 -->
<template id="register-tpl">
<div>
<div class="col-lg-6 offset-lg-3">
<h4 class="text-center my-3">用户注册</h4>
<div class="mb-3">
<label for="exampleInputEmail1" class="form-label">邮箱:</label>
<input type="email" class="form-control" id="exampleInputEmail1" aria-describedby="emailHelp">
<div id="emailHelp" class="form-text">输入注册使用的邮箱.</div>
</div>
<div class="mb-3">
<label for="exampleInputPassword1" class="form-label">密码:</label>
<input type="password" class="form-control" id="exampleInputPassword1">
</div>
<div class="mb-3">
<label for="confirm_password" class="form-label">密码确认:</label>
<input type="password" class="form-control" id="confirm_password" v-model="confirm_password">
</div>
<button type="submit" class="btn btn-primary" @click="register">注 册</button>
</div>
</div>
</template>
两个组件的配置项:
<script>
let login_conf = {
template: '#login-tpl',
data(){
return {
email: '',
password: '',
remember: false
}
},
methods: {
login(){
console.log(`登录成功,邮箱是:${this.email},密码是:${this.password},是否记住密码:${this.remember ? '是' : '否'}`);
}
},
};
let register_conf = {
template: '#register-tpl',
data(){
return {
email: '',
password: '',
confirm_password:''
}
},
methods:{
register(){
if(this.password !== this.confirm_password) {
console.log('注册失败,两次输入的密码不一致');
return false;
}
console.log(`注册成功,邮箱是:${this.email},密码是:${this.password},第二次输入的密码是:${this.confirm_password}`);
}
}
};
</script>
2.1、使用v-if、v-else指令实现组件切换
使用v-if、v-else判断current
属性的值,来实现切换。
<div id="app">
<div class="container">
<div class="row">
<div class="col-lg-12 text-center">
<a @click.prevent="current = 'login'" href="">登录</a>
<a @click.prevent="current = 'register'" href="">注册</a>
</div>
<!-- 一旦组件定义了,就可以当作标签来使用 -->
<login v-if="current == 'login'"></login>
<register v-else></register>
</div>
</div>
</div>
<script src="../lib/vue.js"></script>
<script>
//注册组件
Vue.component('login', login_conf);
Vue.component('register', register_conf);
const vm = new Vue({
el: '#app',
data:{
current: 'login'
},
methods:{
switchComponent(name){
this.current = name;
}
}
});
</script>
2.2、使用component
标签实现组件切换
<component :is="componentName"></component>
通过修改:is
绑定的动态属性的值来实现组件切换。
<div id="app">
<div class="container">
<div class="row">
<div class="col-lg-12 text-center">
<a @click.prevent="componentName = 'login'" href="">登录</a>
<a @click.prevent="componentName = 'register'" href="">注册</a>
</div>
<component :is="componentName"></component>
</div>
</div>
</div>
<script src="../lib/vue.js"></script>
<script>
//注册组件
Vue.component('login', login_conf);
Vue.component('register', register_conf);
const vm = new Vue({
el: '#app',
data:{
componentName: 'login'
}
});
</script>
2.3、组件过渡切换
官方文档:https://v2.cn.vuejs.org/v2/guide/transitions.html
语法:
<transition>
<component :is="componentName"></component>
</transition>
实例:
<!-- 定义样式 -->
<style>
.v-enter-active,.v-leave-active{
transition: all .3s;
}
.v-enter,.v-leave-to{
opacity: 0;
transform: translateX(10px);
}
</style>
<div id="app">
<div class="container">
<div class="row">
<div class="col-lg-12 text-center">
<a @click.prevent="componentName = 'login'" href="">登录</a>
<a @click.prevent="componentName = 'register'" href="">注册</a>
</div>
<!-- 将要实现过渡效果的组件切换包裹在transition标签中。
<transition>
<component :is="componentName"></component>
</transition>
</div>
</div>
</div>
对于这些在过渡中切换的类名来说,如果你使用一个没有名字的 <transition>
,则 v-
是这些类名的默认前缀。如果你使用了 <transition name="my-transition">
,那么 .v-enter
会替换为 .my-transition-enter
。