Day27 SPA路由实现以及SASS讲解
路由
前端路由
根据对应的路由地址渲染不同的内容
前端的分类
页面路由(跳转页面一定会刷新)
- 根据对应的地址访问不同的页面(location.href location.assign location.replace)
hash路由(不会刷新页面)
- 根据对应的hash地址来渲染不同的内容(onhashchange)
- location.hash来获取对应的hash值 通过onhashchange进行监听
history路由(不会刷新)
- 根据对应的history页面地址来渲染不同的内容(onpopstate)
- 通过replaceState和pushState来改变state的值和页面的地址
- 通过history.back history.go history.forward来触发对应的onpopstate事件
后端路由
根据对应的路由地址访问对应的接口
SPA
单页应用程序(single page application)
整个应用只有一个页面 ,对应的页面调整就没有意义了
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./hash.js"></script>
</head>
<body>
<div id="app">
<router-link to="/">去首页</router-link>
<router-link to="/user">去用户页</router-link>
<router-view></router-view>
</div>
</body>
</html>
<script>
let home = {
template: '<div>首页</div>'
}
let user = {
template: '<div>用户页</div>'
}
let router = new VueRouter({
routes: [{
name: 'home',
path: '/',
component: home
}, {
name: 'user',
path: '/user',
component: user
}]
})
new Vue({
el: '#app',
router
})
</script>
hash模式路由实现
class VueRouter {
constructor(option) {
//获取传入的配置
this.routes = option['routes']
}
//监听hash改变事件 渲染需要渲染的元素
obServer(element) {
this.el = element
window.onhashchange = () => {
this.render()
}
}
//渲染
render() {
let _this = this
//获取当前的hash值 去除#
let hash = location.hash.slice(1)
this.routes.forEach(route => {
if (hash == route.path) {
//谁调用this就指向谁
_this.el.querySelector('router-view').innerHTML = route.component.template
}
})
}
//a标签的变化(使link标签变成a标签)
handlerLink() {
let _this = this
//获取所有的router-link
let linkList = this.el.querySelectorAll('router-link')
//遍历所有的link,找到对应的to属性
Array.from(linkList).forEach(link => {
let path = link.getAttribute('to') //找到to属性对应的属性值
//创建a标签
let a = document.createElement('a')
a.href = '#' + path
a.innerHTML = link.innerHTML
//将link替换成a标签
_this.el.replaceChild(a, link)
})
}
//页面加载完成自动加一个#
handlerLoad() {
window.onload = () => {
location.hash = '/'
}
}
}
class Vue {
constructor(option) {
this.el = document.querySelector(option.el)
this.router = option.router
this.router.obServer(this.el)
this.router.render()
this.router.handlerLink()
}
}
history实现
class VueRouter {
constructor(option) {
//获取路由的配置
this.routes = option.routes
}
obServer(element) {
//需要挂载的el对象
this.el = element
window.onpopstate = () => {
//监听onpopstate事件
//根据读取的path内容匹配渲染不同的内容
this.render(location.pathname)
}
}
render(path) {
let _this = this
//匹配
this.routes.forEach(route => {
if (path == route.path) {
//判断路径地址是否相等
let view = _this.el.querySelector('router-view')
//替换页面的内容
view.innerHTML = route.component.template
}
})
}
handlerLoad() {
//页面加载就触发
window.onload = () => {
history.replaceState('', '', './')
//第一次渲染
this.render('/')
}
}
handlerLink() {
let _this = this
let list = []
let linkList = this.el.querySelectorAll('router-link')
//替换所有的link标签
Array.from(linkList).forEach(link => {
let path = link.getAttribute('to')
let a = document.createElement('a')
//将path的值赋值给a要跳转的地址
a.href = path
a.innerHTML = link.innerHTML
_this.el.replaceChild(a, link)
list.push(a)
})
list.forEach(a => {
//给a标签添加点击事件
a.addEventListener('click', function(e) {
e = e || window.event
//阻止a的默认行为
e.preventDefault()
//历史页面推进一个新的节点
history.pushState('', '', a.href)
_this.render(location.pathname)
})
})
}
}
class Vue {
constructor(option) {
this.el = document.querySelector(option.el)
this.router = option.router
//监听当前传入的el元素
this.router.obServer(this.el)
this.router.handlerLoad()
this.router.handlerLink()
}
}
SASS
概述
sass是一个预编译的css,核心还是css,最终还是会编译成css,sass的好处在于他可以以js的方法书写css(有跟js原生一样的语法).跟他同类的预编译的css还有less以及stylus等.sass它是使用ruby语言书写的,后续使用Python所以,sass要具备Python环境
使用方式
使用node来进行sass的编译
npm i sass -D
sass sass文件名 文件名(css文件名)