vue2+node+移动支付沙箱

基于vue2手机端的,茶友商城

1. gitee中创建项目,并初始化文件

1. git clone 项目文件地址
2. cd vue2-node--wechat-pay 切入到创建好的文件夹中
3. git branch -r 查看分支
4. git branch develop 创建 develop分支

>  git checkout develop 切换到develop分支下
5. git push --set-upstream origin develop 将初始化文件,推到develop分支上
6. 在gitee中,查看 分支是否创建成功**
7. 切换到包含 vue2-node--wechat-pay 文件夹中 ,使用vue create vue2-node--wechat-pay 创建vue2项目文件
8. cnpm install express-generator -g 全局安装,报错就是权限不够,前面加sudo,密码输入开机密码
9. 安装成功 cd vue2-node--wechat-pay 回车
10. express --view=ejs server(后端项目名称) 创建后台expree框架文件,cnpm install安装依赖

npm run start 或 yarn run start 启动后端项目,成功启动如下图!请添加图片描述
请添加图片描述

2.将创建好的项目,推到gitee develop分支下

请添加图片描述
请添加图片描述
请添加图片描述

2. 创建 前后端项目

1. 创建后端项目

vue create 项目名称,创建vue2项目,按自己需要选择配置项 yarn start 启动
全局安装 express | cnpm i express-generator -g
在项目目录下创建后端项目 express --view=ejs server
然后 cd server 进入目录, 安装依赖 cnpm i
yarn start 启动项目:http:localhost:3000
在这里插入图片描述

2. 安装插件,实现左右滑动效果

下载插件 cnpm install [email protected] -S 滑动插件
下载mint-ui组件库 cnpm install mint-ui -S
在main.js中引入

import Vue from "vue";
import App from "./App.vue";
import router from "./router";
import store from "./store/index";

//公共css文件
import '@/assets/css/common.css';
//字体图标css文件
import '@/assets/fonts/iconfont.css';
import '@/assets/fonts/iconfont.js';
//淘宝无线适配
import '@/assets/js/flexible';

//ly-tab插件
import LyTab from 'ly-tab';
import 'mint-ui/lib/style.css';
Vue.use(LyTab);

// 引入图片懒加载插件
import { Lazyload } from 'mint-ui';
Vue.use(Lazyload)

// 全局引入vant
import Vant from 'vant';
import 'vant/lib/index.css';
Vue.use(Vant)
// 禁止移动端,双击放大缩小
import FastClick from 'fastclick'
FastClick.attach(document.body)

Vue.config.productionTip = false;

new Vue({
  router,
  store,
  render: (h) => h(App),
}).$mount("#app");

在这里插入图片描述

2. lay-tab插件在vue2中使用

<template>
  <div class="home">
	<ly-tab
	    v-model="selectedId"
	    :items="items"
	    :options="options">
	</ly-tab>
  </div>
</template>

<script>
export default {
  name: "Home",
  data () {
	return {
		selectedId: 0,
		items: [
		  {label: '推荐'},
		  {label: '大红袍'},
		  {label: '绿茶'},
		  {label: '铁观音'},
		  {label: '普洱'},
		  {label: '茶具'},
		  {label: '花茶'}
		],
		options: {
		  activeColor: '#b0352f'
		}
	 }
  },
};
</script>

<style scoped>
.ly-tab{
	position: fixed;
	top:1.6rem;
	left:0;
}
::v-deep .ly-tabbar{
	box-shadow:none;
	border-bottom:none;
}
</style>

3. swiper在vue2中使用

cnpm i vue-awesome-swiper -S // 这种方式下载最新版的
cnpm i [email protected] -S 下载指定版本

main.js 中 全局 引入使用

import 'swiper/dist/css/swiper.css'
import VueAwesomeSwiper from 'vue-awesome-swiper'
Vue.use(VueAwesomeSwiper)

组件局部引入使用,如下

