vue-router的详解及简单原理实现 与vuex简单原理实现

1基础用法

main.js

import Vue from 'vue'
import App from './App.vue'
import router from './router'

Vue.config.productionTip = false

new Vue({
  router,
  render: h => h(App),
}).$mount('#app')

router/index.js
里面注释的部分 包含路由独享守卫 与路由全局守卫

import Vue from 'vue'
import Router from 'vue-router'
import List from '@/components/list.vue';
import About from '@/components/about.vue';
import Detail from '@/components/detail.vue';
import Login from '@/components/login.vue';
import HelloWorld from '@/components/HelloWorld.vue';
Vue.use(Router)
let router = new Router({
    mode:"history",
    base:process.env.BASE_URL,
    routes:[
        {
            path: '/',
            name: 'HelloWorld',
            component: HelloWorld,
            children:[{
              path: '',
               name: 'List',
               component: List,
            },
            {path:'/detail/:id',
            name:Detail,
            component:Detail
          }
           
          ]
          },
          {
            path: '/about',
            name: 'About',
            // beforeEnter:(to,from,next) => {//路由独享守卫
            //     //     //判断是否登陆
            //     if(!window.isLogin){//如果去about页  并且没登陆  那么就去登陆页
            //         next('/login?redirect='+to.path)
            //     }else{
            //         next()
            //     }
            // },
            component: About,
            },
            {
              path: '/login',
            name: 'Login',
            component: Login,
            }
    ]
})
//每次路由激活前都会执行回调函数
// router.beforeEach((to,form,next)=>{   //全局的守卫
//     //判断是否登陆
//     if(to.path ==='/about'&&!window.isLogin){//如果去about页  并且没登陆  那么就去登陆页
//         next('/login?redirect='+to.path)
//     }else{
//         next()
//     }
// })
export default router

about.vue
组件守卫






login.vue






list.vue






HelloWorld.vue






app.vue







.
.
.

原理

app.vue








login.vue







home.vue






about.vue







store.js

/*
 * @Description: 
 * @Autor: wangDuJuan
 * @Date: 2020-08-08 18:07:01
 */
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)
export default new Vuex.Store({
    state:{
        isLogin:false
    },
    mutations:{
        login(state){
            state.isLogin = true
        }
    },
    getters:{
        getLogin(state){
            return state.isLogin ? '欢迎回来':'游客'
        }
    },
    actions:{
        requestLogin(context,prop){
            //context函数的上下文  prop 传过来的参数
            console.log(context,prop)
            return new Promise((resolve)=>{
                setTimeout(()=>{
                    resolve(true)
                    context.commit('login')
                },1000)
                
            })
           
        }
    }
})

router.js

/*
 * @Description: 
 * @Autor: wangDuJuan
 * @Date: 2020-08-08 14:31:45
 */
import Vue from 'vue'
import Router from 'vue-router'
import List from '@/components/list.vue';
import About from '@/components/about.vue';
import Detail from '@/components/detail.vue';
import Login from '@/components/login.vue';
import HelloWorld from '@/components/HelloWorld.vue';
import store from './store.js'
Vue.use(Router)
let router = new Router({
    mode:"history",
    base:process.env.BASE_URL,
    routes:[
        {
            path: '/',
            name: 'HelloWorld',
            component: HelloWorld,
            children:[{
              path: '',
               name: 'List',
               component: List,
            },
            {path:'/detail/:id',
            name:Detail,
            component:Detail
          }
           
          ]
          },
          {
            path: '/about',
            name: 'About',
            // beforeEnter:(to,from,next) => {//路由独享守卫
            //     //     //判断是否登陆
            //     if(!window.isLogin){//如果去about页  并且没登陆  那么就去登陆页
            //         next('/login?redirect='+to.path)
            //     }else{
            //         next()
            //     }
            // },
            component: About,
            },
            {
              path: '/login',
            name: 'Login',
            component: Login,
            }
    ]
})
//每次路由激活前都会执行回调函数
router.beforeEach((to,form,next)=>{   //全局的守卫
    //判断是否登陆
    if(to.path ==='/about'&&!store.state.isLogin){//如果去about页  并且没登陆  那么就去登陆页
        next('/login?redirect='+to.path)
        
    }else{
        next()
    }
})
export default router

