/**
* 编译模板:
* 1.模板不是HTML,有指令、插值、JS表达式,能实现判断、循环
* 2.HTML是标签语言,只有js才能实现判断、循环
* 3.因此,模板一定是转换为某种JS代码,即编译模板
* 4.vue-template-compiler是编译vue模板的包
*
* 初次渲染过程:
* 1.解析模板为render函数(或在开发环境已完成,vue-loader)
* 2.触发响应式,监听data属性getter、setter
* 3.执行render函数,生成VNode,patch(elem,vnode)
*
* 更新过程:
* 1.修改data,触发setter(此前在getter中已被监听)
* 2.重新执行render函数,生成newVnode
* 3.patch(vnode,newVnode)
*
* 异步渲染:
* 1.$nextTick
* 2.汇总data的修改,一次性更新视图
* 3.减少DOM操作次数,提高性能
*
* hash的特点:
* 1.hash变化会触发网页跳转,即浏览器的前进、后退
* 2.hash变化不会刷新页面,SPA必需的特点
* 3.hash永远不会提交到serve端(前端自生自灭)
*
* H5 history:
* 1.用URL规范的路由,但跳转时不刷新页面
* 2.history.pushState
* 3.window.onpopstate
* 4.需要后端支持,可参考:https://router.vuejs.org/zh/guide/essentials/history-mode.html
*/
/**
* Vue原理-总结
* 1.组件化:组件化的历史;数据驱动视图;MVVM
* 2.响应式:Object.defineProperty;监听对象(深度);监听数组;Object.definerProperty的缺点(Vue3用Proxy)
* 3.vdom和diff:应用背景;VNode结构(JS模拟DOM);snabbdom使用:vnode h patch
* 4.模板编译:with语法;模板编译为render函数;执行render函数生成vnode
* 5.渲染过程:初次渲染过程;更新过程;异步渲染
* 6.前端路由:hash;H5 history;两者对比
*
*/
// hash变化,包括:JS修改url,手动修改URL的hash;浏览器前进/后退
window.onhashchange = (event) => {
console.log('oldUrl = ', event.oldURL)
console.log('newUrl = ', event.newURL)
console.log('hash', location.hash)
}
// 页面初次加载,获取hash
document.addEventListener('DOMContentLoaded', () => {
console.log('hash', location.hash)
})
// JS修改url
document.getElementById('btn1').addEventListener('click', () => {
location.href = "#/user"
})
// H5 history
// 页面初次加载,获取path
document.addEventListener('DOMContentLoaded', () => {
console.log('load', location.pathname)
})
// 打开一个新的路由
// 注意:用pushState方式,浏览器不会刷新页面
document.getElementById('btn1').addEventListener('click', () => {
const state = { name: 'page1' }
console.log('切换路由到', 'page1')
history.pushState(state, '', 'page1')
})
// 监听浏览器前进、后退
window.onpopstate = (event) => {
console.log('onpopstate', event.state, location.pathname)
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Observe demo</title>
</head>
<body>
<button id="btn1">修改url</button>
</body>
</html>