node+vue的喵喵商城项目(一)

1.node后台服务器

2.vue构建前后端页面,vuex,vue-cli辅助使用

关于git多人协同开发项目:master分支不动,创建develop分支,在develop创建新的具体事项分支,然后merge到develop分支。

vue create m-miaomiao

git remote -v 查看仓库地址

git remote add origin https://gitee.com/lcglcglcg/m-miaomiao.git

关于 git pull 的使用注意:

git pull --rebase origin master 将远端代码拉取并合并到本地,同文件名远端覆盖

git checkout -b develop

git checkout -b createComponents

git add .

git commit -m 'createcomponents'

git checkout develop

git merge createComponents --no-ff  (加--no-ff的目的是把merge记录加入.git的log中,方便以后查看)

git log 查看日志

git push origin develop

git branch -d createComponents

目录的public 和 assets区别

assets:资源最终会打包到模块中,图片常转base64 存放

vuetr 插件  sca 自动生成页面模板

防止项目过大路由繁杂可以这样处理

 

 关于路由中样式路由随着的切换:

在vue中有 .router-link-active 给指定的router-link 元素加上 eg: #footer ul li.router-link-active{ color: #f03d37;} 。

关于路由的任意未定义字符匹配指定页面:

{ path: '/*', redirect: '/movie' }

 构建页面子路由时 path 可以加'/'代表完整地址,不加代表'当前页面path/子路由。

vue add xxx eg:axios 可以增加vue-cli内置好的模块

axios前端跨域处理

根目录新建 vue.config.js 

添加

module.exports = {
  devServer: {
    proxy: 'http://192.168.0.1:4000',
  ws:true
  changeOrigin: true
} }

 关于处理页面局部滚动问题:

确保有滚动主元素,才能设置其的scrollTop值,(ps:也可以用滚动元素的 scrollTo()方法)

 this.$refs.scroll.scrollTo(0,this.$refs[index][0].offsetTop) //此方式类似于利用a标签的锚点方式

其中:绑定动态:ref元素需要使用this.$refs[index][0]才能访问到。具体关于offsetTop不同浏览器的规定可以查询

(ps: 不使用js原生方式获取元素主要是和vue的设计理念不同)

最简单的做法是利用 <a herf="#">的锚点绑定效果 给元素绑定动态id 利用锚点定位位置。

定义全局过滤器解决图片地址需要自己设置宽高问题

// 定义全局过滤器
Vue.filter('setWH', (url, arg)=>{
  return url.replace(/w\.h/, arg)
})

(ps:对于这时图片可能出现的失帧问题:是setWH(‘arg)填写错误导致后台地址判断识别为最小图片导致,arg是字符串类型  需加引号。)

关于使用watch computed的区别

compueted:计算属性不适合炒作需要发送axios异步请求的数据,适合逻辑计算。

watch:可以监听数据的改变发送异步请求

注意,在写任何axios请求的时候 必须先加async await;

vue-axios防止数据多次请求的方法

<script>
import axios from 'axios'
export default {
  data() {
    return {
      message: '',
      movieList: [],
    }
  },
  methods: {
    cancelRequest(){
      if(typeof this.source ==='function'){
          this.source('终止请求')
      }
    }
  },
  watch: {
    async message(newVal) {
      let that = this
      this.cancelRequest()
      await this.$axios.get(`api/searchList?cityId=10&kw=${newVal}`,{
        cancelToken: new axios.CancelToken(c => {
          that.source = c
        })
      }).then(res=> {
        this.movieList = res.data.data.movies.list
      }).catch((err) => {
        if (axios.isCancel(err)) {
          console.log('Request canceled', err.message);
        } else {
          console.log(err)
        }
      })
      // this.$axios.get(`api/searchList?cityId=10&kw=${newVal}`,{
      //   cancelToken: new axios.CancelToken(function(c){
      //     that.source = c
      //   })
      // }).then(res=> {
      //   this.movieList = res.data.data.movies.list
      // })
      // .catch((err) => {
      //   if (axios.isCancel(err)) {
      //     console.log('Request canceled', err.message);
      //   } else {
      //     console.log(err)
      //   }
      // })
      
    }
  }
}
</script>

 

