即将开始我的实习生活,虽然已经度过了面试的过程,但是学习新知识和复习老知识的脚步永远不能停歇,二面刚刚结束的时候,一面的面试官就跟我说可以提供offer了,然后跟我说了他们公司的目前项目的技术栈是vue2+ts,让我多熟悉一下使用ts编写vue2程序,以及vuex-typescript的写法。
先复习一下vuex的使用吧
为什么要使用Vuex
我们先使用VueCli
初始化一个项目,然后清理一下项目目录,把没用的东西都删掉。
我们先尝试一下不适用Vuex,来写一个组件间数据传递的内容。
在Components
文件夹下,分别创建一个Tab
组件,一个Page
组件。
Tab组件
<template>
<div>
<a href="javascript:;"
:class="[ { current: curIdx == 0 } ]"
@click="changeTab(0)"
>选项一</a>
<a href="javascript:;"
:class="[ { current: curIdx == 1 } ]"
@click="changeTab(1)"
>选项二</a>
<a href="javascript:;"
:class="[ { current: curIdx == 2 } ]"
@click="changeTab(2)"
>选项三</a>
<a href="javascript:;"
:class="[ { current: curIdx == 3 } ]"
@click="changeTab(3)"
>选项四</a>
</div>
</template>
<script>
export default {
name: 'Tab',
props: {
curIdx: Number
},
methods: {
changeTab (index) {
this.$emit('changeTab', index);
}
}
}
</script>
<style scoped>
a {
margin-right: 10px;
}
.current {
text-decoration: none;
color: #000;
}
</style>
Tab
组件的内容如上,首先是四个a
标签,根据当前的索引来动态的给他们赋予样式,并且绑定相同的点击事件,参数为当前的索引。
当前点击的索引curIdx
是由父组件传递过来,所以我们需要props
进行接收,点击事件携带的索引参数也要使用$emit
的方式传给父组件。
以此来达到Tab切换的效果。
Page组件
<template>
<div>
{
{ content[curIdx] }}
</div>
</template>
<script>
export default {
name: 'Page',
props: {
curIdx: Number
},
data () {
return {
content: [
'页面一',
'页面二',
'页面三',
'页面四'
]
}
}
}
</script>
<style scoped>
</style>
Page
组件的内容相对简单,同样使用props
接收一下来自父组件的索引值传递。在data
中保存一个简单的数组,展示Tab
页切换后的内容。
App.vue
<template>
<div id="app">
<tab
:curIdx="curIdx"
@changeTab="changeTab"></tab>
<page :curIdx="curIdx"></page>
</div>
</template>
<script>
import Tab from '@/components/Tab';
import Page from '@/components/Page';
export default {
name: 'App',
components: {
Tab,
Page
},
data () {
return {
curIdx: 0,
};
},
methods: {
changeTab (index) {
this.curIdx = index;
}
}
}
</script>
写好Tab
组件和Page
组件后,接下来就去App.vue
中对组件进行引入和注册。
经过实测,可以实现我们的效果,切换Tab
页的同时页面内容进行对应切换。
这是不使用Vuex
的组件间传值,我们的传值过程是,在App.vue
中把索引值传递给 Tab
组件,Tab
组件将切换后的索引值传回给App.vue
,App.vue
将切换后的索引值再传递给Page
组件。以此来实现预期的效果。
虽然这样的实现方式并不能称得上是很差,因为我们总体来说进行的组件间的嵌套和传值个数都是极少极简的,如果组件间的嵌套有十层,需要传递的值有十个,再使用这种普通的方式实现,是不是就显得很蠢了。
如何使用Vuex
接下来,我们使用Vuex
来改造我们的程序。
首先先介绍一下Vuex
,改造我们上面的程序只需要用到它的state
属性和mutations
属性。
state
,你可以理解成它是一个数据库
,专门用来存储数据的,官方说的状态管理,不好理解。它的作用有且只有一个,那就是存储数据。
mutations
,既然state
可以理解成为是一个数据库
,那么我们知道数据库是可以增删改查的,所以操作state
的方式有且只有一个,就是通过mutations
。
store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
curIdx: 0
},
mutations: {
setCurIdx (state, index) {
state.curIdx = index;
}
}
})
Tab组件
<template>
<div>
<a href="javascript:;"
:class="[ { current: curIdx === 0 } ]"
@click="setCurIdx(0)"
>选项一</a>
<a href="javascript:;"
:class="[ { current: curIdx === 1 } ]"
@click="setCurIdx(1)"
>选项二</a>
<a href="javascript:;"
:class="[ { current: curIdx === 2 } ]"
@click="setCurIdx(2)"
>选项三</a>
<a href="javascript:;"
:class="[ { current: curIdx === 3 } ]"
@click="setCurIdx(3)"
>选项四</a>
</div>
</template>
<script>
import {
mapState, mapMutations } from 'vuex';
export default {
name: 'Tab',
computed: {
...mapState(['curIdx'])
},
methods: {
...mapMutations(['setCurIdx'])
}
}
</script>
<style scoped>
a {
margin-right: 10px;
}
.current {
text-decoration: none;
color: #000;
}
</style>
对于一下之前的Tab
组件,我们只需要引入一下vuex
提供的mapState
和mapMutations
,在计算属性中...mapState(['curIdx'])
就实现了获取state
中数据的操作。在methods
中,...mapMutations(['setCurIdx'])
就实现了修改state
中数据的操作。
Page组件
<template>
<div>
{
{ content[curIdx] }}
</div>
</template>
<script>
import {
mapState } from 'vuex';
export default {
name: 'Page',
computed: {
...mapState(['curIdx'])
},
data() {
return {
content: [
'页面一',
'页面二',
'页面三',
'页面四'
],
};
},
}
</script>
Page
组件的改动很小,只涉及到数据的获取,所以我们只需要引入mapState
。
App.vue
<template>
<div id="app">
<tab></tab>
<page></page>
</div>
</template>
<script>
import Tab from '@/components/Tab';
import Page from '@/components/Page';
export default {
name: 'App',
components: {
Tab,
Page
}
}
</script>
App.vue
中的改动巨大,只需要引入组件并进行注册使用即可,不需要进行任何的操作。
经过实测,依然可以实现我们预期的效果。
对比不使用Vuex
和使用Vuex
实现程序的过程,我们不难看出,使用Vuex
管理数据之后,代码显得很简洁明了。我们的测试用例还是属于比较简单的需求,在这种需求下,你可以不使用Vuex
,但是当你的需求很复杂,数据量很大,组件嵌套层数很多的时候,你自然会选择使用Vuex
。
QQ:505417246
微信:18331092918
微信公众号:Code程序人生
个人博客:http://rayblog.ltd