<template>
	<div class='swiper-main'>
		<swiper :options="swiperOption">
		  <swiper-slide 
			v-for='(item,index) in swiperList' 
			:key='index'
		   >
			<img :src="item.imgUrl" alt="">
		  </swiper-slide>
		</swiper>
		<div class="swiper-pagination"></div> 
	</div>
</template>

<script>
import 'swiper/dist/css/swiper.css'
import { swiper, swiperSlide } from 'vue-awesome-swiper'
export default {
  name: 'Swiper',
  data(){
    return{
		swiperList:[
			{
				id:1,
				imgUrl:'./images/swiper1.jpeg'
			},
			{
				id:2,
				imgUrl:'./images/swiper2.jpeg'
			},
			{
				id:3,
				imgUrl:'./images/swiper3.jpeg'
			}
		],
		swiperOption: {//swiper3
			autoplay: 3000,
			speed: 1000,
			pagination: {
				el: '.swiper-pagination'
			}
		}
    }
  },
  components: {
    swiper,
    swiperSlide
  },
}
</script>

<style scoped>
.swiper-main{
	position: relative;
	width: 100%;
	height: 4.4rem;
	margin-top:3rem;
}
.swiper-container{
	width: 100%;
	height: 4.4rem;
}
.swiper-main img{
	width: 100%;
	height: 4.4rem;
}
.swiper-pagination{
	width: 100%;
	bottom:0px;
}
::v-deep .swiper-pagination-bullet-active{
	background-color: #b0352f;
}
::v-deep .swiper-pagination-bullet{
	margin:0 0.08rem;
}
</style>

4. better-scroll 插件,滚动插件使用

参考 probeType better-scroll文章

// 引入滚动插件
import BetterScorll from 'better-scroll'
<section ref=''rightwrapper">
     <div>
        放页面内容
     </div>
</section>
data(){
     return{
        // 定义滑动数据
        rightBscroll: '',
     }
}
 this.$nextTick(() => {
      this.rightBscroll = new BetterScorll(this.$refs.rightwrapper, {
        click: true,
        probeType: 3,
        // 取消回弹效果
        bounce: false,
      })
 })

5. 图片懒加载

main.js全局引入
// 引入图片懒加载插件
import { Lazyload } from 'mint-ui';
Vue.use(Lazyload)

<img :src="item.imgUrl" alt="" />. 替换成 <img v-lazy="item.imgUrl" alt="" />

6. 使用keep-alive 提升性能,减少请求次数

app.vue组件中

keep-alive 是一个vue的内置组件
只要用的keep-alive会多两个生命周期,activated 和 deactivated

<template>
  <div id="app">
    <!-- 提升性能,减少请求次数 -->
    <!-- 需要缓存的路由 -->
    <keep-alive>
      <router-view v-if="$route.meta.keepAlive"></router-view>
    </keep-alive>
    <!-- 不需要缓存的路由 -->
    <router-view v-if="!$route.meta.keepAlive"></router-view>
  </div>
</template>
<script>
</script>
route.js需要配置
{
    // 结算订单页面
    path: '/order',
    name: 'order',
    meta: {
      keepAlive: true // 此组件需要缓存
    },
    component: () => import("../components/path/Order.vue")
  },

7. 使用 qs 增加安全性的序列化

cnpm i qs -S 更多了解,自己google

// 提高,传递参数的安全系数 (组件内使用,局部引入)
import qs from 'qs'
qs.stringify 替换 JSON.stringify

8. 路由传参,两种方式

