前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >手撸vuex和vue-router

手撸vuex和vue-router

作者头像
一粒小麦
发布2019-07-18 17:53:10
4890
发布2019-07-18 17:53:10
举报
文章被收录于专栏:一Li小麦一Li小麦

3. 手撸vuex源码

在手写之前应该想想:

vuex如何知道状态变化,并通知组件? 组件如何响应?...

接下来,就实现一个duex的状态管理器吧! 对应的store称为DStore

代码语言:javascript
复制
// written by Djtao
class DStore{
    constructor(options){
        //参数内定义了三大方法:
        this.state=options.state;
        this.mutations=options.mutations;
        this.actions=options.actions;
        //借用Vue的数据劫持功能
        this.vm=new Vue({
            data:{
                state:this.state
            }
        });
    }

借用了vue的劫持功能。与redux不同之处,在于vuex与vue强耦合。

commit和actions可根据type拿到函数方法: 不同点在于:

  • commit提交了,就让修改state的方法这么发生了。不返回任何值。
  • dispatch主要是在将来或某个时段(比如请求后)派发修改状态事件,所以必须有返回值。并且需要
代码语言:javascript
复制
    //提交,触发
    commit(type,payload){
        //通过`type`拿到函数
        const mutations=this.mutations[type];
        // 执行这个函数!第一个参数为state,第二个是自定义参数payload
        mutations(this.state.payload);
    }

    //派发事件
    dispatch(type,payload){
        const actions=this.actions[type];
        const ctx={
            commit:this.commit,
            state:this.state,
            dispatch:this.dispatch
        }
        // 把这个函数的运行结果返回出去!
        return actions(ctx,payload);
    }

把这个store返回出去,那就写完了,核心原理可以说是异常简单。 就用官方文档的案例验证下这个duex有多靠谱:

代码语言:javascript
复制
// DStore。js导入duex:

export default new DStore({
  state:{count:1},
  mutations:{
    add(state){
      state.count++
    }
  }
})

在组件中吧状态作为计算属性导入:

代码语言:javascript
复制
// app.vue需要导入DStore
export defaut{
  computed:{
    count(){
      return store.state.count;
    }
  }
}

写一个按钮,点击触发add,然后就成功了。


4. 手撸router

现在回顾一下router通常是怎么用的。

代码语言:javascript
复制
const routes=[
  {path:'/aaa',component:Aaa},
  {path:'/bbb',component:Bbb},
  {path:'/ccc',component:Ccc},
]

const router=new  VueRouter(Vue,{routes});
new Vue({
    el:`#App`,
    router
})

如果看到这个十分亲切而不会一脸懵逼,那么就可以进行手撸router的操作了。 这个简化版的名字就叫做Due-router吧。

构造函数:初始化
代码语言:javascript
复制
// 引入Vue
class DueRouter{
    constructor(Vue,options){
        this.$options=options;
        // 全局路由映射,不可重复,routerMap里的键就是path,值就是里面的组件。
        this.routeMap={};
        //强依赖,把动态路由路径存进去:
        this.vm=new Vue({
            data:{
                current:'#/'
            }
        });

        this.init();
        this.createRouteMap(this.$options);
    }

options就是那一大串路由数组。通过createRouteMap存到this.routeMap中。

代码语言:javascript
复制
    //映射:把options里的内容装进去!
    createRouteMap(options){
        options.routes.forEach(item => {
            this.routeMap[item.path]=item.component
        });
    }

当前页面的的路由值是存到vue实例的一个状态中(current),初始值为#/ 接下来就是监听网页的哈希路由改变事件,网页加载事件:

代码语言:javascript
复制
// 初始化hashChange,只要哈希变化,就执行onHashChange方法。
    init(){
        window.addEventListener('load',this.onHashChange.bind(this),false);
        window.addEventListener('hashchange',this.onHashChange.bind(this),false)
    }

    //onHashChange:设置当前路径
    onHashChange(){
        this.vm.current=this.getHash();
    }

    // 获取hash路由
    getHash(){
        return window.location.hash.slice(1)||'/'
    }
注册组件

实现在使用中的两个功能,router-linkrouter-view:

代码语言:javascript
复制
//注册组件
    initComponent(Vue){
        Vue.component('router-link',{
            props:{
                to:String
            },
            // 返回虚拟a标签
            render:function(h){
                // 这里的h,表示createElement,实际上就是返回虚拟dom的工厂函数。
                // 实际上你看到的是 <a :href="to"><slot></slot></a>
                return h(
                    'a',//a标签
                    {href:this.to},//设置href属性
                    this.slot.default
                );
            }
        })

        const _this=this;
        // 根据组件,返回router-view的虚拟dom
        Vue.component('router-View',{
            render(h){
                let component=_this.routeMap[_this.vm.current];
                //页面刷新,渲染对应的component
                return h(component)
            }
        })
    }

那么核心功能就实现了


本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-05-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 一Li小麦 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 3. 手撸vuex源码
  • 4. 手撸router
    • 构造函数:初始化
      • 注册组件
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档