前言
在日常实际开发中,常会遇到组件切换的需求,如:
1. 点击按钮后,登录组件的切换,切换不同登录方式;
2. tab切换选项卡;
方法一:使用 v-if, v-else(点击按钮显示不同登录组件)
<!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"> <!-- 给input添加key, 是为了让其相互独立,从而解决在一个input中输入信息切换后,当前input还保留之前输入的信息 --> <template v-if='loginType'> <div> <label for="username">用户名:</label> <input type="text" id="username" key='username-input' placeholder="enter your usernmae" /> </div> <div> <label for="password">密码:</label> <input type="password" id="password" key='password-input' placeholder="enter your password" /> </div> </template> <!-- <hr> --> <template v-else> <div> <label for="phoneNumber">手机号:</label> <input type="text" id="phoneNumber" key='phone-input' placeholder="enter your phone number" /> </div> <div> <label for="codeNumber">验证码:</label> <input type="text" id="codeNumber" key='code-input' placeholder="enter your code" /> </div> </template> <hr> <button type="button" @click='doSomething'>click me</button> </div> <script src="https://cdn.staticfile.org/vue/2.5.1/vue.min.js"></script> <script> var vm = new Vue({ el: '#app', data: { loginType: true }, methods: { doSomething() { if(this.loginType === true) { this.loginType = false } else { this.loginType = true } } } }) // this指向vm; vm.name; vm.age </script> </body> </html>
注:示例代码中给input加key,是为了让其相互独立,从而解决在input中输入信息数据残留的问题,
如输入用户名和密码后,点击按钮切换为手机号和验证码登录,此时不输入再切换回去,之前输入的信息会被清空,而不会留存
方法二:使用 is 动态组件(点击按钮显示不同登录组件)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>is动态组件实现切换</title> </head> <body> <div id="app"> <!-- 动态组件是一个有趣的东西,它相当于一张空白的组件,只要你告诉它它是什么组件,它就变成了什么组件。 有时候我们希望发生了xxx事件之后,页面的某个组件变成另一个组件。【你可能会产生如下图的需求:点击按钮,切换登录方式】 --> <!-- 我们只需要给component元素设置上is属性就可以把component元素渲染成目标组件了。 <component :is='组件名'></component>如果改变了is属性的值,那么渲染的组件就会发生变化。 is可以是v-bind的,也可以是非v-bind的,如果希望它是动态可变化的,那么应该使用v-bind:is, 这样才能传入一个变量,从而动态渲染组件。【非v-bind的时候传入的值会被认为一个字符串,然后直接把这个字符串认为是组件名】--> <!-- 重新创建动态组件的行为通常是非常有用的,但是在这个案例中,我们更希望那些标签的组件实例能够被在它们第一次被创建的时候缓存下来。 为了解决这个问题,我们可以用一个 <keep-alive> 元素将其动态组件包裹起来 --> <keep-alive> <component :is='loginType'></component> </keep-alive> <hr> <button type="button" @click='tabChange'>tabchange</button> </div> <script src="https://cdn.staticfile.org/vue/2.5.1/vue.min.js"></script> <script> Vue.component('loginInfo', { template: `<div> <div>用户名:<input type='text' /></div> <div>密码:<input type='password' /></div> </div>` }) Vue.component('phoneInfo', { template: `<div> <div>手机号:<input type='text' /></div> <div>验证码:<input type='text' /></div> </div>` }) var vm = new Vue({ el: '#app', data: { loginType: 'loginInfo' }, methods: { tabChange() { this.loginType = this.loginType === 'loginInfo'? 'phoneInfo': 'loginInfo' } } }) // this指向vm; vm.name; vm.age </script> </body> </html>
注:与方法一中示例demo中不同的是,这里使用<keep-alive>是为了把input中输入的信息缓存起来,即使切换后也不会清空
方法三:使用路由router实现tab切换
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>vue-router</title> <style> .nav { float: left; width: 300px; height: 300px; background-color: black; } .nav a { color: #fff; } .content { width: 600px; height: 300px; background-color: red; } </style> </head> <body> <div id="app"> <!-- 路由用于设定访问路径,并将路径和组件映射起来,这样就可以实现通过路由router来切换组件 --> <!--使用 router-link 组件来导航.--> <!-- 通过传入 `to` 属性指定链接. --> <div class="nav"> <router-link to="/vue">简易vue</router-link> <router-link to="/es6">趣味ES6</router-link> <router-link to="/career">人在职场</router-link> </div> <div class="content"> <!-- 匹配到的组件将渲染在这里 --> <router-view></router-view> </div> </div> <script src="https://cdn.staticfile.org/vue/2.5.1/vue.min.js"></script> <script src="https://unpkg.com/vue-router@2.5.3/dist/vue-router.js"></script> <script> // 局部注册3个组件 const vueComponent = { template: `<div> 这里是《简易vue》教程 </div>` }; const es6Component = { template: `<div> 这里是《趣味ES6》教程 </div>` } const careerComponent = { template: `<div> 《混口饭吃》与《工资待遇》 </div>` } //创建router实例,并定义导航和组件的映射关系 const router = new VueRouter({ //配置routes routes: [ //定义3个导航和组件的映射关系 { path: '/vue', component: vueComponent }, { path: '/es6', component: es6Component }, { path: '/career', component: careerComponent } ] }) //创建vue实例,注入路由router const vm = new Vue({ el: '#app', router //此处是ES6语法,相当于router:router }) </script> </body> </html>
有需要的朋友可以领取支付宝到店红包,能省一点是一点