Vue实战(二) - 实战项目(上) - 初识组件/内置函数/状

2021-05-08  本文已影响0人  ElliotG

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

结果

image.png

 

2. Vuex全局状态管理

2-1) 定义
Vuex是一个专门为Vue.js应用程序开发的状态管理库,它采用集中式存储来管理应用程序中所有组件的状态。


2-2) 基本用法

a) 它是响应式的,如果store中的状态发生变化,相应的组件也会得到高效更新。
b) 不能直接改变store中的状态, 改变store状态的唯一途径就是显式地提交mutation。(非常重要!!)

新建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
上一篇下一篇

猜你喜欢

热点阅读