先看流程图
按照 步骤 我们先创建一个基础的 vue 框架
创建项目
vue create app
安装依赖
npm i
添加路由
npm i vue-router
vue add router
运行项目
npm run serve
赋值 rule 更改名字
**创建router.js 来编写 router组件 ** 把 VueRouter 组件引用改为我们自己的 js目录
创建组件
let vue;
class VueRouter{
constructor(options){
}
}
VueRouter.install = function(_vue){
}
export default VueRouter;
options 对应的值是
install 注册组件 组件是通过 use 挂载在vue上 可以引用下 vue
这时候就可以运行项目 看下对应的log
这时候会报错router-link 和 route-view不存在
在install 里通过 引用的 vue 创建 component
`
VueRouter.install = function(_Vue) {
Vue = _Vue;
Vue.component("router-link", {
render(h) {
return h('a',{},'')
},
});
Vue.component("router-view", {
render(h) {
return h('div',{},1111)
},
});
};
接下来把router-link看成a标签带有herf属性 属性值是组件的to属性值 对应的内容是 组件插槽的值
vue.component("router-link",{
props:{
to:String,
request:true
},
render(h){
return h("a",{
attrs:{
href:"#"+this.to
}
},this.$slots.default)
}
})
接下来 要监听 rul hash 的变化 同时用个响应式对象来 保存它
constructor(options){
this.$options = options;
console.log(window.location.hash.slice(1));
const hashInit = window.location.hash.slice(1) || '/';
//创建一个响应式对象
vue.util.defineReactive(this,'hashInit',hashInit);
window.addEventListener('hashchange',this.hashChange.bind(this));
window.addEventListener('load',this.hashChange.bind(this))
}
hashChange(){
this.hashInit = window.location.hash.slice(1);
console.log(this.hashInit)
}
创建响应式对应 有多重方法
方法一
new vue({
data(){
return {
创建
}
}
})
方法二
vue.util.defineReactive(this, target,value)
应为我们在使用路由时是先 use引用 后才创建vue实例
所有我们需要通过mixin在vue初始化时候把接收的options.router 挂载到vue上
//挂载在vue 初始化实例
vue.mixin({
beforeCreate(){
if(this.$options.router){
vue.prototype.$router = this.$options.router;
}
}
})
接下来就是router-view展示对应路由的 template
我们已经通过options获取到对应路由的component 同时也通过响应式对象保存了hash最新值
只需要把 options 里对应等于 hash 值的component 取出来 渲染就可以了
vue.component("router-view",{
render(h){
let component = null
//判断时候有对应hash 的路由
const route = this.$router.$options.routes.find(
(router)=>{
return router.path === this.$router.hashInit;
}
);
//有就把component取出来
if (route) {
component = route.component
}
//渲染
return h(component)
}
})
完整代码
let vue;
// import Home from '../views/Home.vue'
class VueRouter{
constructor(options){
this.$options = options;
console.log(window.location.hash.slice(1));
const hashInit = window.location.hash.slice(1) || '/';
//创建一个响应式对象
vue.util.defineReactive(this,'hashInit',hashInit);
window.addEventListener('hashchange',this.hashChange.bind(this));
window.addEventListener('load',this.hashChange.bind(this))
}
hashChange(){
this.hashInit = window.location.hash.slice(1);
console.log(this.hashInit)
}
}
VueRouter.install = function(_vue){
vue = _vue;
//挂载在vue 初始化实例
vue.mixin({
beforeCreate(){
if(this.$options.router){
vue.prototype.$router = this.$options.router;
}
}
})
vue.component("router-link",{
props:{
to:String,
request:true
},
render(h){
return h("a",{
attrs:{
href:"#"+this.to
}
},this.$slots.default)
}
})
vue.component("router-view",{
render(h){
let component = null
const route = this.$router.$options.routes.find(
(router)=>{
return router.path === this.$router.hashInit;
}
);
if (route) {
component = route.component
}
return h(component)
}
})
}
export default VueRouter;