vue
1. router总结
1) 最简单路由应用
定义路由
const routes = [
{ path: '/index', component: index },
{ path: '/hello', component: hello },
]
创建 router 实例,然后传 routes 配置
const router = new VueRouter({
routes
})
创建和挂载根实例。通过 router 配置参数注入路由,从而让整个应用都有路由功能
const app = new Vue({
router,
render: h => h(App)
}).$mount('#app')
经过上面的配置之后呢,路由匹配到的组件将会渲染到App.vue里的<router-view></router-view>
那么这个App.vue里应该这样写:
<template>
<div id="app">
<router-view></router-view>
</div>
</template>
index.html里呢要这样写:
<body>
<div id="app"></div>
</body>
这样就会把渲染出来的页面挂载到这个id为app的div里了。
2) 在ES5中使用,需要先创建路由器实例,随后传入配置参数即可,如:
var router = new VueRouter();
router.map({
'/view-a': {
component: ViewA
},
'/view-b': {
component: ViewB
}
});
router.start(App, '#app');
以上定义的路由器规则,采用映射到一个组件的方式,最后启动应用的时候,挂载到#app的元素上。
3) 每个组件都有一个route选项,route选项有一系列钩子函数,在切换路由时会执行这些钩子函数。
其中一个钩子函数是data钩子函数,它用于加载和设置组件的数据
var Home = Vue.extend({
template: '#home',
data: function() {
return {
msg: 'Hello, vue router!',
currentPath: ''
}
},
route: {
data: function(transition){
transition.next({
currentPath: transition.to.path
})
}
}
})
4) 流程举例:
现在我们以一个简单的单页面应用开启vue-router之旅,这个单页面应用有两个路径:/home和/about,与这两个路径对应的是两个组件Home和About。
<1>. 创建组件
首先引入vue.js和vue-router.js:
<script src="js/vue.js"></script>
<script src="js/vue-router.js"></script>
然后创建两个组件构造器Home和About:
var Home = Vue.extend({
template: '<div><h1>Home</h1><p>{{msg}}</p></div>',
data: function() {
return {
msg: 'Hello, vue router!'
}
}
})
var About = Vue.extend({
template: '<div><h1>About</h1><p>This is the tutorial about vue-router.</p></div>'
})
<2>. 创建Router
var router = new VueRouter()
调用构造器VueRouter,创建一个路由器实例router。
<3>. 映射路由
router.map({
'/home': { component: Home },
'/about': { component: About }
})
调用router的map方法映射路由,每条路由以key-value的形式存在,key是路径,value是组件。
例如:'/home'是一条路由的key,它表示路径;{component: Home}则表示该条路由映射的组件。
<4>. 使用v-link指令
<div class="list-group">
<a class="list-group-item" v-link="{ path: '/home'}">Home</a>
<a class="list-group-item" v-link="{ path: '/about'}">About</a>
</div>
在a元素上使用v-link指令跳转到指定路径。
<5>. 使用<router-view>标签
<router-view></router-view>
在页面上使用<router-view></router-view>标签,它用于渲染匹配的组件
<6>. 启动路由
var App = Vue.extend({})
router.start(App, '#app')
路由器的运行需要一个根组件,router.start(App, '#app') 表示router会创建一个App实例,并且挂载到#app元素。
注意:使用vue-router的应用,不需要显式地创建Vue实例,而是调用start方法将根组件挂载到某个元素。
5). 创建一个单页面应用的基本步骤:
JavaScript
创建组件:创建单页面应用需要渲染的组件
创建路由:创建VueRouter实例
映射路由:调用VueRouter实例的map方法
启动路由:调用VueRouter实例的start方法
HTML
使用v-link指令
使用<router-view>标签
router.redirect
应用在首次运行时右侧是一片空白,应用通常都会有一个首页,例如:Home页。
使用router.redirect方法将根路径重定向到/home路径:
router.redirect({
'/': '/home'
})
router.redirect方法用于为路由器定义全局的重定向规则,全局的重定向会在匹配当前路径之前执行。
执行过程
当用户点击v-link指令元素时,我们可以大致猜想一下这中间发生了什么事情:
vue-router首先会去查找v-link指令的路由映射
然后根据路由映射找到匹配的组件
最后将组件渲染到<router-view>标签
6). 嵌套路由
路由映射:
router.map({
'/home': {
component: Home,
// 定义子路由
subRoutes: {
'/news': {
component: News
},
'/message': {
component: Message
}
}
},
'/about': {
component: About
}
})
在/home路由下定义了一个subRoutes选项,/news和/message是两条子路由,它们分别表示路径/home/news和/home/message,这两条路由分别映射组件News和Message
7). 具名路由
router.map({
'/home': {
component: Home,
subRoutes: {
'/news': {
name: 'news',
component: News,
subRoutes: {
'detail/:id': {
name: 'detail',
component: NewsDetail
}
}
},
'/message': {
component: Message
}
}
},
'/about': {
component: About
}
})
注意:我们在定义/homes/news/和home/news/detail/:id路由时,给该路由指定了name属性。
/:id 是路由参数,例如:如果要查看id = '01'的News详情,那么访问路径是/home/news/detail/01。
Home组件和News组件模板:
<template id="home">
<div>
<h1>Home</h1>
<p>{{msg}}</p>
</div>
<div>
<ul class="nav nav-tabs">
<li>
<a v-link="{ name: 'news'}">News</a>
</li>
<li>
<a v-link="{ path: '/home/message'}">Messages</a>
</li>
</ul>
<router-view></router-view>
</div>
</template>
<template id="news">
<div>
<ul>
<li>
<a v-link="{ name: 'detail', params: {id: '01'} }">News 01</a>
</li>
<li>
<a v-link="{ path: '/home/news/detail/02'}">News 02</a>
</li>
<li>
<a v-link="{ path: '/home/news/detail/03'}">News 03</a>
</li>
</ul>
<div>
<router-view></router-view>
</div>
</div>
</template>
<a v-link="{ name: 'news'}">News</a>和<a v-link="{ name: 'detail', params: {id: '01'} }">News 01</a>这两行HTML代码,使用了用了具名路径。
8). 钩子函数
每个组件都有一个route选项,route选项有一系列钩子函数,在切换路由时会执行这些钩子函数。
其中一个钩子函数是data钩子函数,它用于加载和设置组件的数据。
举例:
var Home = Vue.extend({
template: '#home',
data: function() {
return {
msg: 'Hello, vue router!',
currentPath: ''
}
},
route: {
data: function(transition){
transition.next({
currentPath: transition.to.path
})
}
}
})
组件的钩子函数一共6个:
data: 可以设置组件的data
activate:激活组件
deactivate:禁用组件
canActivate:组件是否可以被激活
canDeactivate:组件是否可以被禁用
canReuse:组件是否可以被重用
data 它是个路由切换的时候的一个生命周期函数。它获取一个 transition 对象作为参数,这个特点是组件的 ready 阶段所不具有的。
当路径包含动态片段的时候,有时候需要根据这个动态的值来决定渲染的结果,比如说:
// router.js
// 根据 username 的不同,渲染不同用户的主页
router.map({
'/user/:username': UserView
}
})
// UserView.vue
route: {
data (transition) {
let username = transition.to.params.username
// ...
}
}
这种情况必须要在 route 的生命周期函数里面来处理。
route的data可以用于获取路由参数,通过这些参数发送请求,取得数据,可以实现“组件刚载进来就已经拿到数据并完成渲染”
data 切换钩子会在 activate 被断定( resolved )以及界面切换之前被调用。切换进来的组件会得到一个名为 $loadingRouteData 的元属性,其初始值为 false ,在 data 钩子函数被断定后会被赋值为 true 。这个属性可用来会切换进来的组件展示加载效果。
data 钩子和 activate 钩子的不同之处在于:
a.
data在每次路由变动时都会被调用,即使是当前组件可以被重用的时候,但是 activate 尽在组件是新创建时才会被调用。
假设我们有一个组件对应于路由 /message/:id ,当前用户所处的路径是 /message/1 。当用户浏览 /message/2 时,当前组件可以被重用,所以 activate 不会被调用。但是我们需要根据新的 id 参数去获取和更新数据,所以大部分情况下,在 data 中获取数据比在 activate 中更加合理。
b.
activate 的作用是控制切换到新组件的时机。data 切换钩子会在 activate 被断定( resolved )以及界面切换之前被调用,所以数据获取和新组件的切入动画是并行进行的,而且在 data 被断定( resolved )之前,组件会处在“加载”状态。
从用户体验的角度来看一下两者的区别:
如果我们等到获取到数据之后再显示新组件,用户会感觉在切换前界面被卡住了。
相反的话(指不用等到获取数据后再显示组件),我们立刻响应用户的操作,切换视图,展示新组件的“加载”状态。如果我们在 CSS 中定义好相应的效果,这正好可以用来掩饰数据加载的时间。
9). router.map(routeMap)
路由配置对象包含两个字段:
component:
当路径匹配时,会渲染到顶级 <router-view> 的 Vue 组件。此字段的值可以是调用 Vue.extend 后返回的构造函数,或者普通的组件选项对象。在后一种情况下,路由会隐式调用 Vue.extend 。
subRoutes:
嵌套的子路由映射。对于每一个 subRoutes 映射中的子路由对象,路由器在做匹配时会使用其路径拼接到父级路径后得到的全路径。成功匹配的组件会渲染到父级组件的 <router-view> 中。
10).router.start(App, el)
启动一个启用了路由的应用。创建一个 App 的实例并且挂载到元素 el 。
App: 可以是 Vue 组件构造函数或者一个组件选项对象。如果是一个对象,路由会隐式的对其调用 Vue.extend 。这个组件会用来创建这个应用的根组件。
el: 挂载应用的元素。可以是 CSS 选择符或者一个实际的元素。
11).router.redirect(redirectMap)
为路由器定义全局的重定向规则。
全局的重定向会在匹配当前路径之前执行。
如果发现需要进行重定向,原本访问的路径会被直接忽略而且不会在浏览器历史中留下记录。
参数
redirectMap: Object
重定向映射对象的格式应该为 { fromPath: toPath, ... } 。路径中可以包含动态片段。
举例:
router.redirect({
// 重定向 /a 到 /b
'/a': '/b',
// 重定向可以包含动态片段
// 而且重定向片段必须匹配
'/user/:userId': '/profile/:userId',
// 重定向任意未匹配路径到 /home
'*': '/home'
})
- <template>标签
<template></template>
- MVVM
以“ViewMMVVM的本质是通过数据绑定链接View和Model,让数据的变化自动映射为视图的更新。Vue.js在数据绑定的API设计上借鉴了Angular的指令机制:用户可以通过具有特殊前缀的HTML属性来实现数据绑定,也可以使用常见的花括号模板插值,或是在表单元素上使用双向绑定:
<!-- 指令 -->
<span v-text="msg"></span>
<!-- 插值 -->
<span>{{msg}}</span>
<!-- 双向绑定 -->
<input v-model="msg">
插值本质上也是指令,只是为了方便模板的书写。在模板的编译过程中,Vue.js会为每一处需要动态更新的DOM节点创建一个指令对象。每当一个指令对象观测的数据变化时,它便会对所绑定的目标节点执行相应的DOM操作。基于指令的数据绑定使得具体的DOM操作都被合理地封装在指令定义中,业务代码只需要涉及模板和对数据状态的操作即可,这使得应用的开发效率和可维护性都大大提升。odel 实例”为基本单位:
举例:
<!-- 模板 -->
<div id="app">
{{msg}}
</div>
// 原生对象即数据
var data = {
msg: 'hello!'
}
// 创建一个 ViewModel 实例
var vm = new Vue({
// 选择目标元素
el: '#app',
// 提供初始数据
data: data
})
渲染结果:
div id="app">
hello!
</div>