Vue商城项目05(完)

vue

实现购物车效果

vuex并设计购物车数据存储方式

  1. 运行 cnpm i vuex -S
  2. import Vuex from ‘vuex’
  3. Vue.use(Vuex)
  4. var store = new Vuex.Store({})
  5. 在vm实例中挂载 store 状态管理对象 store

点击加入购物车功能

    addToShopCar() {

// 添加到购物车

this.ballFlag = !this.ballFlag;

// { id:商品的id, count: 要购买的数量, price: 商品的单价,selected: false }

// 拼接出一个,要保存到 store 中 car 数组里的 商品信息对象

var goodsinfo = {

id: this.id,

count: this.selectedCount,

price: this.goodsinfo.sell_price,

selected: true

};

// 调用 store 中的 mutations 来将商品加入购物车

this.$store.commit("addToCar", goodsinfo);

}

购物车处徽标数值的自动更新

				<span class="mui-badge" id="badge">{{ $store.getters.getAllCount }}</span>

<span class="mui-tab-label">购物车</span>

  getters: { // this.$store.getters.***

// 相当于 计算属性,也相当于 filters

getAllCount(state) {

var c = 0;

state.car.forEach(item => {

c += item.count

})

return c

}

}

实现购物车商品的本地持久存储

每次刚进入 网站,肯定会 调用 main.js 在刚调用的时候,先从本地存储中,把 购物车的数据读出来,放到 store 中
var car = JSON.parse(localStorage.getItem(\'car\') || \'[]\')

当 更新 car 之后,把 car 数组,存储到 本地的 localStorage 中
localStorage.setItem(\'car\', JSON.stringify(state.car))

绘制购物车页面中商品列表的布局

借助于mui-master,examples,card.html。
复制一个基础的组件shopcar_numbox.vue,有选择数量按钮。可以直接加样式style="height:25px;"改变高度

获取购物车中所有商品列表并加载显示

    getGoodsList() {

// 1. 获取到 store 中所有的商品的Id,然后拼接出一个 用逗号分隔的 字符串

var idArr = [];

this.$store.state.car.forEach(item => idArr.push(item.id));

// 如果 购物车中没有商品,则直接返回,不需要请求数据接口,否则会报错

if (idArr.length <= 0) {

return;

}

// 获取购物车商品列表。join(",")根据接口文档需要传入的办法,用逗号分隔开传过去

this.$http

.get("api/goods/getshopcarlist/" + idArr.join(","))

.then(result => {

if (result.body.status === 0) {

this.goodslist = result.body.message;

}

});

}

在循环购物车列表时候初始化数量值,购物车商品数量改变同步到store中

main.js里

getters:

getGoodsCount(state) {

var o = {}

state.car.forEach(item => {

o[item.id] = item.count

})

return o

}

mutations:

updateGoodsInfo(state, goodsinfo) {

// 修改购物车中商品的数量值

// 分析:

state.car.some(item => {

if (item.id == goodsinfo.id) {

item.count = parseInt(goodsinfo.count)

return true

}

})

// 当修改完商品的数量,把最新的购物车数据,保存到 本地存储中

localStorage.setItem(\'car\', JSON.stringify(state.car))

}

父组件:

               <numbox :initcount="$store.getters.getGoodsCount[item.id]" :goodsid="item.id"></numbox>

<!-- 问题:如何从购物车中获取商品的数量呢 -->

<!-- 1. 我们可以先创建一个 空对象,然后循环购物车中所有商品的数据, 把 当前循环这条商品的 Id, 作为 对象 的 属性名,count值作为 对象的 属性值,这样,当把所有的商品循环一遍,就会得到一个对象: { 88: 2, 89: 1, 90: 4 } -->

子组件:

<input  :value="initcount" />

methods: {

countChanged() {

// 数量改变了

// console.log(this.$refs.numbox.value);

// 每当数量值改变,则立即把最新的数量同步到 购物车的 store 中,覆盖之前的数量值

this.$store.commit("updateGoodsInfo", {

id: this.goodsid,

count: this.$refs.numbox.value

});

}

},

props: ["initcount", "goodsid"]

实现购物车中商品的删除

    <a href="#" @click.prevent="remove(item.id, i)">删除</a>

<!-- prevent阻止默认事件 -->

remove(id, index) {

// 点击删除,把商品从 store 中根据 传递的 Id 删除,同时,把 当前组件中的 goodslist 中,对应要删除的那个商品,使用 index 来删除

this.goodslist.splice(index, 1); //第一个参数是删除项目的位置,第二个是要删除的项目数量。

this.$store.commit("removeFormCar", id);

}

main.js里的store里的mutations:

removeFormCar(state, id) {

// 根据Id,从store 中的购物车中删除对应的那条商品数据

state.car.some((item, i) => {

if (item.id == id) {

state.car.splice(i, 1)

return true;

}

})

// 将删除完毕后的,最新的购物车数据,同步到 本地存储中

localStorage.setItem(\'car\', JSON.stringify(state.car))

}

绘制结算区域样式

    display: flex; //让里面竖着的的盒子一行排放

justify-content: space-between;//两端对齐

align-items: center;//垂直居中

把store中选中的状态同步到页面上,同步商品的勾选状态到store中保存

计算属性是基于响应式依赖进行缓存的,只有数据发生变化时,才会重新计算,否则直接调用缓存

    // $store.getters.getGoodsSelected的值为{"88":true}(id为键,值为selected状态)            

//v-model=true时为打开开关

<mt-switch

v-model="$store.getters.getGoodsSelected[item.id]"

@change="selectedChanged(item.id, $store.getters.getGoodsSelected[item.id])">

</mt-switch>

组件里的方法

selectedChanged(id, val) {

// 每当点击开关,把最新的 快关状态,同步到 store 中

// console.log(id + " --- " + val);

this.$store.commit("updateGoodsSelected", { id, selected: val });

}

main.js里

getters:

getGoodsSelected(state) {

var o = {}

state.car.forEach(item => {

o[item.id] = item.selected

})

return o

}

mutations:

updateGoodsSelected(state, info) {

state.car.some(item => {

if (item.id == info.id) {

item.selected = info.selected

}

})

// 把最新的 所有购物车商品的状态保存到 store 中去

localStorage.setItem(\'car\', JSON.stringify(state.car))

}

实现勾选数量和总价的自动计算

main.js中  getters: 

getGoodsCountAndAmount(state) {

var o = {

count: 0, // 勾选的数量

amount: 0 // 勾选的总价

}

state.car.forEach(item => {

if (item.selected) {

o.count += item.count

o.amount += item.price * item.count

}

})

return o

}

组件里:

<p>已勾选商品 <span class="red">{{ $store.getters.getGoodsCountAndAmount.count }}</span> 件, 总价 <span class="red">¥{{ $store.getters.getGoodsCountAndAmount.amount }}</span></p>

实现返回按钮的功能

在Mint-ui官网里找,简单修改一下app.vue

    <mt-header fixed title="黑马程序员·Vue项目">

<span slot="left" @click="goBack" v-show="flag">

<mt-button icon="back">返回</mt-button>

</span>

</mt-header>

<script>

export default {

data() {

return {

flag: false

};

},

created() {

this.flag = this.$route.path === "/home" ? false : true;

},

methods: {

goBack() {

// 点击后退

this.$router.go(-1);

}

},

watch: { //监听路由的变化

"$route.path": function(newVal) {

if (newVal === "/home") {

this.flag = false;

} else {

this.flag = true;

}

}

}

};

</script>

tomcat虚拟目录

server.xml文件里的<Connector port="80"></Connector>是打开的端口号80

在Tomcat安装目录下的conf文件夹找到server.xml文件,在结尾处的</Host>前面加上
<Context path="" reloadable="true" docBase="D:\Demo" />
path为浏览器访问目录,docBase项目的虚拟根目录
开启Tomcat服务器,在浏览器访问localhost:80即可看到该目录

项目外网测试

将项目托管到Apache并启用:
先把dist删除,然后webpack打包会放到dist中,把dist中的index.html,bundle.js拷贝到docBase项目的虚拟根目录
注意:如果没有设置虚拟根目录,放在默认的根目录中
输入172.0.0.1:80或者localhost:80即可看到本地

开启Apache的gzip压缩

要让apache支持gzip功能,要用到deflate_Module和headers_Module。打开apache的配置文件httpd.conf,大约在105行左右,找到以下两行内容:(这两行不是连续在一起的)

#LoadModule deflate_module modules/mod_deflate.so

#LoadModule headers_module modules/mod_headers.so

然后将其前面的“#”注释删掉,表示开启gzip压缩功能。开启以后还需要进行相关配置。在httpd.conf文件的最后添加以下内容即可:

<IfModule deflate_module>

#必须的,就像一个开关一样,告诉apache对传输到浏览器的内容进行压缩

SetOutputFilter DEFLATE

DeflateCompressionLevel 9

</IfModule>

最少需要加上以上内容,才可以生gzip功能生效。由于没有做其它的额外配置,所以其它相关的配置均使用Apache的默认设置。这里说一下参数“DeflateCompressionLevel”,它表示压缩级别,值从1到9,值越大表示压缩的越厉害。

使用ngrok将本机映射为一个外网的Web服务器

打开ngrok.exe,输入ngrok http 80
注意 80 是项目运行的端口号
Session Status online时说明已经上线。其中Forwarding后面的就是地址,直接输入即可。

注意:由于默认使用的美国的服务器进行中间转接,所以访问速度炒鸡慢,访问时可启用f墙软件,提高网页打开速度。

以上是 Vue商城项目05(完) 的全部内容, 来源链接: utcz.com/z/379379.html

回到顶部