Skip to content

Commit 4c7ad52

Browse files
author
wangbingying
committed
feature: 添加响应式api,组合式api示例
1 parent 17a66db commit 4c7ad52

21 files changed

+994
-352
lines changed

README.md

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
# vue3-demo
1+
# vue3-ts-boilerplate
22

3-
这是一个关于vue3的入门教程:包含`HelloWorld``响应式API``组合式API`的使用,以及`TodoList`的MVC示例。
4-
集成了`vuex4``vue-router4``typescript`以及`vite`
3+
a `vue3` + `vuex4` + `vue-router4` + `typescript` + `vite` boilerplate
54

6-
![screenshot](https://user-images.githubusercontent.com/1866848/95722987-37319480-0ca7-11eb-9d0b-b3155947b1c7.png)
5+
![screenshot](https://user-images.githubusercontent.com/1866848/95722987-37319480-0ca7-11eb-9d0b-b3155947b1c7.png)

package.json

+5-5
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,16 @@
66
"build": "vite build"
77
},
88
"dependencies": {
9-
"vue": "^3.0.0-rc.1",
10-
"vue-router": "^4.0.0-beta.13",
11-
"vuex": "^4.0.0-beta.4"
9+
"vue": "^3.0.3",
10+
"vue-router": "^4.0.0-rc.5",
11+
"vuex": "^4.0.0-rc.2"
1212
},
1313
"devDependencies": {
14-
"@vue/compiler-sfc": "^3.0.0-rc.1",
14+
"@vue/compiler-sfc": "^3.0.3",
1515
"eslint": "^7.11.0",
1616
"eslint-plugin-vue": "^7.0.1",
1717
"sass": "^1.27.0",
1818
"typescript": "^4.0.3",
19-
"vite": "^1.0.0-rc.1"
19+
"vite": "^1.0.0-rc.13"
2020
}
2121
}

src/App.vue

+23-2
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,32 @@
22
<div class="view">
33
<div id="nav">
44
<div>
5-
<b>🚀 [vue3, vite, ts]</b>
5+
<b>🚀 vue3-demo </b>
66
</div>
77
<div>
88
<router-link to="/"> Home</router-link>
99
</div>
10+
<div class="group">
11+
<div>响应式API</div>
12+
<ul>
13+
<li><router-link to="/reactivity/ref">Ref</router-link></li>
14+
<li><router-link to="/reactivity/reactive">Reactive</router-link></li>
15+
<li><router-link to="/reactivity/computed">Computed</router-link></li>
16+
<li><router-link to="/reactivity/effect">Effect</router-link></li>
17+
<li><router-link to="/reactivity/watch">Watch</router-link></li>
18+
<li><router-link to="/reactivity/watchEffect">WatchEffect</router-link></li>
19+
</ul>
20+
</div>
21+
<div class="group">
22+
<div>组合式API</div>
23+
<ul>
24+
<li><router-link to="/composition/setup">Setup</router-link></li>
25+
<li><router-link to="/composition/lifecycle">Lifecycle</router-link></li>
26+
<li><router-link to="/composition/provide">Provide&Inject</router-link></li>
27+
<li><router-link to="/composition/nextTick">NextTick</router-link></li>
28+
<li><router-link to="/composition/event">Event</router-link></li>
29+
</ul>
30+
</div>
1031
<div>
1132
<router-link to="/counter"> Counter</router-link>
1233
</div>
@@ -18,4 +39,4 @@
1839
<router-view/>
1940
</div>
2041
</div>
21-
</template>
42+
</template>

src/index.scss

