美文网首页
Vue2.5 去哪儿网App实战项目开发知识梳理

Vue2.5 去哪儿网App实战项目开发知识梳理

作者: 极简博客 | 来源:发表于2022-07-08 14:57 被阅读0次

    简介

    本文是作者通过学习 慕课网 Vue 2.5 去哪儿网课程的总结。由于在下才疏学浅,可能有很多不足之处,欢迎指正。

    一、移动端ios出现click事件300ms延迟。

    1.1 引入fastclick插件

    npm install fastclick --save
    

    1.2 在main.js文件中引入并使用

    import fastClick from 'fastclick'
    
    fastClick.attach(document.body)
    

    二、stylus(富于表现力、动态的、健壮的 CSS) 的使用

    2.1 使用

    <style lang="stylus" scoped>
        @import '~styles/varibles.styl'
        .parent
          position relative
          .child
            position absolute
            background $bgColor
    </style>
    

    2.2 解析

    • 通过缩进控制上下层关系
    • 通过@import引入全局变量,使用$bgColor调用
    • lang="stylus" 表明为stylus, scoped 指定仅在当前文件使用
    • stylus学习网址

    三、iconfont 图标使用

    3.1 创建图标项目,添加文件到开发项目中

    • 将喜欢的图标加入购物车,然后添加至项目,下载到本地即可

    • 将压缩文件解压,在src/assets/styles/ 文件夹中导入以下四个文件

      iconfont.eot、iconfont.svg、iconfont.ttf、iconfont.woff

    • 在 src/assets/ 中导入iconfont.css,并将url修改为本地路径

    • 在main.js中引入 import 'styles/iconfont.css'

    3.2 在代码中的使用

    <span class="iconfont">&#xe632;</span>
    

    四、@表示的意思

    4.1 注意

    @默认表示src所在路径,在<style ></style>中使用需要加~@修饰

    4.2 例子

    import Home from '@/pages/home/Home'
    
    <style lang="stylus" scoped>
      @import '~styles/varibles.styl'
    </style>
    

    4.3 拓展

    // 通过修改webpack.base.conf.js 可以自定义变量解析路径,参照@
    resolve: {
        extensions: ['.js', '.vue', '.json'],
        alias: {
          'vue$': 'vue/dist/vue.esm.js',
          '@': resolve('src'),
          'styles': resolve('src/assets/styles'),
          'common': resolve('src/common'),
        }
      }
    

    五、vue-awesome-swiper轮播插件

    5.1 引入

    // 下载插件
    npm install --save vue-awesome-swiper@2.6.7
    // 在项目main.js中全局引入
    import VueAwesomeSwiper from 'vue-awesome-swiper'
    import "swiper/dist/css/swiper.css"
    Vue.use(VueAwesomeSwiper)
    

    5.2 使用

    <template>
      <div class="wrapper">
        <swiper ref="mySwiper" :options="swiperOption" v-if="showSwiper">
          <swiper-slide v-for="item of list" :key="item.id">
            <img class="swiper-image" :src="item.imgUrl" />
          </swiper-slide>
          <div class="swiper-pagination" slot="pagination"></div>
        </swiper>
      </div>
    </template>
    
    <script>
    export default {
      name: 'HomeSwiper',
      props: {
        list: Array
      },
      data () {
        return {
          swiperOption: {
            pagination: '.swiper-pagination',
            loop: true,
            // 以下两个元素为父类元素DOM发生变化时自定刷新swiper
            observeParents: true,
            observer: true
          }
        }
      },
      computed: {
        showSwiper () {
          return this.list.length
        }
      }
    }
    </script>
    

    5.3 存在页面加载抖动问题

    • 5.3.1 分析原因

      由于网络延迟,而图片加载缓慢,导致图片挤压高度

    • 5.3.2 设置固定宽高比

      // 高度设置为0导致,padding-bottom会参照宽度去设置padding-bottom
      <style lang="stylus" scoped>
        .wrapper
            overflow hidden
            width 100%
            height 0
            padding-bottom 31.25%
      </style>
      
    • 5.3.3 拓展

      父元素display:flex布局,子元素flex:1;min-width:0,表示自适应父元素剩余的宽度,且不会超出父元素的宽度

    六、axios 实现跨平台请求(ajax)

    6.1 下载插件

    npm install axios --save
    

    6.2 使用

    import axios from 'axios'
    axios.get('/api/index.json', {
      params: {
        id: 1
      }
    })
    .then(function (response) {
      console.log(response);
    })
    .catch(function (error) {
      console.log(error);
    });
    

    6.3 自定义路径转发

    // config/index.js 修改配置使得/api路由为/static/mock
    proxyTable: {
     '/api': {
        target: 'http://127.0.0.1:8080',
        pathRewrite: {
            '^/api': '/static/mock'
        }
     }
    }
    

    6.4 拓展

    // 修改package.json 添加 --host 0.0.0.0 使得以ip访问,默认不能通过ip访问
    "scripts": {
        "dev": "webpack-dev-server --host 0.0.0.0 --inline --progress --config  build/webpack.dev.conf.js",
        "start": "npm run dev",
        "lint": "eslint --ext .js,.vue src",
        "build": "node build/build.js"
    }
    

    七、better-scroll滚动插件使用

    7.1 使用

    • 下载插件:npm install better-scroll --save
    • 引入better-scroll:import Bscroll from "better-scroll"
    • 定义标签dom: < div ref="myRef"></div>
    • 实例化bscroll: this.scroll=new Bscroll(this.$refs.div)即可;
    • Bscroll提供滚动到指定DOM位置的API,this.scroll.scrollToElement(this.$refs.myRef)

    7.2 注意

    • 默认它会阻止touch事件。所以在配置中需要加上click: true,否则@click会在移动端失效
    mounted(){
        this.scroll=new Bscroll(this.$refs.wrapper, { mouseWheel: true, click: true, tap: true })
    }
    
    • v-for 会导致this.$refs.myRef得到的结果为数组,获取单个Dom需要指定下标,如:[0]

    八、vuex

    8.1 使用场景

    • 如果您不打算开发大型单页应用,使用 Vuex 可能是繁琐冗余的。确实是如此——如果您的应用够简单,您最好不要使用 Vuex。一个简单的 global event bus 就足够您所需了。但是,如果您需要构建一个中大型单页应用,您很可能会考虑如何更好地在组件外部管理状态,Vuex 将会成为自然而然的选择

    8.2 下载插件

    • npm install vuex --save
    • 对于大型应用,我们会希望把 Vuex 相关代码分割到模块中。下面是项目结构示例:
    ├── index.html
    ├── main.js
    ├── api
    │   └── ... # 抽取出API请求
    ├── components
    │   ├── App.vue
    │   └── ...
    └── store
        ├── index.js          # 我们组装模块并导出 store 的地方
        ├── actions.js        # 根级别的 action
        ├── mutations.js      # 根级别的 mutation
        └── modules
            ├── cart.js       # 购物车模块
            └── products.js   # 产品模块
    
    • [图片上传失败...(image-42936e-1657263417528)]
    • 在main.js中引入
    import store from "./store"
    new Vue({
      el: '#app',
      router,
      store,
      components: { App },
      template: '<App/>'
    })
    
    • 使用
    import { mapState, mapMutations } from 'vuex'
    export default {
      name: 'CityList',
      props: {
        hot: Array,
        cities: Object,
        letter: String
      },
      computed: {
        ...mapState({
          currentCity: 'city'  // 获取modules中city赋值到属性currentCity
        })
      },
      methods: {
        handleCityClick (city) {
          // this.$store.commit('changeCity', city) 简化
          this.changeCity(city)
          this.$router.push('/')
        },
        ...mapMutations(['changeCity'])
      },
      watch: {
        // 监听letter变化 由于v-for修饰导致获取到数组所有增加[0]获取dom元素对象
        letter () {
          if (this.letter) {
            const element = this.$refs[this.letter][0]
            this.scroll.scrollToElement(element)
          }
        }
      },
      mounted () {
        this.scroll = new Bscroll(this.$refs.wrapper, {mouseWheel: true, click: true, tap: true})
      }
    }
    

    九、localStorage本地存储

    let defaultCity='重庆';  
    try{    
        //防止用户关闭缓存造成报错
        if(localStorage.city){
            defaultCity=localStorage.city
        }
    }catch(e){}
            
    export default new Vuex.Store({
        state:defaultCity,     //首页头部显示的城市,默认为localStorage.city或者重庆
    })
    

    十、keep-alive代码优化,将加载的页面存储到缓存中

    10.1 使用

    <!--App.vue 文件-->
    <template>
      <div id="app">
        <!-- 显示的是当前路由地址所对应的内容 keep-alive 将首次路由的内容加到内存中避免重复调用mounted -->
        <keep-alive exclude="Detail">
          <router-view/>
        </keep-alive>
      </div>
    </template>
    
    <script>
    export default {
      name: 'App'
    }
    </script>
    
    <style>
    
    </style>
    

    10.2 代码判断是否触发axios重新加载数据

    // 由于改变城市页面跟着变动,所以不能还是使用缓存中的数据,当页面重新显示时调用activated函数
    activated () {
        // 城市改变时重新渲染页面
        if (this.lastCity !== this.city) {
            this.lastCity = this.city
            this.getHomeInfo()
        }
    }
    

    十一、页面跳转

    11.1 router-link

    <!--tag使用避免了a标签改变了li表示内里的文字颜色,相当于<li></li>且自带跳转页面的功能-->
    <router-link
            tag="li"
            class="item border-bottom"
            v-for="item of list"
            :key="item.id"
            :to="'/detail/' + item.id"
          >
    </router-link>
    

    11.2 this.$router.push('/')

    this.$router.push('/')
    

    11.3 拓展

    // 获取url后的参数
    this.$route.params.id
    

    十二、滚动事件

    12.1 创建

    // 页面展示执行
    activated () {
        window.addEventListener('scroll', this.handleScroll)
    }
    

    12.2销毁

    // 页面隐藏或者被新页面替换执行 window为全局事件,创建之后需要有销毁,否则每个页面都会触发scroll事件
    deactivated () {
        window.removeEventListener('scroll', this.handleScroll)
    }
    

    12.3 跳转至其它页面,滚动条置顶

    // router/indx.js 文件
    export default new Router({
      routes: [
        {
          path: '/',
          name: 'Home',
          component: Home
        },
        {
          path: '/city',
          name: 'City',
          component: City
        },
        {
          path: '/detail/:id',
          name: 'Detail',
          component: Detail
        }
      ],
      // 切换页面重新定位到顶部
      scrollBehavior (to, from, savedPosition) {
        return {x: 0, y: 0}
      }
    })
    

    十三、拓展

    13.1 父子组件之间的传值

    // 父 > 子
    通过属性传值:父组件: :city="city" 子组件:props: { city: String }
    // 子 > 父
    通过事件触发:子组件:this.$emit('change', params) 父组件:@change="handleLetterChange"
    

    13.2 兄弟组件传值

    兄弟1->父组件->兄弟2
    

    13.3 其它组件

    使用 vuex | localStorage
    

    13.4 安装淘宝镜像

    npm install -g cnpm --registry=https://registry.npm.taobao.org
    

    13.5 Vue生命周期图示

    vue生命周期.jpg

    相关文章

      网友评论

          本文标题:Vue2.5 去哪儿网App实战项目开发知识梳理

          本文链接:https://www.haomeiwen.com/subject/dulvbrtx.html