路由传值 显式:
 this.$router.push({
    path: '/detail',
    query: {
        id
    }
}) 
隐式:
 this.$router.push({
    name: 'Detail',
    params: {
        id
    }

9. 移动端禁止用户,缩放

<meta name="viewport"  content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0,user-scalable=no" />

只设置meta,ios无效。

# 在App.vue,设置
<script>
    window.onload = function() {
    // 禁用双指放大
    document.addEventListener('touchstart', function(event) {
      if (event.touches.length > 1) {
        event.preventDefault()
      }
    });
    document.addEventListener('gesturestart', function(event) {
      event.preventDefault()
    })
    // 禁用双击放大
    var lastTouchEnd = 0;
    document.documentElement.addEventListener('touchend', function (event) {
        var now = Date.now();
        if (now - lastTouchEnd <= 300) {
            event.preventDefault();
        }
        lastTouchEnd = now;
    }, {
        passive: false
    });
  };
</script>

10. FastClick插件

处理移动端 click 事件 300 毫秒延迟, 由 FT Labs 开发。Github 项目地址:https://github.com/ftlabs/fastclick
1.为什么存在延迟?

从点击屏幕上的元素到触发元素的 click 事件,移动浏览器会有大约 300 毫秒的等待时间。为什么这么设计呢?
因为它想看看你是不是要进行双击(double tap)操作。

2. 不应用FastClick的场景

桌面浏览器;

  • 如果 viewport meta 标签 中设置了 width=device-width, Android 上的 Chrome32+ 会禁用 300ms 延时;
  • viewport meta 标签如果设置了 user-scalable=no,Android 上的Chrome(所有版本)都会禁用 300ms 延迟;
  • IE10 中,可以使用 css 属性 -ms-touch-action: none禁止元素双击缩放。

vue2项目中使用

// 处理移动端 click 事件 300 毫秒延迟
import FastClick from 'fastclick'
FastClick.attach(document.body)

11. 滑动时候警告1.滑动时候警告[Intervention] Unable to preventDefault inside passive event listener due to target being treated as passive

解决办法
请添加图片描述

 * { touch-action: pan-y; } 
 // 使用全局样式样式去掉

12. vue2引入less

下载 依赖
cnpm install less less-loader --sav-dev
cnpm i style-resources-loader --save
cnpm i vue-cli-plugin-style-resources-loader --save
代码中
<style lang='less'></style>

13. vue2底部导航,如果是本页面不进行跳转

在这里插入图片描述
如果不设置,到本页面,点击分类还是会进行跳转本页面,然后控制台报错

<template>
  <div class="tabbar">
    <ul>
      <li
        v-for="(item, index) in routerList"
        :key="index"
        @click="switchTab(item.path)"
      >
        <img
          v-lazy="$route.path.includes(item.path) ? item.selected : item.active"
          alt=""
        />
        <span :class="$route.path.includes(item.path) ? 'active' : ''">{
   
   {
          item.title
        }}</span>
      </li>
    </ul>
  </div>
</template>

<script>
export default {
  data() {
    return {
      routerList: [
        {
          title: '首页',
          path: '/home',
          active: '/images/home.png',
          selected: '/images/home-select.png',
        },
        {
          title: '分类',
          path: '/list',
          active: '/images/list.png',
          selected: '/images/list-select.png',
        },
        {
          title: '购物车',
          path: '/cart',
          active: '/images/cart.png',
          selected: '/images/cart-select.png',
        },
        {
          title: '我的',
          path: '/mine',
          active: '/images/my.png',
          selected: '/images/my-select.png',
        },
      ],
    }
  },
  methods: {
    switchTab(path) {
      //判断是否点击的是同一个路由
      if (this.$route.path == path) return
      //对应跳转页面
      this.$router.push(path)
    },
  },
}
</script>

<style scoped>
.tabbar {
  /* position: fixed;
  bottom: 0;
  left: 0; */
  width: 100%;
  height: 1.6rem;
  background-color: #fff;
}
.tabbar ul {
  display: flex;
  justify-content: space-around;
  align-items: center;
  width: 100%;
  height: 100%;
}
.tabbar ul li {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}
.tabbar ul li img {
  width: 0.826666rem;
  height: 0.826666rem;
}
.tabbar ul li img[lazy='loading'] {
  background-color: #f7f7f7;
}
.tabbar ul li span {
  font-size: 0.426666rem;
}
.active {
  color: red;
}
</style>

3. vue2进行配置,axios请求代理

在vue.config.js中进行配置

const { defineConfig } = require("@vue/cli-service");
module.exports = defineConfig({
  // 关闭文件校验
  lintOnSave: false,
  transpileDependencies: true,
  // Http请求代理
  devServer: {
    open: true, //自动打开浏览器
    // 访问路径就为,http://192.168.46.249:8080/
    host: '192.168.46.249', // 真机测试地址,mac os终端输入,ifconfig 查看ip地址
    proxy: {
      '/api': {
        target: "http://localhost:3000",
        changeOrigin: true,
        pathRewrite: {
          '^/api': '/api'
        }
      }
    },
  },
});

mac os 终端输入 ifconfig进行查看自己的本机地址

4. 使用route.go(-1),返回上一页并携带参数

请添加图片描述
地址选择这里,需要跳转到,地址页面,返回的时候携带参数,赋值给地址栏

创建 bus.js 文件,如下

// path/index.js,地址页面,回退到订单页,需要传递参数
// 声明一个空的Vue模块eventBus
import Vue from 'vue'
/** 
 * 定义空的vue实例,作为 eventbus实现非父子组件之间的通信(vue2.x中去掉了broadcast)
 */
var eventBus = new Vue({});
export default eventBus;

提交订单页面,先这样写,后面还有,往下看

order.js 提交订单页面
// 提交订单按钮
 <div class="order-topay" @click="goPayment">提交订单</div>
 // 引入bus.js文件
import eventBus from '@/components/common/bus'
 goPayment(){
     this.$router.push({
        path: '/mypath',
        query: {
          // 地址页面根据,传参判断从那个页面进入的
          type: 'select',
        },
      })
 }

地址管理页面
在这里插入图片描述
这里要进行,判断从那个页面来的,然后回退给他携带参数(提交订单需要参数)

  • 这里到goList 事件也用于,地址修改,我相信写过的人。
  • 应该知道(点击修改传递进去的参数 就是 goList(option) 中option地址详细信息的数据
  • 而 回退路由 同样要将这些获取到的数据,传递给提交订单页面
// 导入eventBus,路由回退到订单页,需要携带参数过去
import eventBus from '@/components/common/bus'

export default{
    data(){
      return { 
         // 判断从那个页面来的
         pathStatus:false
      }
    },
    // 初始化渲染数据,这里进行判断
    create(){
        // 从订单页面进来的
       if (this.$route.query.type == 'select') {
                this.pathStatus = true
       }
    },
    // 跳转到新增地址页面
    goList(option) {
      if (option == 'select') {
        this.pathStatus = false
      }
      // pathStatus如果为true,代表从订单页进入的
      if (this.pathStatus) {
        // selectPath传递到名字,option传递的参数(这里是收货地址,点击那个,传递那个,类似修改地址),
        eventBus.$emit('selectPath', JSON.stringify(option))
        this.$router.go(-1)
        return
      }
    },
  },
}

这样回退回去的时候,就携带上参数了,但是在提交订单页面,如果直接进行接收是无法接受到的,这里如下解决使用到 keep-alive

这时改进上面,提交订单页面代码

order.js 提交订单页面
// 提交订单按钮
 <div class="order-topay" @click="goPayment">提交订单</div>
 // 引入bus.js文件
import eventBus from '@/components/common/bus'
  // keep-alive缓存组件,生命周期
  activated() {
    // 需要在当前router路由页面加入meta: {keepAlive: true // 此组件需要缓存},
    eventBus.$on(
      'selectPath',
      function (data) {
        this.path = JSON.parse(data)
        console.log(this.path, '里面的')
      }.bind(this)
    )
    console.log(this.path, '外面的')
  },
    methods:{
       goPayment(){
            this.$router.push({
                  path: '/mypath',
                  query: {
                     // 地址页面根据,传参判断从那个页面进入的
                     type: 'select',
                  },
             })
       }
 }

详细的大家,搜一下b站小鹿线的,vue2茶城移动端项目,确实不错,有短信,有支付,我就是抄的

猜你喜欢

转载自blog.csdn.net/weixin_46426412/article/details/129422402