说明:这里的axios最初写的是 this.$axios 但始终报错 this.$axios.CancelToken is not construct 无奈只好 再次引入了一次 axios 才成功,不知是否是在安装axios时采用了  vue add axios 导致的?

 

vue-axios同时执行多个请求

axios.all([
 
    axios.get('https://api.github.com/xxx/1'),
 
    axios.get('https://api.github.com/xxx/2')
 
  ])
 
  .then(axios.spread(function (userResp, reposResp) {
 
    // 上面两个请求都完成后,才执行这个回调方法
 
    console.log('User', userResp.data);
 
    console.log('Repositories', reposResp.data);
 
  }));

当所有的请求都完成后,会收到一个数组,包含着响应对象,其中的顺序和请求发送的顺序相同,可以使用 axios.spread 分割成多个单独的响应对象

 scroll组件的封装:props属性既可以接收值类型的传递,也可以接受方法的传递

<template>
  <div class="wrapper" ref="wrapper">
    <slot></slot>
  </div>
</template>

<script>
import Bscroll from 'better-scroll'
export default {
  props: {
    handleToScroll: {type: Function, default: function(){}},
    handleToTouchEnd: {type: Function, default: function(){}},
  },
  mounted() {
    let scroll = new Bscroll(this.$refs.wrapper, {
      tap: true,
      probeType: 1
    })
  this.scroll = scroll scroll.on(
'scroll', (pos) => { this.handleToScroll(pos) }) scroll.on('touchEnd', pos => { this.handleToTouchEnd(pos) }) },
methods: {
  handleScrollTo(y){
    this.scroll.scrollTo(0, y)
  }
 }
}
</script> <style scoped> .wrapper { height: 100%; } </style>

 对于固定不变的资源没有必要请求多次,可以添加到window.localStorage.setItem()里面。例如城市数据的请求。

 

async fetch() {
      let cities = window.localStorage.getItem('cities')
      let hotCities = window.localStorage.getItem('hotCities')
      if(cities && hotCities){
        this.cities = JSON.parse(cities)
        this.hotCities = JSON.parse(hotCities)
        this.isLoading = false
      }else {
        const res = await this.$axios.get('api/cityList')
        if(res.data.msg === 'ok') {
          this.isLoading = false
          let cities = res.data.data.cities
          // [{index: 'B', list:[{id: 1, nm: "北京", isHot: 1, py: "beijing"}]}]
          const {cityList, hotList} = this.formatCityList(cities)
          this.cities = cityList
          this.hotCities = hotList
          window.localStorage.setItem('cities', JSON.stringify(this.cities))
          window.localStorage.setItem('hotCities', JSON.stringify(this.hotCities))
        }
      }
    },

关于better-scroll:

使用 npm i better-scroll@next -S 安装2版本会出现tap事件无效的问题,移动适配不佳的问题。npm i better-scroll -S 安装1版本则没有出现类似问题

网上查询better-scroll的问题:

点击事件无效:添加参数设置,参考官方文档https://ustbhuangyi.github.io/better-scroll/doc/zh-hans/options.html#click

pc端出现点击一次多次触发:在pc端添加 scroll的destroy()事件:销毁 better-scroll,解绑事件

 

关于出现一个组件内需要渲染多个router-view 的情况 可以采用vue的命名视图解决

 // 路由端
   {
      path: 'detail',
      components: {
        detail: ()=> import ('@/components/movie/Detail')
      }
    },

  //  页面端
    <router-view name="detail"></router-view>

  //具体参考vue官网

而通过命名视图的方式解决跳转问题则需要如下操作

 

  路由端
  { path:
'detail/:movieId', components: { detail: ()=> import ('@/components/movie/Detail') }, props: { detail: true } },

页面端
  props: {
   movieId: {required: true}
  },
