跳转到主要内容

主页内容

Vue组件(二)Vue组件中的data及多组件切换

由 webadmin 发布于 阅读 17 次

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