-
Notifications
You must be signed in to change notification settings - Fork 324
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
12 changed files
with
434 additions
and
24 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,28 +1,36 @@ | ||
<template> | ||
<div id="app"> | ||
<img src="./assets/logo.png"> | ||
<HelloWorld msg="Welcome to Your Vue.js App"/> | ||
<div id="nav"> | ||
<router-link to="/">Home</router-link> | | ||
<router-link to="/about">About</router-link> | ||
</div> | ||
<p @click="$store.commit('add')">{{ $store.state.counter }}</p> | ||
<p @click="$store.dispatch('add')">async{{ $store.state.counter }}</p> | ||
<p>double: {{$store.getters.doubleCounter}}</p> | ||
<!-- 占位符 --> | ||
<router-view /> | ||
</div> | ||
</template> | ||
|
||
<script> | ||
import HelloWorld from './components/HelloWorld.vue' | ||
export default { | ||
name: 'app', | ||
components: { | ||
HelloWorld | ||
} | ||
} | ||
</script> | ||
|
||
<style> | ||
#app { | ||
font-family: 'Avenir', Helvetica, Arial, sans-serif; | ||
font-family: "Avenir", Helvetica, Arial, sans-serif; | ||
-webkit-font-smoothing: antialiased; | ||
-moz-osx-font-smoothing: grayscale; | ||
text-align: center; | ||
color: #2c3e50; | ||
margin-top: 60px; | ||
} | ||
#nav { | ||
padding: 30px; | ||
} | ||
#nav a { | ||
font-weight: bold; | ||
color: #2c3e50; | ||
} | ||
#nav a.router-link-exact-active { | ||
color: #42b983; | ||
} | ||
</style> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import Vue from 'vue' | ||
import VueRouter from './kvue-router' | ||
import Home from '../views/Home.vue' | ||
|
||
// 引入插件 | ||
// use方法将来会调用install方法 | ||
Vue.use(VueRouter) | ||
|
||
// 路由映射表 | ||
const routes = [ | ||
{ | ||
path: '/', | ||
name: 'Home', | ||
component: Home, | ||
}, | ||
{ | ||
path: '/about', | ||
name: 'About', | ||
// route level code-splitting | ||
// this generates a separate chunk (about.[hash].js) for this route | ||
// which is lazy-loaded when the route is visited. | ||
component: () => import(/* webpackChunkName: "about" */ '../views/About.vue') | ||
} | ||
] | ||
|
||
const router = new VueRouter({ | ||
routes | ||
}) | ||
|
||
export default router |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
let Vue; | ||
|
||
// vue插件编写 | ||
// 实现一个install方法 | ||
class VueRouter { | ||
constructor(options) { | ||
console.log(Vue); | ||
this.$options = options; | ||
|
||
// 保存当前hash到current | ||
// current应该是响应式的 | ||
// 给指定对象定义响应式属性 | ||
Vue.util.defineReactive( | ||
this, | ||
"current", | ||
window.location.hash.slice(1) || "/" | ||
); | ||
// this.current = "/"; | ||
|
||
// 监控hashchange | ||
window.addEventListener("hashchange", () => { | ||
// #/about => /about | ||
this.current = window.location.hash.slice(1); | ||
}); | ||
} | ||
} | ||
|
||
// 形参1是Vue构造函数: 目的是便于扩展 | ||
VueRouter.install = function(_Vue) { | ||
Vue = _Vue; | ||
|
||
// 1. 将$router注册一下 | ||
// 下面代码延迟未来某个时刻:根实例创建时 | ||
Vue.mixin({ | ||
beforeCreate() { | ||
// 只需要根实例时执行一次 | ||
if (this.$options.router) { | ||
// 希望将来任何组件都可以通过$router | ||
// 访问路由器实例 | ||
Vue.prototype.$router = this.$options.router; | ||
} | ||
}, | ||
}); | ||
|
||
// 2. 注册两个全局组件:router-Link, router-view | ||
Vue.component("router-link", { | ||
// template: '<a>router-link</a>' | ||
props: { | ||
to: { | ||
type: String, | ||
required: true, | ||
}, | ||
}, | ||
render(h) { | ||
// h就是createElement() | ||
// 作用:返回一个虚拟dom | ||
// <router-link to="/about">abc</router-link> | ||
// return <a href={"#" + this.to}>{this.$slots.default}</a>; | ||
// 获取插槽内容:this.$slots.default | ||
return h( | ||
"a", | ||
{ | ||
attrs: { | ||
href: "#" + this.to, | ||
}, | ||
}, | ||
this.$slots.default | ||
); | ||
}, | ||
}); | ||
|
||
Vue.component("router-view", { | ||
// vue.runtime.js | ||
// vue.js compiler -> template -> render() | ||
// template: '<div>router-view</div>' | ||
render(h) { | ||
// 可以传入一个组件直接渲染 | ||
// 思路:如果可以根据url的hash部分动态匹配这个要渲染的组件 | ||
// window.location.hash | ||
// console.log(this.$router.$options.routes); | ||
// console.log(this.$router.current); | ||
let component = null; | ||
const route = this.$router.$options.routes.find( | ||
(route) => route.path === this.$router.current | ||
); | ||
if (route) { | ||
component = route.component | ||
} | ||
return h(component); | ||
}, | ||
}); | ||
}; | ||
|
||
export default VueRouter; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import Vue from 'vue' | ||
import Vuex from './kvuex' | ||
|
||
Vue.use(Vuex) | ||
|
||
export default new Vuex.Store({ | ||
// state应该是响应式对象 | ||
state: { | ||
counter: 0 | ||
}, | ||
mutations: { | ||
// state从何而来 | ||
add(state) { | ||
state.counter++ | ||
} | ||
}, | ||
actions: { | ||
// 上下文从何而来,长什么样 | ||
add({commit}) { | ||
setTimeout(() => { | ||
commit('add') | ||
}, 1000); | ||
} | ||
}, | ||
getters: { | ||
doubleCounter: state => { | ||
return state.counter * 2; | ||
} | ||
} | ||
}) |
Oops, something went wrong.