也可以写成: props:['movieId']

 

关于detail页面在渲染时,我试着通过路由加props:true参数来解决接收传入的id的问题

routes: [
    movieRouter,cinemaRouter,mineRouter,
    {path: '/', redirect: '/movie'},
    {
      path: '/detail/:movieId',
      component: ()=> import ('@/components/movie/Detail'),
      props: true
    }, 
  ]

然后将movie中的nowing页面的h2标签改写为router-link,但页面跳转不了,尝试过a标签,发现也不能跳转,再次在非scroll组件标签内加router-link发现可以跳转,在尝试在其他的自定义组件header中加入router-link也可以点击

得出:scroll组件会使router-link,a标签失效。

所以只好通过scroll的tap事件来跳转路由 this.$router.push(`/detail/${movieId}`)

 

再由nowing页面切换到detail页面的时候 ,由于命名视图只渲染命名的<router-view name="detail" /> ,加上屏幕之间的滑动动画效果,会出现nowing页面默认的<router-view/>没有渲染出现空白,导致不好的交互体验。

解决方法:

    {
      path: 'nowing/detail/:movieId',
      components: {
        default: () => import('@/components/movie/Nowing'),
        detail: ()=> import ('@/components/movie/Detail')
      },
      props: { detail: true }
    },
    {
      path: 'comming/detail/:movieId',
      components: {
        default: () => import('@/components/movie/Comming'),
        detail: ()=> import ('@/components/movie/Detail')
      },
      props: { detail: true }
    },

ps:如果存在很多个页面的指向问题,这样的做法是否存在优化方案?(待解决)

swiper组件缩略图的写法待掌握 eg:http://bbs.swiper.com.cn/forum.php?mod=viewthread&tid=24338

添加动态背景图:

:style="{ 'background-image': 'url('+ detailMovie.videoImg.replace(/w\.h/, '148.208') +')'}"
filter:blur(5px); 调整元素的模糊度
 
一个‘/’的差别,在页面数据的获取中,由于之前看过其他的视频教程在前端页面获取数据this.$axios.get(‘api/xxx’)和这样写this.$axios.get('/api/xxx')都能请求获得数据,故以为两者是一样的,所以在这个项目中一直采取的前一种写法,
但在这个项目中将原本路由的hash模式改成history模式时,在路由中加了
export default new Router({
  mode: 'history',
  base: 'miaomiao',
  routes: [
    movieRouter,cinemaRouter,mineRouter,
    {path: '/', redirect: '/movie'},
  ]
})

在vue.config.js中写入

module.exports = {
  publicPath: '/miaomiao/',
  devServer: {
    proxy: {
      '/api': {
        target: 'http://39.97.33.178',
        changeOrigin: true
      },
    }
  }
}

多次不同更改打包出错,最后发现是‘/’的锅,虽然没有找到两者的区别以及问题的关键所在,但赤裸裸时间的教训一定要写‘/’。(暂猜测原因:不跨域请求数据,应该都一样的,一但跨域,一定加‘/’)。

在没有加‘/’,路由是hash模式的时候,直接打包,不能设置根目录文件夹base,放在niginx html 根目录下能成功。

niginx.conf配置如下

location /miaomiao/ {
            root  html;
            index  index.html index.htm;
            try_files $uri $uri/ /miaomiao/index.html;
        }

        location /api/ {
            proxy_set_header x-Real-IP $remote_addr;
            proxy_pass http://39.97.33.178/api/;  //上面是niginx代理重定向到真实服务器的地址
            proxy_redirect off;  //下面这部分是取消重定向,获取用户的信息定位用户的所在地。
            proxy_set_header X-Forwarded_For $proxy_add_x_forwarded_for;
            proxy_set_header Host $http_host;
            proxy_set_header X-Niginx-Proxy true;
        }

 在服务器端采用niginx负载均衡和反向代理,用pm2做服务器的后台进程管理。

转载于:https://www.cnblogs.com/lcglcglcglcglcg/p/11143579.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值