就是只有一个 web 页面的应用,
是加载单个 HTML 页面,
并在用户与应用程序交互时, 动态更新该页面的 web 应用程序css
区别html
只有第一次会加载页面,
之后的每次请求,
仅仅是获取必要的数据.而后,
由页面中 js 解析获取的数据,
展现在页面中前端
单页面优点 :vue
单页面劣势 :node
路由 : 是浏览器 URL 中的哈希值( # hash) 与 展现视图内容 之间的对应规则ios
#
hash) 发生改变后,路由会根据制定好的规则, 展现对应的视图内容为何要学习路由?web
npm i vue-router
<script src="./vue.js"></script> // 千万注意 :引入路由必定要在引入vue以后,由于vue-router是基于vue工做的 <script src="./node_modules/vue-router/dist/vue-router.js"></script>
实例路由对象 + 挂载到vue上vue-router
const router = new VueRouter()
new Vue({ router,data,methods })
#/
# 1. 入口 // 方式1 : url地址为入口 调试开发用 输入url地址 改变哈希值 `01-路由的基本使用.html#/one` // 方式2 : 声明式导航 : router-link+to (见下面介绍) # 2. 路由规则 // path : 路由路径 // component : 未来要展现的路由组件 routes: [ { path: '/one', component: One }, { path: '/two', component: Two } ] # 3. 组件 // 使用返回值的这个组件名称 const One = Vue.component('one', { template: ` <div> 子组件 one </div> ` }) # 4. 出口 <!-- 出口 组件要展现的地方--> <router-view></router-view> # 总结 拿到入口哈希路径, 根据路由匹配规则,找到对应的组件,显示到对应的出口位置
入口npm
<!-- router-link 组件最终渲染为 a标签, to属性转化为 a标签的href属性 to 属性的值 , 实际上就是哈希值,未来要参与路由规则中进行与组件匹配 --> <router-link to="/one">首页</router-link>
const One = { template: `<div> 子组件 one </div> ` }
<div id="app"> <!-- 1 路由入口:连接导航 --> <router-link to="/one">One</router-link> <router-link to="/two">Two</router-link> <!-- 4 路由出口:用来展现匹配路由视图内容 --> <router-view></router-view> </div> <!-- 导入 vue.js --> <script src="./vue.js"></script> <!-- 导入 路由文件 --> <script src="./node_modules/vue-router/dist/vue-router.js"></script> <script> // 3 建立两个组件 const One ={ template: '<h1>这是 one 组件</h1>' } const Two = { template: '<h1>这是 two 组件</h1>' } // 0 建立路由对象 const router = new VueRouter({ // 2. 路由规则 routes: [ { path: '/one', component: One }, { path: '/two', component: Two } ] }) const vm = new Vue({ el: '#app', //0. 不要忘记,将路由与vue实例关联到一块儿! router }) </script>
<a href="#/one" class="router-link-exact-active router-link-active">One</a> <a href="#/two" class="">Two</a>
.router-link-exact-active, .router-link-active { color: red; font-size: 50px; }
const router = new VueRouter({ routes: [], // 修改默认高亮的a标签的类名 // red 是已经存在过的 linkActiveClass: 'red' })
导入 : 列表三个手机都要点击进去详情页, 只须要一个组件,显示不一样的数据便可
# 入口 <router-link to="/detail/1">手机1</router-link> <router-link to="/detail/2">手机2</router-link> <router-link to="/detail/3">手机3</router-link> <router-link to="/detail">手机4</router-link> 没有参数如何???? # 规则 routes: [ // 2 . 路由规则 { path: '/detail/:id?', component: Detail } ] # 获取参数的三种方式 const Detail = { template: ` // 方式1 : 组件中直接读取 <div> 显示详情页内容....{{ $route.params.id }} </div> `, created() { // 方式2 : js直接读取 // 打印只会打印一次,由于组件是复用的,每次进来钩子函数只会执行一次 console.log(this.$route.params.id) }, // 方式3 : 监听路由的参数,为何不须要深度监听,由于一个路径变化,就会对应一个对新的路由对象(地址变) watch: { $route(to, from) { console.log(to.params.id) } } }
$route.path编程
string
"/foo/bar"
。# 后面?前面的内容
$route.params
Object
$route.query
Object
/foo?user=1
,则有 $route.query.user == 1
,若是没有查询参数,则是个空对象。$route.hash
string
当前路由的 hash 值 (带 #
) ,若是没有 hash 值,则为空字符串。
$route.fullPath
string
# 演示 : <router-link to="/detail/4?age=21#one">detail</router-link> { path: '/detail/:id?', component: detail } 在组件内 created打印 this.$route > fullPath: "/detail/4?id=001#one" > hash : "#one" > params : {id:'4'} > query : {age : 21} > path : '/detail/4'
导入 : url测试 parent 和child, 想让child 在 parent 中显示
<router-view> </router-view>
/child 和 child 的区别
/child
=> 那么访问就能够直接访问#/child
就能够访问 子组件child
=> 那么访问就应该访问#/parent/child
才能够访问子组件const parent = { template: `<p>parent <router-view> </router-view> </p>` } const child = { template: `<p>child</p>` } const router = new VueRouter({ routes: [ { path: '/parent', component: parent, children: [ { path: '/child', component: child } ] } ] })
routes
配置中给某个路由设置名称。 ==> 如何命名# 命名 routes: [ { path: '/parent', name: 'parent', component: parent } ] # 入口连接 + 跳转 (使用 path 和 name 的转换) <!-- 方式1 : url手动写 --> <!-- 方式2 : 入口连接 声明式导航 --> <router-link to="/parent">点击</router-link> <router-link :to="{ name : 'parent' }">点击</router-link> # 忘了 带 : 原始对象类型 <!-- 方式3 : 编程式导航 --> fn() { // this.$router.push('/parent') this.$router.push({ name: 'parent' }) }
导入 : 有时候想同时 (同级) 展现多个视图,需求 : 访问 / 根目录 同时展现如下三个组件
const header = { template: `<p>header </p>` } const main = { template: `<p>main </p>` } const footer = { template: `<p>footer </p>` }
# 之前的那个方式只能显示三个 header # 演示以前的效果 routes: [ { path: '/', components: { default: header, m: main, f: footer } } ]
<router-view> </router-view> <router-view name="m"> </router-view> <router-view name="f"> </router-view>
redirect: '/header' redirect: { name: 'header' } redirect: to => { // console.log(to) return { name: 'about' } }
# 入口 <router-link to="/header/3">123</router-link> # 规则 routes: [ { path: '/header/:id', component: header, } ] # 获取参数 const header = { template: `<p>header {{ $route.params.id }} </p>` }
# 入口 <router-link to="/header/3">123</router-link> # 规则 routes: [ { path: '/header/:id', component: header, // 若是 props 被设置为 true,route.params 将会被设置为组件属性 props: true } ] # 获取参数 const header = { // 参数 id 当成参数 props: ['id'], template: `<p>header {{ id }} </p>` }
# 入口 <router-link to="/header">123</router-link> # 规则 routes: [ { path: '/header', component: header, props: { foo: '0000' } } ] # 组件 const header = { props: ['foo'], template: `<p>header {{ foo }} </p>` }
# 同对象模式同样 # 区别是props值不同 props: to => { return { foo: '0000' } }
实际生活中的应用界面,一般由多层嵌套的组件组合而成。一样地,URL 中各段动态路径也按某种结构对应嵌套的各层组件。
借助 vue-router
,使用嵌套路由配置,就能够很简单地表达这种关系。
<div id="app"> <router-view></router-view> </div>
const User = { template: '<div>User {{ $route.params.id }}</div>' } const router = new VueRouter({ routes: [ { path: '/user/:id', component: User } ] })
这里的 <router-view>
是最顶层的出口,渲染最高级路由匹配到的组件。一样地,一个被渲染组件一样能够包含本身的嵌套 <router-view>
。例如,在 User
组件的模板添加一个 <router-view>
嵌套路由
const User = { template: ` <div class="user"> <h2>User {{ $route.params.id }}</h2> <router-view></router-view> </div> ` }
VueRouter
的参数中使用 children
配置const router = new VueRouter({ routes: [ { path: '/user/:id', component: User, children: [ { // 当 /user/:id/profile 匹配成功, // UserProfile 会被渲染在 User 的 <router-view> 中 path: 'profile', component: UserProfile }, { // 当 /user/:id/posts 匹配成功 // UserPosts 会被渲染在 User 的 <router-view> 中 path: 'posts', component: UserPosts } ] } ] })
注意,以 /
开头的嵌套路径会被看成根路径。 这让你充分的使用嵌套组件而无须设置嵌套的路径。
routes: [ { path: '/header', component: header, meta: { title: 'XXXX' } } ]
created() { document.title = this.$route.meta.title }
在路由导航的时候,能够用做判断
const one = { template: ` <div> <button @click="handleClick('back')">返回 上一页</button> <button @click="handleClick('push')">跳转 two页</button> <button @click="handleClick('replace')">替换 two页</button> </div>`, methods: { handleClick(type) { if (type == 'back') { // 返回 this.$router.back() } else if (type == 'push') { // 跳转 有历史记录 this.$router.push('/two') } else { // 替换 没有历史记录 this.$router.replace('/two') } } } } const two = { template: `<p>two </p>` }
router.beforeEach((to, from, next) => { // 访问 login if (to.name == 'login') { // 下一步 next() } else { // 中止跳转 next(false) // 跳转到下一步 next({ name: 'login' }) 或者 使用路径 next('/login') } })