前端路由和后端路由的概念
后端路由: 对于普通网站,所有的链接都是URL地址,所有的URL地址都对应服务器上对应的资源
前端路由: 对于单页面应用程序来说,主要通过URL的hash(#号),来实现不同页面之间的切换,同时,hash有一个特点,HTTP请求中不包含hash相关的内容,所以单页面程序中的页面跳转主要用hash来实现
在单页面应用程序中,这种通过hash改变切换页面的方式,称作前端路由(区别于后端路由)
vue-router
Vue-router3.0安装方式:
1 2 3 4
| import Vue from 'vue' import VueRouter from 'vue-router'
Vue.use(VueRouter)
|
- 构建开发版
1 2 3 4
| git clone https://github.com/vuejs/vue-router.git node_modules/vue-router cd node_modules/vue-router npm install npm run build
|
基本用法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| <div id="app"> <p><font color="red">*</font>地址:<span>{{route_path}}</span></p> <font color="red">地址无刷新不会变化,这也正印证了上边的特性</font>
<router-link to="/login">登录</router-link> <router-link to="/register">注册</router-link><br> <router-view></router-view> </div> <template id="login"> <div> <label>用户名</label> <input type="text" name=""><br> <label>密码</label> <input type="text" name=""><br> <button type="button">登录</button> </div> </template> <template id="register"> <div> <label>用户名:</label> <input type="text" name=""><br> <label>密码:</label> <input type="text" name=""><br> <label>确认密码:</label> <input type="text" name=""><br> <button type="button">注册</button> </div>
</template>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
|
var login = { template:'#login' } var register = { template:'#register' }
var routerObj = new VueRouter({ routes:[ {path:'/login',component:login}, {path:'/register',component:register}, ] }) var vm = new Vue({ el:'#app', data:{ route_path: '' }, methods:{ }, created(){ this.route_path = this.$route.path }, components:{ login, register }, router:routerObj })
|
这样默认展示根路径 /
,很别扭
1 2 3 4 5 6 7 8 9 10
| var routerObj = new VueRouter({ routes:[ {path:'/',redirect:'/login'} {path:'/login',component:login}, {path:'/register',component:register}, ] })
|
需求1:设置选中路由高亮
1 2 3 4 5 6 7 8 9 10
| <style> .router-link-active{ color:red; font-weight:800; font-style: italic; font-size:20px; text-decoration: underline; background-color:green; } </style>
|
1 2 3 4 5 6 7 8 9 10 11
| var routerObj = new VueRouter({ routes:[ {path:'/',redirect:'/login'} {path:'/login',component:login}, {path:'/register',component:register}, ], linkActiveClass:'myactive' })
|
需求2: 为路由切换加入动画
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <style> .v-enter, .v-leave{ opacity: 0; transform: translateX(140px) } .v-enter-active, .v-leave-active{ transition: all 0.4s ease } </style> <transition mode="out-in"> <router-view></router-view> </transition>
|
路由规则中定义参数
1 2 3 4 5 6
| <div id="app"> <router-link to="/login?id=1&name=dong">登录</router-link> <router-link to="/register">注册</router-link> <router-view></router-view> </div>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| var login = { template:'<h1>登录---ID:{{$route.query.id}}---用户:{{$route.query.name}}</h1>', created(){ console.log(this.$route) } } var register = { template:'<h1>注册</h1>' } var router = new VueRouter({ routes:[ {path:'/',redirect: '/login'}, {path:'/login',component: login}, {path:'/register',component: register} ] }) var vm = new Vue({ el:'#app', data:{
}, methods:{}, router:router })
|
- $route.params
1 2 3 4 5 6
| <div id="app"> <router-link to="/login/:id">登录</router-link> <router-link to="/register">注册</router-link> <router-view></router-view> </div>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| var login = { template:'<h1>登录---{{$route.params.id}}</h1>', created(){ console.log(this.$route) } } var register = { template:'<h1>注册</h1>' } var router = new VueRouter({ routes:[ {path:'/',component: login}, {path:'/login/12',component: login}, {path:'/register',component: register} ] }) var vm = new Vue({ el:'#app', data:{
}, methods:{}, router:router })
|
路由的嵌套(children)
使用 children
属性 ,实现子路由,同时,子路由的path前面,不要带 / ,否则永远以根路径开始请求,这样不方便用户理解 url 地址
1 2 3 4 5 6 7 8 9 10 11 12
| <div id="app"> <router-link to="/account">Account</router-link> <router-view></router-view> </div> <template id="temp1"> <div> <h1>这是Account组件</h1> <router-link to="/account/login">登录</router-link> <router-link to="/account/register">注册</router-link> <router-view></router-view> </div> </template>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| var account = { template:'#temp1' } var login = { template:'<h4>登录</h4>' } var register = { template:'<h4>注册</h4>' } var router = new VueRouter({ routes:[ { path:'/account', component:account, children:[ {path:'login',component:login}, {path:'register',component:register} ] } ] }) var vm = new Vue({ el:'#app', data:{}, methods:{}, router:router })
|
使用命名视图实现经典布局
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| <style type="text/css"> html,body{ margin: 0; padding: 0 } h1{ margin: 0; padding: 0; font-size: 16px } .header{ height: 80px; background-color: orange } .container{ display: flex; height: 600px; } .left{ background-color: lightgreen; flex:2; } .main{ background-color: lightpink; flex: 8 }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| <div id="app"> <router-view></router-view> <div class="container"> <router-view name="left"></router-view> <router-view name="main"></router-view> </div> </div> <template id="header"> <div class="header"> 头部区域 </div> </template> <template id="leftBox"> <div class="left"> 左边区域 </div> </template> <template id="MainBox"> <div class="main"> 主区域 </div> </template>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| var header = { template:'#header' } var leftBox = { template:'#leftBox' } var MainBox = { template:'#MainBox' } var router = new VueRouter({ routes:[ { path:'/', components:{ 'default': header, 'left': leftBox, 'main': MainBox } } ] }) var vm = new Vue({ el:'#app', data:{ }, methods:{}, router:router })
|
效果链接
案例: keyup事件实现
方式1
1 2 3 4 5 6
| <div id="app"> <input type="text" name="" v-model="firstname" @keyup="getFullName">+ <input type="text" v-model="lastname" name="" @keyup="getFullName"> <input type="text" v-model="fullname" name=""> </div>
|
1 2 3 4 5 6 7 8 9 10 11 12 13
| var vm = new Vue({ el:'#app', data:{ firstname:'', lastname:'', fullname:'' }, methods:{ getFullName:function(){ this.fullname = this.firstname+'-'+ this.lastname } }, })
|
效果
方式2
1 2 3 4 5 6
| <div id="app"> <input type="text" name="" v-model="firstname">+ <input type="text" v-model="lastname" name=""> <input type="text" v-model="fullname" name=""> </div>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| var vm = new Vue({ el:'#app', data:{ firstname:'', lastname:'', fullname:'' }, methods:{ }, watch:{ 'firstname':function(newVal,oldValue){ this.fullname = newVal + '-' + this.lastname }, 'lastname':function(newVal){ this.fullname = this.firstname + '-' + newVal } } })
|
方式3
1 2 3 4 5 6
| <div id="app"> <input type="text" name="" v-model="firstname">+ <input type="text" v-model="lastname" name=""> <input type="text" v-model="fullname" name="" readonly> </div>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| var vm = new Vue({ el:'#app', data:{ firstname:'', lastname:'', }, methods:{ }, computed:{ 'fullname': function(){ return this.firstname + '-' + this.lastname } } })
|
通过 watch 监听路由变化
代码
1 2 3 4 5 6 7 8
| <div id="app"> <router-link to="/login">登录</router-link> <router-link to="/register">注册</router-link>
<router-view></router-view> </div>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| const login = { template:'<h4>这是登录组件,这个组件是爸爸我开发的</h4>' } const register = { template:'<h4>这是注册组件,这个组件是某某开发的</h4>' } const router = new VueRouter({ routes:[ {path:'/',component:login}, {path:'/login',component: login}, {path:'/register',component: register} ] }) var vm = new Vue({ el:'#app', data:{
}, methods:{}, router:router, watch:{ '$route.path':function(newVal,oldVal){ if (newVal==="/login") { alert('欢迎进入登录页面^-^') }else if(newVal === '/register'){ alert('欢迎进入注册页面^-^') } } } })
|
总结
computed
属性的结果会缓存,除非以来的响应式属性发生变化才会重新计算算,主要当作属性来用
method
方法表示一个具体的操作,主要书写业务逻辑
watch
一个对象,就是需要观察的表达式,主要用来监听某些特定数据的变化,,从而进行某些逻辑操作,可以视为 computed
+ method