vue_travel项目知识整理

vue stylus 安装

$ npm install stylus --save
$ npm install stylus-loader --save
Stylus是一个CSS预处理器。那么在SaaS,Less和Stylus中,为什么选择后者呢?
因为Stylus是来源于Node.js社区,与js关系密切,所以基于Vue.js的开发,我们选择使用Stylus。
[详情查看](https://stylus.bootcss.com/)

vue 全局引入外部css文件

main.js 使用 import 导入外部css文件
import './assets/styles/reset.css'

vue css使用

组件内部css中引入其他css时,import需要加上@,路径需要加上~, 
  - @import '~../../../assest/styles/reset.css'
css样式穿透, scoped只修饰当前组件,使用插件渲染的组件需要使用样式穿透 >>> 

vue iconfont使用

// 下载iconfont项目,将字体文件以及css样式拷贝到项目中
// 引入全局iconfont样式,main.js下
import '@/assets/styles/iconfont.css'
// 组件内使用iconfont,标签必须添加iconfont样式,还有相对应图标的样式
<i class="iconfont iconhanhui"></i>

vue 路径优化之resolve的使用

// 当子组件引用一些公共组件或其他样式时,通常都会一长串的路径
import CommonGallery from '../../../common/gallery/Gallery'
@import '~../../../assets/styles/variables.styl'
这时配置build/webpack.bas.conf.js,resolve配置项alias属性
resolve: {
  // 表示引用组件是可以省略后缀名
  extensions: ['.js', '.vue', '.json'],
  alias: {
    'vue$': 'vue/dist/vue.esm.js',
    '@': resolve('src'),
    '$styles': resolve('src/assets/styles'),
    '$common': resolve('src/common')
  }
},
配置后就可以使用“别名”来引用相关组件
import CommonComponent from '$common/gallery/Gallery'
@import '~$styles/variables.styl'
// 这是webpack打包工具提供的方法

vue 移动端点击300毫秒延迟

fastclick常用于消除移动端点击事件触发的300ms延迟
// fastclick 安装使用
$ npm install fastclick --save
// main.js调用方法
import fastClickAttach from 'fastclick'
fastClickAttach.attach(document.body)

vue 使用 vue-awesome-swiper

// 安装:$ npm install swiper vue-awesome-swiper --save // => 基于swiper封装所以也要安装swiper插件
// 详情https://www.npmjs.com/package/vue-awesome-swiper
// vue-awesome-swiper基于swiper,[详情配置查看](https://www.swiper.com.cn/api/index.html)
// vue全局引用vue-awesome-swiper, main.js下:
import Vue from 'vue'
import VueAwesomeSwiper from 'vue-awesome-swiper'
// 引入swiper样式
import 'swiper/css/swiper.css'
Vue.use(VueAwesomeSwiper, /* { default options with global component } */)
// 组件结构
<template>
  <swiper :options="swiperOptions">
    <swiper-slide>
      <img />
      .....
    </swiper-slide>
    <div class="swiper-pagination" slot="pagination"></div>
    <div class="swiper-button-prev"></div>
    <div class="swiper-button-next"></div>
    .....
  </swiper>
</template>
<script>
  export default {
    data () {
      return {
        // swiper组件的常用配置项
        swiperOptions: {
          // 设置初始化显示下标为2的slide,默认值0
          initialSlide: 2,
          // Slides的滑动方向,可设置水平(horizontal)或垂直(vertical),默认水平
          direction : 'vertical',
          // 切换速度,即slider自动滑动开始到结束的时间(单位ms),默认300
          speed: 300,
          // 设置为true 则开启loop模式,默认false
          // 会在原本slide前后复制若干个slide(默认一个)并在合适的时候切换,让Swiper看起来是循环的
          loop: true,
          // 启动动态检查器(OB/观众/观看者),当改变swiper的样式(例如隐藏/显示)或者修改swiper的子元素时,自动初始化swiper,默认false
          observer: true
          // 将observe应用于Swiper的父元素。当Swiper的父元素变化时,例如window.resize,Swiper更新。默认false
          observeParents: true,
          // 设置为true启动自动切换,并使用默认的切换设置。默认false
          autoplay: true,
          // 自动切换的时间间隔,单位ms
          autoplay: {
            delay: 1000, // 1秒切换一次, 存在此属性默认表示自动切换,和autopalay:true二选一
          },
          // pagination,使用分页器导航。分页器可使用小圆点样式(默认)、分式样式或进度条样式。
          pagination: {
            el: '.swiper-pagination', // 选择分页器的元素
            type: 'bullets',  // ‘bullets’  圆点(默认)‘fraction’  分式 ‘progressbar’  进度条‘custom’ 自定义
          },
          // 使用前进后退按钮来控制Swiper切换。
          navigation: {
            nextEl: '.swiper-button-next', // 选择前进按钮的元素
            prevEl: '.swiper-button-prev', // 选择后退按钮的元素
          },
        }
      }
    }
  }
</script>

vue 移动端+swiper多页图标渲染

一些app都有可以滑动的图标区域,假如一页只能显示8个图标,现在获取到数据一共有10个或多条数据
怎么渲染出根据数据来渲染几页的图标呢,核心思想就是一个二维数组
// 模拟获取到的图标数据
cosnt iconArr = ['icon1', 'icon2', 'icon3', 'icon4', 'icon5', 'icon6', 'icon7', 'icon8', 'icon9', 'icon10']
// 创建一个空数组,用来存储当前是第几页的图标
let pages = []
iconArr.forEach((item, index) => {      // 遍历数据
   const page = Math.floor(index / 8)   // 表示一页只能显示8个图标
   if (!pages[page]) pages[page] = []   // 如果当前这一页不存在的话,就创建当前页
   pages[page].push(item)               // 最后把当前页的数据添加在当前页
})
return pages
// vue组件渲染
<template>
  <swiper :options="swiperOptions" v-for="(page, index) of pages">
    <swiper-slide v-for="(item, index) of page">
      <span class="swiper-icon">{{ item }}</span>
    </swiper-slide>
    <div class="swiper-pagination" slot="pagination"></div>.
  </swiper>
</template>

vue 路由模式

vue-router 默认hash模式——使用URL的hash来模拟一个完整的URL,于是当URL改变时,页面不会重新加载。
hash模式会自动在url地址末尾加上#/
如果不想要很丑的hash,我们可以用路由的history模式,这种模式充分利用history.pushStateAPI来完成URL跳转而无须重新加载页面。
history模式打包问题,........

vue 路由配置 scrollBehavior, 只有history模式下才有用

使用前端路由,当切换到新路由时,想要页面滚到顶部,或者是保持原先的滚动位置,就像重新加载页面那样。
当创建一个 Router 实例,你可以提供一个 scrollBehavior 方法:
// router/index.js
scrollBehavior (to, from, savedPosition) {
  return { x: 0, y: 0 } // 表示路由跳转一个新页面时,页面第一次加载滚动条的为是x坐标0,y坐标0
}

vue 函数节流 提高性能

防抖和节流的目的都是为了减少不必要的计算,不浪费资源,只在适合的时候再进行触发计算。
1. 函数防抖
- 在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时;
  典型的案例就是输入搜索:输入结束后n秒才进行搜索请求,n秒内又输入的内容,就重新计时。
- 实现原理, 基本思想就是设置一个定时器,在指定时间内执行代码清楚上一次的计时器,并设置另一个定时器,直到函数请求停止并超过时间间隔
- 使用场景, 文本框输入搜索(连续输入避免多次请求接口)
- 大致代码实现:
export default {
  dadta() {
    return {
      timer: ''
    }
  },
  watch: {
    inputValue () {
      if (this.timer) clearTimeout(this.timer)
      this.setTimeout(()=> {
        axios.get('/getData', { params:{ inputValue: this.inputValue } })
        .......
      }, 100)
    }
  }
}
2. 函数节流
- 规定在一个单位时间内,只能触发一次函数,如果这个单位时间内触发多次函数,只有一次生效; 
  典型的案例就是鼠标不断点击触发,规定在n秒内多次点击只有一次生效
- 实现原理, 用时间戳来判断是否到了回调执行,记录上次的时间戳,每次mousemove时间执行回调,
  回调中判断当前时间戳到上次时间戳是否达到在规定时间段,如果是,执行回调函数,并更新时间戳
- 使用场景, resize,scroll,mousemove,touchmove,
- 代码大致实现:
export default {
  data () {
    return {
      timer: '',
      lastTime: ''
    }
  },
  methods: {
    // 假设移动触发了函数
    handleMousemove () {
      const nowTime = Date.now()
      const delay = 200
      if (this.lastTime && (nowTime - this.lastTime) <= delay) {
        if(this.timer) clearTimeout(this.timer)
        this.timer = setTimeout(() => {
          this.lastTime = nowTime
          this.handleMove()
        }, delay)
      }else {
        this.lastTime = nowTime
        this.handleMove() // 第一次无需延时
      }
    },
    handleMove () {
      .......
    }
  }
}

vue better-scroll的使用

- better-scroll是解决移动端滚动的一种方案,核心是基于iscroll实现,还扩展了某些功能
- better-scroll是通过纯javascript实现的,意味着没有依赖项,是一个轻量级的javascript库
- install
  $ npm install better-scroll --save
- template结构,better-scroll应用于外部的warpper容器,滚动部分是content
  // 请注意:better-scroll指挥处理wrapper的第一个子元素(content),其他元素被忽略
  <template>
    <div class="wrapper" ref="wrapper">
    	<ul class="content">
    		<li>...</li>
    		<li>...</li>
    		<li>...</li>
    	</ul>
      // 放置一些其他内容,不会影响滚动  
    </div>
  </template>
- vue 组件中使用
  import BScroll from 'better-scroll'
  mounted () {
    this.scroll = new BScroll(this.refs.wrapper, { click: true }) // 参数接收一个DOM元素, 第二个参数为配置想,click: true,表示包裹的元素可以被点击
  }
- 滚动的原理
  .wrapper容器,设置其高度固定,.content是父容器的第一个子元素,其高度随其内容的大小而增加
  当内容的高度不超过父容器的高度时,内容将不会滚动,一旦超过,就可以滚动内容

vue better-scroll模拟app选择城市页面

当手指在右边字母表中移动时,页面内容滑动到相对应的字母开头的城市
better-scroll提供一个原型上的方法: this.scroll.scrollToElement(el,time,offsetX,offsetY,easing)
el: 目标DOM元素。如果值是一个字符串,底层使用queryelector获取元素
time: 滚动到对应元素需要的动画时间, 单位毫秒
offsetX: x到目标元素的偏移量,如果值为true,则滚动到目标元素的中心。
offsetY: y到目标元素的偏移量,如果值为true,则滚动到目标元素的中心。
easing:  动画过渡的速度,linear,slow.....
this.scroll.scrollToElement(this.refs['A'])
[更多配置信息查看](https://better-scroll.github.io/docs/en-US/guide/base-scroll-api.html#properties)

vue touchEvent事件

touchstart  // 手指长按
touchmove   // 手指移动
touchend    // 手指松开
touchEvent.touches事件是一个touchList集合,使用下标[0] 可以获取手指到浏览器距离等信息

vue 列表渲染ref绑定返回一个数组

当列表渲染组件时绑定ref时,ref的时候返回的是一个数组
const data = ['one', 'two', 'three']
<ul>
  <li v-for="item in data" :ref="item">item</li>
</ul>
this.$refs.one // 返回的是一个数组, this.$refs.one[0]就能获取到相对应的DOM元素

vue 本地存储sessionStorage和localStorage

对浏览器来说,使用 Web Storage 存储键值对比存储 Cookie 方式更直观,而且容量更大,
它包含两种:localStorage 和 sessionStorage
  - sessionStorage(临时存储) :为每一个数据源维持一个存储区域,在浏览器打开期间存在,包括页面重新加载
  - localStorage(长期存储) :与 sessionStorage 一样,但是浏览器关闭后,数据依然会一直存在
// 使用方法
sessionStorage 和 localStorage 的用法基本一致,引用类型的值要转换成JSON
const info = { name: 'hou', age: 24, id: '001' }
const str ='hehe'
// 保存
sessionStorage.say = str
localStorage.setItem('say', JSON.stringify(info))
// 读取
sessionStorage.say // => hehe
localStorage.getItem('say')
// 删除
sessionStorage.removeItem('say') // 删除某个
localStorage.clear() // 删除全部

// 注意点
- localStorage有效期是永久的。一般的浏览器能存储的是5MB左右。sessionStorage api与localStorage相同。
- sessionStorage默认的有效期是浏览器的会话时间(也就是说标签页关闭后就消失了)。
- localStorage作用域是协议、主机名、端口。(理论上,不人为的删除,一直存在设备中)
- sessionStorage作用域是窗口、协议、主机名、端口。
- localStoragewindow上的。所以不需要写this.localStorage,vue中如果写this,是指vue实例。会报错

vue keep-alive 组件

<keep-alive> 包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。主要用于保留组件状态或避免重新渲染。
是一个抽象组件:它自身不会渲染一个 DOM 元素,也不会出现在组件的父组件链中
当组件在 <keep-alive> 内被切换,它的 activated 和 deactivated 这两个生命周期钩子函数将会被对应执行。
// 组件(标签)特性
  - include - 字符串或正则表达式。只有名称匹配的组件会被缓存。
  - exclude - 字符串或正则表达式。只有名称匹配的组件都不会被缓存。
  - max - 数字。最多可以缓存多少组件实例。
// include 和 exclude 属性允许组件有条件地缓存。二者都可以用逗号分隔字符串、正则表达式或一个数组来表示:
<keep-alive include="a, b"></keep-alive>
<keep-alive include="/a|b/"></keep-alive>
<keep-alive include="['a', 'b']"></keep-alive>
// 匹配首先检查组件自身的 name 选项,如果 name 选项不可用,则匹配它的局部注册名称 (父组件 components 选项的键值)。匿名组件不能被匹配
// max 最多可以缓存多少组件实例。一旦这个数字达到了,在新实例被创建之前,已缓存组件中最久没有被访问的实例会被销毁掉

// <keep-alive> 是用在其一个直属的子组件被开关的情形,<keep-alive> 要求同时只有一个子元素被渲染。

vue 递归组件

组件是可以在它们自己的模板中调用自身的。不过它们只能通过 name 选项来做这件事
实现一个城市多级选择组件,加入有以下城市数据
const data = [{
  "code": "500000",
  "name": "重庆市",
  "list": [{
    "code": "500000",
    "name": "重庆市",
    "list": [{
      "code": "500101",
      "name": "沙坪坝区",
      "list": [{
        "code": "....",
        "name": "西永"
      }, {
        "code": "....",
        "name": "大学城"
      }]
    },{
      "code": "500102",
      "name": "九龙坡区"
    }]
  }]
}]
// city.vue
<template>
  <div class="wrapper">
    <div class="city" v-for="(item, index) of cities" :key="index">
      <div class="cityName">{{ item.name }}</div>
      <div v-if="item.list">
        <city :cities="item.list"></city>
      </div>
    </div>
    
  </div>
</template>
<sciprt>
  export default {
    name: 'city',
    props: {
      cities: Array
    },
  }
</sciprt>

vue 组件中export default的name属性作用

1. 在keep-alive组件中匹配
2. 递归组件时可以调用自身
3. 在页面使用dev-tools工具可以查看组件的名字就是name属性的值

vue 手机调试

babel-polyfill包,手机白屏(是手机不支持promise)
在手机端浏览, package.json/script/dev后面加上 --host 0.0.0.0
"dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js --host 0.0.0.0",

打包上线

$ npm run build // => 会生成一个dist文件夹,给到后端
如果希望打包生成的文件最后在后端一个project目录运行代码
// config/index.js
assetsPublicPath: '/project'
posted @   前端之旅  阅读(409)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
点击右上角即可分享
微信分享提示