+13-5
Original file line numberDiff line numberDiff line change
@@ -31,20 +31,29 @@ body {
3131

3232
#nav {
3333
position: fixed;
34+
width: 200px;
3435
top: 0;
3536
left: 0;
3637
bottom: 0;
3738
background-color: #487ab5;
38-
padding: 24px 12px 12px;
39+
padding: 24px;
3940
flex: 0 0 auto;
4041
height: 100vh;
4142
z-index: 99;
4243

43-
div {
44+
> div {
4445
display: flex;
45-
height: 46px;
46-
line-height: 46px;
46+
flex-direction: column;
47+
justify-content: flex-start;
48+
align-items: flex-start;
4749
color: #92abcf;
50+
padding: 10px 0;
51+
52+
ul{
53+
li{
54+
text-align: left;
55+
}
56+
}
4857
}
4958

5059
a {
@@ -53,7 +62,6 @@ body {
5362
color: #92abcf;
5463
text-decoration: none;
5564
cursor: pointer;
56-
padding-left: 20px;
5765
text-align: left;
5866

5967
&:hover {

src/router/index.ts

+60
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,66 @@ const routes: Array<any> = [
77
name: "Home",
88
component: Home,
99
},
10+
{
11+
path: "/reactivity/ref",
12+
name: "Ref",
13+
component: () => import("../views/reactivity/Ref.vue"),
14+
},
15+
{
16+
path: "/reactivity/reactive",
17+
name: "Reactive",
18+
component: () => import("../views/reactivity/Reactive.vue"),
19+
},
20+
{
21+
path: "/reactivity/computed",
22+
name: "Computed",
23+
component: () => import("../views/reactivity/Computed.vue"),
24+
},
25+
{
26+
path: "/reactivity/effect",
27+
name: "Effect",
28+
component: () => import("../views/reactivity/Effect.vue"),
29+
},
30+
{
31+
path: "/reactivity/watch",
32+
name: "Watch",
33+
component: () => import("../views/reactivity/Watch.vue"),
34+
},
35+
{
36+
path: "/reactivity/watchEffect",
37+
name: "WatchEffect",
38+
component: () => import("../views/reactivity/WatchEffect.vue"),
39+
},
40+
{
41+
path: "/composition/setup",
42+
name: "Setup",
43+
component: () => import("../views/composition/Setup.vue"),
44+
},
45+
{
46+
path: "/composition/lifecycle",
47+
name: "Lifecycle",
48+
component: () => import("../views/composition/Lifecycle.vue"),
49+
},
50+
{
51+
path: "/composition/provide",
52+
name: "Provide",
53+
component: () => import("../views/composition/Provide.vue"),
54+
},
55+
{
56+
path: "/composition/inject",
57+
name: "Inject",
58+
component: () => import("../views/composition/Inject.vue"),
59+
},
60+
{
61+
path: "/composition/nextTick",
62+
name: "NextTick",
63+
component: () => import("../views/composition/nextTick.vue"),
64+
},
65+
{
66+
path: "/composition/event",
67+
name: "Event",
68+
component: () => import("../views/composition/Event.vue"),
69+
},
1070
{
1171
path: "/counter",
1272
name: "Counter",

src/views/Counter.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
export default {
2121
components: {MyButton},
2222
setup() {
23+
2324
const count = ref(0)
2425
const disabled = ref(false)
2526
const btnText = ref("点击增加count值")
@@ -44,7 +45,6 @@
4445
}
4546
}
4647
}
47-
4848
</script>
4949
<style lang="scss">
5050
.title {

src/views/Home.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<template>
22
<div class="home">
3-
<HelloWorld msg="Welcome to vue3-ts App"/>
3+
<HelloWorld msg="Welcome to vue3 App"/>
44
</div>
55
</template>
66

src/views/composition/Event.vue

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<template>
2+
event
3+
</template>
4+
5+
<script lang="ts">
6+
import { reactive, ref } from '@vue/reactivity'
7+
export default {
8+
setup(){
9+
// 使用 reactive() 函数定义响应式数据
10+
const count = ref(0)
11+
const obj = reactive({ count: 0 })
12+
13+
14+
}
15+
};
16+
</script>
17+

src/views/composition/Inject.vue

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<template>
2+
<h3>inject</h3>
3+
color: {{color}}
4+
</template>
5+
6+
<script lang="ts">
7+
import { inject } from 'vue'
8+
export default {
9+
name: 'Inject',
10+
setup(){
11+
// provide() 和 inject() 可以实现嵌套组件之间的数据传递。这两个函数只能在 setup() 函数中使用。
12+
// 父级组件中使用 provide() 函数向下传递数据;子级组件中使用 inject() 获取上层传递过来的数据。
13+
const color = inject('themeColor')
14+
15+
return {
16+
color
17+
}
18+
}
19+
};
20+
</script>
21+

src/views/composition/Lifecycle.vue

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<template>
2+
lifecycle
3+
</template>
4+
5+
<script lang="ts">
6+
7+
/**
8+
* 选项 API 生命周期选项和组合式 API 之间的映射
9+
10+
beforeCreate -> use setup()
11+
12+
created -> use setup()
13+
14+
beforeMount -> onBeforeMount
15+
16+
mounted -> onMounted
17+
18+
beforeUpdate -> onBeforeUpdate
19+
20+
updated -> onUpdated
21+
22+
beforeUnmount -> onBeforeUnmount
23+
24+
unmounted -> onUnmounted
25+
26+
errorCaptured -> onErrorCaptured
27+
28+
renderTracked -> onRenderTracked
29+
30+
renderTriggered -> onRenderTriggered
31+
*/
32+
import {onBeforeMount, onMounted, onBeforeUpdate, onUpdated, onBeforeUnmount, onUnmounted} from 'vue'
33+
34+
export default {
35+
setup() {
36+
console.log('setup')
37+
38+
onBeforeMount(() => {
39+
console.log('beforeMount!')
40+
})
41+
onBeforeUpdate(() => {
42+
console.log('beforeUpdate!')
43+
})
44+
onBeforeUnmount(() => {
45+
console.log('beforeUnmount!')
46+
})
47+
onMounted(() => {
48+
console.log('mounted!')
49+
})
50+
onUpdated(() => {
51+
console.log('updated!')
52+
})
53+
onUnmounted(() => {
54+
console.log('unmounted!')
55+
})
56+
}
57+
}
58+
</script>
59+

src/views/composition/NextTick.vue

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<template>
2+
nextTick
3+
4+
<input id="input" :value="message"/>
5+
</template>
6+
7+
<script lang="ts">
8+
import { nextTick, ref, onMounted } from 'vue'
9+
export default {
10+
setup(){
11+
// nextTick 是 vue 中的更新策略,也是性能优化手段,基于JS执行机制实现
12+
// vue 中我们改变数据时不会立即触发视图,如果需要实时获取到最新的DOM,这个时候可以手动调用 nextTick
13+
14+
// nextTick接受函数作为参数,同时nextTick会创建一个微任务。
15+
// queueJob接受函数作为参数,queueJob会将参数push到queue队列中,在当前宏任务执行结束之后,清空队列。
16+
// queuePostFlushCb接受函数或者又函数组成的数组作为参数,queuePostFlushCb会将将参数push到postFlushCbs队列中,在当前宏任务执行结束之后,清空队列。
17+
// queueJob执行的优先级高于queuePostFlushCb
18+
// queueJob和queuePostFlushCb允许在清空队列的期间添加新的成员。
19+
const message = ref('Hello!')
20+
21+
const changeMessage = async newMessage => {
22+
message.value = newMessage
23+
console.log((document.getElementById('input') as HTMLInputElement).value)
24+
25+
// 这里获取DOM的value是旧值
26+
await nextTick()
27+
28+
// nextTick 后获取DOM的value是更新后的值
29+
console.log('Now DOM is updated')
30+
console.log((document.getElementById('input') as HTMLInputElement).value)
31+
}
32+
33+
onMounted(()=>{
34+
changeMessage('world')
35+
})
36+
37+
return {
38+
message
39+
}
40+
}
41+
};
42+
</script>
43+

src/views/composition/Provide.vue

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<template>
2+
<h3>Provide</h3>
3+
<button @click="changeColor('black')">变成黑色</button>
4+
5+
<Inject/>
6+
</template>
7+
8+
<script lang="ts">
9+
import { provide, ref } from 'vue'
10+
import Inject from './Inject.vue'
11+
export default {
12+
components: { Inject },
13+
setup(){
14+
const color = ref('red')
15+
16+
// provide() 和 inject() 可以实现嵌套组件之间的数据传递。这两个函数只能在 setup() 函数中使用。
17+
// 父级组件中使用 provide() 函数向下传递数据;子级组件中使用 inject() 获取上层传递过来的数据。
18+
provide('themeColor', color)
19+
20+
const changeColor = (val) => {
21+
color.value = val
22+
}
23+
24+
return {
25+
color,
26+
changeColor
27+
}
28+
}
29+
};
30+
</script>
31+

0 commit comments

Comments
 (0)