0. 准备工作
- 引入项目的基本依赖和开发依赖
cd [项目文件夹]
npm install axios@0.18.0
npm install vue-router@3.0.1
npm install vuex@3.0.1
npm install vuelidate@0.7.4
npm install bootstrap@4.0.0
npm install font-awesome@4.7.0
npm install --save-dev json-server@0.12.1
npm install --save-dev jsonwebtoken@8.1.1
npm install --save-dev faker@4.1.0
注: 带--save-dev的依赖是开发依赖,只在开发环境时生效。
- 各个依赖包解释
包名 | 详细描述 |
---|---|
axios | HTTP请求服务,这是一个通用类库。 |
vue-router | 路由功能。 |
vuex | Vue的全局状态管理库,应用程序级别的数据共享。 |
veulidate | 表单验证。 |
bootstrap | Twitter大名鼎鼎的样式库。 |
font-awesome | 丰富的icon库。 |
json-server | 模拟假的Rest服务,用于前后分离开发时前端开发模拟后端接口用。 |
jsonwebtoken | 模拟假的认证token。 |
faker | 用于生成假数据的库。 |
1. 假数据模拟REST接口
1-1) 造假数据
data.js
var data = [{ id: 1, name: "Kayak", category: "Watersports",
description: "A boat for one person", price: 275 },
...
];
module.exports = function () {
return {
products: data,
categories: [...new Set(data.map(p => p.category))].sort(),
orders: []
} }
1-2) 启用json-server
package.json
运行
npm run json
结果
2. Vuex全局状态管理
2-1) 定义
Vuex是一个专门为Vue.js应用程序开发的状态管理库,它采用集中式存储来管理应用程序中所有组件的状态。
2-2) 基本用法
-
每一个Vuex应用的核心就是store, store可理解为保存应用程序状态的容器。
-
store与普通的全局对象的区别:
a) 它是响应式的,如果store中的状态发生变化,相应的组件也会得到高效更新。
b) 不能直接改变store中的状态, 改变store状态的唯一途径就是显式地提交mutation。(非常重要!!)
- store通常以不同的JS模块的形式存在。
新建src/store文件夹。
在该文件夹下新建一个index.js文件。
2-3) 实例
a) 新建一个store
(src/store/index.js)
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
const testData = [];
for (let i = 1; i <= 10; i++) {
testData.push({
id: i, name: `Product #${i}`, category: `Category ${i % 3}`,
description: `This is Product #${i}`, price: i * 50
})
}
export default new Vuex.Store({
strict: true,
state: {
products: testData
}
})
代码解释:
关键词 | 描述 |
---|---|
Vue.use(Vuex) | 开启Vuex插件库 |
new Vuex.Store | 新建一个data store, 其中state属性负责存储数据 |
b) 引入Vuex Data Store
main.js
...
import store from "./store";
new Vue({
render: h => h(App),
store
}).$mount('#app')
3. 组件化开发初步
a) 编写组件
在src/components文件夹下新建Home.vue文件,作为首页组件。
内容如下:
<template>
<div class="container-fluid">
<div class="row">
<div class="col bg-dark text-white">
<a class="navbar-brand">SPORTS STORE</a>
</div>
</div>
<div class="row">
<div class="col-3 bg-info p-2">
<h4 class="text-white m-2">Categories</h4>
</div>
<div class="col-9 bg-success p-2">
<h4 class="text-white m-2">Products</h4>
</div>
</div>
</div>
</template>
b) 引用组件
App.vue
<template>
<home />
</template>
<script>
import Store from "./components/Home";
export default {
name: 'app',
components: { Home }
}
</script>
代码解释:
如上代码我们只是新建了一个简单的首页组件,分为上下左右结构,各个区域的内容暂时用简单文本占位一下。
c) 新建内容区域组件
在src/components文件夹下新建ProductList.vue文件,作为产品列表组件。
内容如下:
<template>
<div>
<div v-for="p in products" v-bind:key="p.id" class="card m-1 p-1 bg-light">
<h4>
{{p.name}}
<span class="badge badge-pill badge-primary float-right">
{{ p.price }}
</span>
</h4>
<div class="card-text bg-white p-1">{{ p.description }}</div>
</div>
</div>
</template>
<script>
import { mapState } from "vuex";
export default {
computed: {
...mapState(["products"])
}
}
</script>
代码解释:
还记得我们在上一步的src/store下新建的index.js吗,我们在里面模拟了一个测试产品列表数据。
现在就是派上用处的时候了!
注意点:
1. mapState是Vuex里比较重要的一个函数,它用来映射store中的状态。
2. mapState前面的...号是因为: mapSate可以映射多个状态。
3. data store中的状态一般被映射为组件的计算属性(computed)。
关于计算属性映射state, 名字可以不一样。
我们看一下下面的例子:
创建全局状态:
export default new Vuex.Store({
state: {
count: 0,
message: 'Hello KG'
}
})
引用全局状态:
<script>
import { mapState } from "vuex";
export default {
computed: {
mapState({
num: 'count',
msg: 'message'
})
}
}
</script>
代码解释:
上面代码中,冒号前是计算属性的名字(num, msg),
冒号后是store中状态属性的名字(count, message)。
d) 引用内容区域组件
修改Home.vue如下:
<template>
<div class="container-fluid">
...
<div class="row">
...
<div class="col-9 p-2 ">
<product-list />
</div>
</div>
</div>
</template>
<script>
import ProductList from "./ProductList";
export default {
components: { ProductList }
}
</script>
效果图如下:
image.png
4. 设置过滤器(Filters)
过滤器被用来做绑定数据格式化。
修改ProductList.vue如下:
<template>
<div>
...
<span class="...">
{{ p.price | currency }}
</span>
...
</div>
</template>
<script>
import { mapState } from "vuex";
export default {
...
filters: {
currency(value) {
return new Intl.NumberFormat("en-US",
{ style: "currency", currency: "USD" }).format(value);
}
}
}
</script>
效果图如下:
image.png
网友评论