美文网首页
7天深入Vue- 路由与vuex(二)

7天深入Vue- 路由与vuex(二)

作者: 申_9a33 | 来源:发表于2021-02-12 12:45 被阅读0次

1.vue 路由

1.1实现router-link组件 (主要返回一个a标签)

/**router-link.js**/

export default {
  props:{
    to:{
      type:String,
      required:true
    }
  },
  render(h){
    return h("a",{attrs:{herf:`#${this.to}`}},this.$slots.default) // 三个参数,第一个是a标签,第二个是参数,第三个是children
  }
}

1.2实现router-view组件, (渲染匹配到的内容)

/**router-view.js**/

export default {
        render(h) {
            // 标记自己是router-view 组件
            this.$vnode.data.routerView = true;

            // 标记路由深度
            let depth = 0;
            let parent = this.$parent;
            while (parent) {
                const vnodeData = parent.$vnode && parent.$vnode.data
                if (vnodeData) {
                    if (vnodeData.routerView) {
                        depth++
                    }
                }
                parent = parent.$parent
            }



            // 获取path对应的component
            // const item = this.$router.$options.routes.find(({ path }) => path === this.$router.current);

            const item = this.$router.matched[depth]
            if (!item) {
                return h('div', '')
            }
            return h(item.component)
        }
 }

1.3 vue-router (实现vue-router功能)

/**vue-router.js**/

import link from './router-link.js'
import view from './router-view.js'

let Vue;

class VueRouter {
    constructor(options) {
        this.$options = options;

        // 需要创建响应式属性
        // Vue.util.defineReactive(this, 'current', window.location.hash.slice(1))
        this.current = window.location.hash.slice(1);
        Vue.util.defineReactive(this, 'matched', [])

        // 监听url变化
        window.addEventListener('hashchange', () => {
            console.log(window.location.hash)
            this.current = window.location.hash.slice(1)
            this.matched = []

            this.match()
        })
    }

    match(routers) {
        routers = routers || this.$options.routes

        for (const router of routers) {
            if (router.path === '/' && this.current === '/') {
                this.matched.push(router)
            } else if (router.path !== '/' && this.current.indexOf(router.path) === 0) {
                this.matched.push(router)
                if (router.children)
                    this.match(router.children)
                return;
            }

        }
    }
}

VueRouter.install = function(_vue){
  Vue  = _vue;

  Vue.mixin({
     beforeCreate(){
      if(this.$options.router){
        Vue.prototype.$router = this.$options.router // 将vue-router挂载到Vue实例上
      }
     }
   })

  // 注册两个组件
  Vue.component('router-link',link)
  Vue.component('router-view',view)
}

export default VueRouter

1.4 配置路由表

/**index.js**/

import Vue from 'vue'
import VueRouter from './vue-router'
import Home from '../views/Home.vue'

Vue.use(VueRouter)

const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home
  },
  {
    path: '/about',
    name: 'About',
    component: () => import(/* webpackChunkName: "about" */ '../views/About.vue'),
    children: [
      {
        path: '/about/test',
        name: 'test',
        component: {
          render(h) {
            return h('div', 'test page')
          },
        }
      }
    ]
  }
]

const router = new VueRouter({
  routes
})

export default router

1.5使用

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

Vue.config.productionTip = false
Vue.prototype.$create = create;

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

2.vuex

2.1实现

/**vuex.js**/

class Store {
    constructor(options) {
        this._getters = options.getters
        this._mutations = options.mutations
        this._actions = options.actions

        // 定义computed选项
        const computed = {};
        this.getters = {}; // 暴露给用户

        const stroe = this;
        Object.keys(this._getters).forEach(key => {
            const fn = stroe._getters[key]

            computed[key] = function () { // 增加computed 需要的参数
                return fn(stroe.state);
            }

            Object.defineProperty(stroe.getters, key, {
                get: () => stroe.state[key]
            })
        })

        this.state = new Vue({
            data: options.state,
            computed: computed,
        })



        // 绑定commit actions 的上下文为store示例
        this.commit = this.commit.bind(this);
        this.dispatch = this.dispatch.bind(this);
    }

    // 类型 ,负载
    commit(type, payload) {
        const entry = this._mutations[type]
        if (entry) {
            entry(this.state, payload);
        }
    }

    dispatch(type, payload) {
        const entry = this._actions[type]
        if (entry) {
            entry(this, payload);
        }
    }
}

function install(_Vue) {
    Vue = _Vue

    Vue.mixin({
        beforeCreate() {
            if (this.$options.store) {
                Vue.prototype.$store = this.$options.store
            }
        },
    })
}

// Vuex
export default {
    Store,
    install
}

2.2配置

import Vue from 'vue'
import Vuex from './vuex.js'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    count: 1
  },
  mutations: {
    add(state) {
      state.count++
    }
  },
  actions: {
    asyncAdd({ commit }) {
      setTimeout(() => {
        commit("add")
      }, 2000)
    }
  },
  getters: {
    doubleCount(state) {
      return state.count * 2
    }
  },
  modules: {
  }
})

2.3 使用

import Vue from 'vue'
import App from './App.vue'
import store from './Store'


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

/**
    <P @click="$store.commit('add')">add:{{ $store.state.count }}</P>
    <P @click="$store.dispatch('asyncAdd')"
      >asyncAdd:{{ $store.state.count }}</P
    >
    <P>doubleCount:{{ $store.getters.doubleCount }}</P>
**/

源码链接

相关文章

  • 7天深入Vue- 路由与vuex(二)

    1.vue 路由 1.1实现router-link组件 (主要返回一个a标签) 1.2实现router-view组...

  • 6 VUE路由

    vue-> SPA应用,单页面应用(引入vue-router.js) 路由嵌套(多层路由): 路由其他信息:

  • Vue-基础-05-重点

    Vue-基础-day05-重点 01-基础-路由-vue-router-嵌套路由 children用法和route...

  • 由修改路由懒加载引起的

    layout: posttitle: 由修改路由懒加载引起的tags:- Vue- 笔记 项目背...

  • 11. vue-­router路由和vuex

    11.1 vue-­router路由基本加载 小案例:在根路径下只显示图片,在/hello下即显示图片又显示hel...

  • 第十一章 vue­-router路由和前端状态 管理

    11.1 vue-­router路由基本加载 简单四步走 安装 引用 配置路由文件,并在vue实例中注入 确定视图...

  • 【vue-进阶】之深入理解Vuex

    为什么需要Vuex 通常 Vue 项目中的数据通信,我们通过以下三种方式就可以解决,但是随着项目多层嵌套的组件增加...

  • Vue路由与Vuex

    一、 VueRouter Vue Router是Vue.js官方的路由管理器。它和Vue.js的核心深度集成,让构...

  • vue-路由

    路由是什么 路由,其实就是指向,当我点击home导航按钮,页面显示home的内容,如果点击的是about,就切换成...

  • vue-路由

    需要掌握: 路由map路由视图路由导航 路由参数的配置嵌套路由的使用 命名路由和命名视图重定向 router/in...

网友评论

      本文标题:7天深入Vue- 路由与vuex(二)

      本文链接:https://www.haomeiwen.com/subject/xxvdxltx.html