Yrouter.js

/*
 * @Description: 
 * @Autor: wangDuJuan
 * @Date: 2020-08-09 16:24:02
 */
class VueRouter{
    constructor(Vue,options){
        this.$option = options
        this.routeMap = {}
        this.app = new Vue({
            data:{
                current:'#/'
            }
        })
        this.init()
        this.initCreateRouterMap(options)
        this.initComponent(Vue)
    }
    init(){
        window.addEventListener('load',this.onHashchange,false)
        window.addEventListener('hashchange',this.onHashchange,false)
    }
    getHash(){
        return window.location.hash.splice(1)||'/'
    }
    onHashchange(){
        this.app.current = this.getHash()
    }
    initCreateRouterMap(options){
        options.routers.forEach(item=>{
           this.routeMap[item.path] = item.component
        })
    }
    initComponent(Vue){
//         props可以使用实例中的变量赋值
// 全局组件可以获取用使用prop 的做操作 ,指定类型
        Vue.component('router-link',{
          prop:{
            to:String
          },
//           用来访问被 slot 分发的内容。每个具名 slot 有其相应的属性
// (例如:slot="foo" 中的内容将会在 vm.$slots.foo 中被找到)
// default 属性包括了所有没有被包含在具名 slot 中的节点。
          render:function(h){
            return h(
                "a",
                {attr:{href:this.to}},
                this.$slots.default
            )
          }
        })
        let _this = this
        Vue.component('route-view',{
            render(h){
                let component = _this.routeMap[_this.app.current]
                h(component)
            }
        })
    }
}

Ystore.js

/*
 * @Description: 
 * @Autor: wangDuJuan
 * @Date: 2020-08-09 15:24:40
 */
import Vue from 'vue'
class Ystore{
    constructor(options){
        this.state = options.state
        this.mutations = options.mutations
        this.actions = options.actions
        // 借助Vue本身的数据响应机制
        new Vue({
            data:{
                state:this.state
            }
        })
    }
    commit(type,payload){
        let mutation = this.mutations[type]
        mutation(this.state,payload)
    }
    dispatch(type,payLoad){
        let action = this.actions[type]
        // createClass  创建类的函数里面中es5的写法默认是绑定了bind方法,而es6中 新增加了class,绑定的方法需要绑定this,如果是箭头函数就不需要绑定this,用箭头的方式
        let atx= {
            state:this.state.bind(this),
            mutations:this.mutations,
            dispatch:this.dispatch.bind(this)
        }
        return action(atx,payLoad)
    }
}
export default new Ystore({
    state:{
        count:1
    },
    mutations:{
        add(state){
            state.count++
        }
    }
})

vue.config.js(mock数据)

/*
 * @Author: yang
 * @Date: 2020-08-07 11:36:56
 * @LastEditors: Please set LastEditors
 * @LastEditTime: 2020-08-08 19:03:45
 * @FilePath: \testproject\vue.config.js
 */
// node代码
module.exports = {
    publicPath:'/cart',
    lintOnSave: false,
    configureWebpack:{//webpack的配置项 webpack开发服务器
        devServer:{//mock数据  服务器的代理 都可以在这里配置
            before(app){ //在服务器启动之前的钩子函数,在这里可以对服务器的实例做一些提前的操作
                //app 是express的实例
                app.get('/goods',(req,res)=>{
                    res.json([{
                        id:1,text:'kk'
                    },{id:2,text:'lll'}
                ])
                })
            }
        }
    }
}

你可能感兴趣的:(vue-router的详解及简单原理实现 与vuex简单原理实现)