小白学习vue笔记

一安装Vue

//全局安装 vue-cli
npm install --global vue-cli
//创建一个基于 webpack 模板的新项目
vue init webpack my-project
//安装依赖
cd my-project
npm install
//运行
npm run dev
  • 安装过程中的问题解决
  • npm构建保存 code ELIFECYCLE解决办法
进入工作目录
rm -rf node_modules
rm -rf package-lock.json
npm cache clear --force
npm install

二 做移动端应用注意

2.1 在index.html中修改mate设置

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

2.2 reset.css重新设置样式,在入口文件中引入

@charset "utf-8";html{background-color:#fff;color:#000;font-size:12px}
body,ul,ol,dl,dd,h1,h2,h3,h4,h5,h6,figure,form,fieldset,legend,input,textarea,button,p,blockquote,th,td,pre,xmp{margin:0;padding:0}
body,input,textarea,button,select,pre,xmp,tt,code,kbd,samp{line-height:1.5;font-family:tahoma,arial,"Hiragino Sans GB",simsun,sans-serif}
h1,h2,h3,h4,h5,h6,small,big,input,textarea,button,select{font-size:100%}
h1,h2,h3,h4,h5,h6{font-family:tahoma,arial,"Hiragino Sans GB","微软雅黑",simsun,sans-serif}
h1,h2,h3,h4,h5,h6,b,strong{font-weight:normal}
address,cite,dfn,em,i,optgroup,var{font-style:normal}
table{border-collapse:collapse;border-spacing:0;text-align:left}
caption,th{text-align:inherit}
ul,ol,menu{list-style:none}
fieldset,img{border:0}
img,object,input,textarea,button,select{vertical-align:middle}
article,aside,footer,header,section,nav,figure,figcaption,hgroup,details,menu{display:block}
audio,canvas,video{display:inline-block;*display:inline;*zoom:1}
blockquote:before,blockquote:after,q:before,q:after{content:"\0020"}
textarea{overflow:auto;resize:vertical}
input,textarea,button,select,a{outline:0 none;border: none;}
button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}
mark{background-color:transparent}
a,ins,s,u,del{text-decoration:none}
sup,sub{vertical-align:baseline}
html {overflow-x: hidden;height: 100%;font-size: 50px;-webkit-tap-highlight-color: transparent;}
body {font-family: Arial, "Microsoft Yahei", "Helvetica Neue", Helvetica, sans-serif;color: #333;font-size: .28em;line-height: 1;-webkit-text-size-adjust: none;}
hr {height: .02rem;margin: .1rem 0;border: medium none;border-top: .02rem solid #cacaca;}
a {color: #25a4bb;text-decoration: none;}

2.3 引入border.css 解决一像素边框的问题

在入口文件中引入

@charset "utf-8";
.border,
.border-top,
.border-right,
.border-bottom,
.border-left,
.border-topbottom,
.border-rightleft,
.border-topleft,
.border-rightbottom,
.border-topright,
.border-bottomleft {
    position: relative;
}
.border::before,
.border-top::before,
.border-right::before,
.border-bottom::before,
.border-left::before,
.border-topbottom::before,
.border-topbottom::after,
.border-rightleft::before,
.border-rightleft::after,
.border-topleft::before,
.border-topleft::after,
.border-rightbottom::before,
.border-rightbottom::after,
.border-topright::before,
.border-topright::after,
.border-bottomleft::before,
.border-bottomleft::after {
    content: "\0020";
    overflow: hidden;
    position: absolute;
}
/* border
 * 因,边框是由伪元素区域遮盖在父级
 * 故,子级若有交互,需要对子级设置
 * 定位 及 z轴
 */
.border::before {
    box-sizing: border-box;
    top: 0;
    left: 0;
    height: 100%;
    width: 100%;
    border: 1px solid #eaeaea;
    transform-origin: 0 0;
}
.border-top::before,
.border-bottom::before,
.border-topbottom::before,
.border-topbottom::after,
.border-topleft::before,
.border-rightbottom::after,
.border-topright::before,
.border-bottomleft::before {
    left: 0;
    width: 100%;
    height: 1px;
}
.border-right::before,
.border-left::before,
.border-rightleft::before,
.border-rightleft::after,
.border-topleft::after,
.border-rightbottom::before,
.border-topright::after,
.border-bottomleft::after {
    top: 0;
    width: 1px;
    height: 100%;
}
.border-top::before,
.border-topbottom::before,
.border-topleft::before,
.border-topright::before {
    border-top: 1px solid #eaeaea;
    transform-origin: 0 0;
}
.border-right::before,
.border-rightbottom::before,
.border-rightleft::before,
.border-topright::after {
    border-right: 1px solid #eaeaea;
    transform-origin: 100% 0;
}
.border-bottom::before,
.border-topbottom::after,
.border-rightbottom::after,
.border-bottomleft::before {
    border-bottom: 1px solid #eaeaea;
    transform-origin: 0 100%;
}
.border-left::before,
.border-topleft::after,
.border-rightleft::after,
.border-bottomleft::after {
    border-left: 1px solid #eaeaea;
    transform-origin: 0 0;
}
.border-top::before,
.border-topbottom::before,
.border-topleft::before,
.border-topright::before {
    top: 0;
}
.border-right::before,
.border-rightleft::after,
.border-rightbottom::before,
.border-topright::after {
    right: 0;
}
.border-bottom::before,
.border-topbottom::after,
.border-rightbottom::after,
.border-bottomleft::after {
    bottom: 0;
}
.border-left::before,
.border-rightleft::before,
.border-topleft::after,
.border-bottomleft::before {
    left: 0;
}
@media (max--moz-device-pixel-ratio: 1.49), (-webkit-max-device-pixel-ratio: 1.49), (max-device-pixel-ratio: 1.49), (max-resolution: 143dpi), (max-resolution: 1.49dppx) {
    /* 默认值,无需重置 */
}
@media (min--moz-device-pixel-ratio: 1.5) and (max--moz-device-pixel-ratio: 2.49), (-webkit-min-device-pixel-ratio: 1.5) and (-webkit-max-device-pixel-ratio: 2.49), (min-device-pixel-ratio: 1.5) and (max-device-pixel-ratio: 2.49), (min-resolution: 144dpi) and (max-resolution: 239dpi), (min-resolution: 1.5dppx) and (max-resolution: 2.49dppx) {
    .border::before {
        width: 200%;
        height: 200%;
        transform: scale(.5);
    }
    .border-top::before,
    .border-bottom::before,
    .border-topbottom::before,
    .border-topbottom::after,
    .border-topleft::before,
    .border-rightbottom::after,
    .border-topright::before,
    .border-bottomleft::before {
        transform: scaleY(.5);
    }
    .border-right::before,
    .border-left::before,
    .border-rightleft::before,
    .border-rightleft::after,
    .border-topleft::after,
    .border-rightbottom::before,
    .border-topright::after,
    .border-bottomleft::after {
        transform: scaleX(.5);
    }
}
@media (min--moz-device-pixel-ratio: 2.5), (-webkit-min-device-pixel-ratio: 2.5), (min-device-pixel-ratio: 2.5), (min-resolution: 240dpi), (min-resolution: 2.5dppx) {
    .border::before {
        width: 300%;
        height: 300%;
        transform: scale(.33333);
    }
    .border-top::before,
    .border-bottom::before,
    .border-topbottom::before,
    .border-topbottom::after,
    .border-topleft::before,
    .border-rightbottom::after,
    .border-topright::before,
    .border-bottomleft::before {
        transform: scaleY(.33333);
    }
    .border-right::before,
    .border-left::before,
    .border-rightleft::before,
    .border-rightleft::after,
    .border-topleft::after,
    .border-rightbottom::before,
    .border-topright::after,
    .border-bottomleft::after {
        transform: scaleX(.33333);
    }
}

修改里面边框颜色的方法可以在样式中这样写

.border-topbottom
    &:before
      border-color #cccccc
    &after
      border-color #cccccc
  .border-bottom
    &:before
      border-color #cccccc

2.4 解决click延迟300ms的问题 fastclick插件

引入fastclick
在项目目录下,在终端中写入 --save表示开发环境还是上线打包都需要,用–save

//表示将此插件安装到项目中
npm install fastclick --save

使用
在main.js中

//引入
import fastClick from 'fastclick'

//使用
fastClick.attach(document.body)

2.5 在style中引入其他样式,需要这样 ~@

@import '~@/assets/styles/varibles.styl';

2.6 对全局事件的解绑

//绑定,作用于全局,不用时一定要解绑
window.addEventListener('scroll', this.handleScroll)

//解绑
// 使用keep-alive后出现的方法,页面即将被影藏时会执行
deactivated() {
    window.removeEventListener('scroll', this.handleScroll)
}

2.7 解决么面滑动影响其他页面的问题

在路由里面添加这句就解决了

// 解决页面滑动影响其他页面效果的问题
  scrollBehavior (to, from, savedPosition) {
    return {x:0 ,y:0}
  }

3 插件使用

3.1 stylus和stylus-loader

可以快速帮助编写css代码

npm install stylus --save

3.2 轮播图组件 vue-awesome-swiper

官网地址:https://www.swiper.com.cn/
github地址:https://github.com/surmon-china/vue-awesome-swiper
安装:npm install vue-awesome-swiper@2.6.7 --save,使用2.6.7这个版本

//使用
import Vue from 'vue'
import VueAwesomeSwiper from 'vue-awesome-swiper'

// require styles
import 'swiper/dist/css/swiper.css'

Vue.use(VueAwesomeSwiper, /* { default global options } */)

3.2.1 使用vue代码

<template>
    <div class="wrapper">
        <swiper :options="swiperOption">
            <!-- slides -->
            <swiper-slide v-for="item of swiperList" :key="item.id" data-swiper-autoplay="1500">
                <img class="swiper-img" :src="item.imgUrl">
            </swiper-slide>
            <div class="swiper-pagination"  slot="pagination"></div>
        </swiper>
    </div>
</template>

<script>
export default {
  name: 'HomeSwiper',
  data () {
    return {
      swiperOption: {
        pagination: '.swiper-pagination',
        // 支持循环轮播
        loop: true,
        // 自动播放
        autoplay: true
      },
      swiperList: [{
        id: '0001',
        imgUrl: 'http://img1.qunarzz.com/piao/fusion/1609/b5/43a1ba885cbdd802.jpg_750x200_d70aa046.jpg'
      }, {
        id: '0002',
        imgUrl: 'http://img1.qunarzz.com/piao/fusion/1805/f2/503916bba911f502.jpg_750x200_b12d0184.jpg'
      }, {
        id: '0003',
        imgUrl: 'http://img1.qunarzz.com/piao/fusion/1809/fc/5e4ea3c336a86b02.jpg_750x200_62bf515a.jpg'
      }, {
        id: '0004',
        imgUrl: 'http://mp-piao-admincp.qunarzz.com/mp_piao_admin_mp_piao_admin/admin/20196/818f6cc784ae6669b74bbbb255414a53.jpg_750x200_66ca5873.jpg'
      }, {
        id: '0005',
        imgUrl: 'http://mp-piao-admincp.qunarzz.com/mp_piao_admin_mp_piao_admin/admin/20193/87a224d0349d94a11e97f31aa1aba4f5.jpg_750x200_1f78af87.jpg'
      }]
    }
  }
}
</script>

<style lang="stylus" scoped>
// 样式进行穿透
    .wrapper >>> .swiper-pagination-bullet-active
        background #ffffff
    .wrapper
        overflow hidden
        width 100%
        height 0
        padding-bottom 26.5%
        background #cccccc
        .swiper-img
            width 100%
</style>

3.2.2 swiper自定义图片轮播组件

<template>
  <div class="container" @click="handlerGallarlyClick">
    <div class="wrapper">
      <swiper :options="swiperOption">
        <!-- slides -->
        <swiper-slide v-for="(item, index) in imgs" :key="index">
          <img class="gallarly-img" :src="item">
        </swiper-slide>
        <div class="swiper-pagination"  slot="pagination"></div>
      </swiper>
    </div>
  </div>
</template>

<script>
export default {
  name: 'CommonGallary',
  props: {
    imgs: {
      type: Array,
      default () {
        return []
      }
    }
  },
  data () {
    return {
      swiperOption: {
        pagination: '.swiper-pagination',
        paginationType: 'fraction',
        // 组件有变化时,轮播会自动加载一遍
        observer:true,
        observeParents:true
      }
    }
  },
  methods: {
    handlerGallarlyClick () {
      this.$emit('close')
    }
  },
}
</script>

<style lang="stylus" scoped>
  .container >>> .swiper-container
    overflow inherit
  .container
    display flex
    flex-direction column
    justify-content center
    z-index 99
    position fixed
    left 0
    right 0
    top 0
    bottom 0
    background #000
    .wrapper
      width 100%
      height 0
      padding-bottom 100%
      .gallarly-img
        width 100%
      .swiper-pagination
        color #ffffff  
        bottom -1rem
</style>

3.3 数据请求 axios

1 安装

npm install axios --save

2 使用

//导入
import axios from 'axios'
//请求
axios.get('/api/index.json').then(this.getHomeInfoSucc)
//接收返回值的方法
getHomeInfoSucc (res) {
  console.log(res)
}

3 注意 配置地址代理
在 config - index.js里面这么配置

// 代理配置
proxyTable: {
  '/api': {
    target: 'http://localhost:8080',
    pathRewrite: {
      // 将API 替换为 /static/mock
      '^/api': '/static/mock'
    }
  }
},

3.4 页面跳转路由

1 路由配置

import Vue from 'vue'
import Router from 'vue-router'
import Home from '@/pages/home/Home'
import City from '@/pages/city/City'

Vue.use(Router)
// 导出去的内容   是一个路由
// 当用户访问根路径时,我给用户展示HelloWorld这个组件
export default new Router({
  // 路由配置
  routes: [
    {
      path: '/',
      name: 'Home',
      component: Home
    }, {
      path: '/city',
      name: 'City',
      component: City
    }
  ]
})

2 路由跳转

<router-link to="/city">
        <div class="header-right">
          {{ this.city }}
          <span class="iconfont arrow-icon">&#xe600;</span>
        </div>
      </router-link>

3 跳转 router

this.$router.push('/')

3.5 Better-scroll 滚动插件

github地址:https://github.com/ustbhuangyi/better-scroll
1 安装

npm install better-scroll --save

2 使用

//代码结构要符合要求

<div class="wrapper">
  <ul class="content">
    <li>...</li>
    <li>...</li>
    ...
  </ul>
  <!-- you can put some other DOMs here, it won't affect the scrolling
</div>

样例代买

<template>
  <div class="list" ref="wrapper">
    <div>
      <div class="area">
        <div class="title border-topbottom">当前城市</div>
        <div class="button-list">
          <div class="button-wraper"><div class="button">北京</div></div>
        </div>
      </div>
      <div class="area">
        <div class="title border-topbottom">热门城市</div>
        <div class="button-list">
          <div class="button-wraper"><div class="button">北京</div></div>
          <div class="button-wraper"><div class="button">北京</div></div>
          <div class="button-wraper"><div class="button">北京</div></div>
          <div class="button-wraper"><div class="button">北京</div></div>
          <div class="button-wraper"><div class="button">北京</div></div>
        </div>
      </div>
      <div class="area">
        <div class="title border-topbottom">A</div>
        <div class="item-list">
          <div class="item border-bottom">阿拉尔</div>
          <div class="item border-bottom">阿拉尔</div>
          <div class="item border-bottom">阿拉尔</div>
          <div class="item border-bottom">阿拉尔</div>
          <div class="item border-bottom">阿拉尔</div>
          <div class="item border-bottom">阿拉尔</div>
          <div class="item border-bottom">阿拉尔</div>
        </div>
        <div class="title border-topbottom">A</div>
        <div class="item-list">
          <div class="item border-bottom">阿拉尔</div>
          <div class="item border-bottom">阿拉尔</div>
          <div class="item border-bottom">阿拉尔</div>
          <div class="item border-bottom">阿拉尔</div>
          <div class="item border-bottom">阿拉尔</div>
          <div class="item border-bottom">阿拉尔</div>
          <div class="item border-bottom">阿拉尔</div>
        </div>
        <div class="title border-topbottom">A</div>
        <div class="item-list">
          <div class="item border-bottom">阿拉尔</div>
          <div class="item border-bottom">阿拉尔</div>
          <div class="item border-bottom">阿拉尔</div>
          <div class="item border-bottom">阿拉尔</div>
          <div class="item border-bottom">阿拉尔</div>
          <div class="item border-bottom">阿拉尔</div>
          <div class="item border-bottom">阿拉尔</div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import BScroll from 'better-scroll'
export default {
  name: 'CityList',
  mounted () {
    this.scroll = new BScroll(this.$refs.wrapper)
  }
}
</script>

<style lang="stylus" scoped>
  @import '~styles/varibles.styl';
  .list
    overflow hidden
    position absolute
    top 1.58rem
    left 0
    right 0
    bottom 0
    .border-topbottom
      &:before
        border-color #cccccc
      &after
        border-color #cccccc
    .border-bottom
      &:before
        border-color #cccccc
    .title
      line-height .44rem
      background #eee
      padding-left .2rem
      color #666
      font-size .26rem
    .button-list
      overflow hidden
      padding .1rem .6rem .1rem .1rem
      .button-wraper
        float left
        width 33.33%
        .button
          margin .1rem .1rem
          padding .1rem 0
          text-align center
          border .02rem solid #cccccc
          border-radius .06rem
    .item-list
      .item
        line-height .76rem
        color #666
        padding-left .2rem
</style>

3 滚动到某一个元素处

this.scroll.scrollToElement(element)

3.6 Vuex实现数据共享

官方推荐
安装:

npm install vuex --save

使用:

//1 创建store 存储值的文件index.js
import Vue from 'vue'
import Vuex from 'vuex'
// 使用插件
Vue.use(Vuex)
// 导出vuex 创建的仓库
export default new Vuex.Store({
  state: {
    city: '北京'
  },
  //这个可以被跳过,直接调用commit
  actions: {
    //接收修改值的请求
    changeCity (ctx, city) {
      // 执行mutations,来修改需要修改的值
      ctx.commit('changeCity', city)
    }
  },
  mutations: {
    //修改值
    changeCity (state, city) {
      state.city = city
    }
  }
})


//2 在main.js中引入
import store from './store'

new Vue({
  el: '#app',
  //数据共享
  store,
})

// 3 在用的地方直接调用
{{ this.$store.state.city }}

//4 改变里面值的方法,发送请求
handleCityClick (city) {
  this.$store.dispatch('changeCity', city)
}

vuex映射值,简单使用

import { mapState } from 'vuex'

//将值映射到计算属性中
computed: {
// ... 展开属性
...mapState(['city'])
}

然后直接 this.city 就可以了

3.6 本地存储 localStorage

使用

//存值
localStorage.city = city

//取用
localStorage.city || '默认值'

3.7 keep-alive优化网页性能

//用这个包裹了以后,就会有缓存,不在重新加载数据,Detail组件不被缓存
<keep-alive exclude="Detail">
  <!-- 显示的是当前路由地址所对应的内容 -->
  <router-view/>
</keep-alive>

使用了 keep-alive后,会多出一个生命周期函数,可以用来做一些操作

// 使用了 keep-alive后,会多出一个生命周期函数,可以用来做一些操作
  activated() {
    
  },

3.8 递归组件的使用

数据

list: [{
    title: '成人票',
    children: [{
      title: '成人三馆联票',
      children: [{
        title: '成人三馆联票-某一连锁店销售'
      }]
    }, {
      title: '成人五馆联票'
    }]
    }, {
    title: '学生票'
    }, {
    title: '儿童票'
    }, {
    title: '特惠票'
    }]

组件的自身去调用组件自身

<template>
  <div>
    <router-link tag="div" to="/" class="header-abs" v-show="showAbs">
      <div class="iconfont header-abs-back">&#xe624;</div>
    </router-link>
    <div
      class="header-fixed"
      v-show="!showAbs"
      :style="opacityStyle"
      >
      景点详情
      <router-link to="/"><div class="iconfont header-fixed-back">&#xe624;</div></router-link>
    </div>
  </div>
</template>

<script>
export default {
  name: 'DetailHeader',
  data () {
    return {
      showAbs: true,
      opacityStyle: {
        opacity: 0
      }
    }
  },
  methods: {
    // 滚动监听事件
    handleScroll () {
      const top = document.documentElement.scrollTop
      if (top > 60) {
        let opacity = top / 140
        opacity = opacity > 1 ? 1 : opacity
        this.opacityStyle = { opacity }
        this.showAbs = false
      } else {
        this.showAbs = true
      }
    }
  },
  activated () {
    window.addEventListener('scroll', this.handleScroll)
  },
  // 使用keep-alive后出现的方法,页面即将被影藏时会执行
  deactivated () {
    window.removeEventListener('scroll', this.handleScroll)
  }
}
</script>

<style lang="stylus" scoped>
  @import '~styles/varibles.styl';
  .header-abs
    position absolute
    left .2rem
    top  .2rem
    width .8rem
    height .8rem
    line-height .8rem
    border-radius .4rem
    text-align center
    background rgba(0, 0, 0, .8)
    .header-abs-back
      color #ffffff
      font-size .4rem
  .header-fixed
    z-index 2
    position fixed
    top 0
    left 0
    right 0
    height $headerHeight
    line-height $headerHeight
    text-align center
    color #ffffff
    background $bgColor
    font-size .32rem
    .header-fixed-back
      position absolute
      top 0
      left 0
      width .64rem
      text-align center
      font-size .4rem
      color #ffffff
</style>

4 样例

4.1 头部渐隐渐现的效果组件

<template>
  <div>
    <router-link tag="div" to="/" class="header-abs" v-show="showAbs">
      <div class="iconfont header-abs-back">&#xe624;</div>
    </router-link>
    <div
      class="header-fixed"
      v-show="!showAbs"
      :style="opacityStyle"
      >
      景点详情
      <router-link to="/"><div class="iconfont header-fixed-back">&#xe624;</div></router-link>
    </div>
  </div>
</template>

<script>
export default {
  name: 'DetailHeader',
  data () {
    return {
      showAbs: true,
      opacityStyle: {
        opacity: 0
      }
    }
  },
  methods: {
    // 滚动监听事件
    handleScroll () {
      const top = document.documentElement.scrollTop
      if (top > 60) {
        let opacity = top / 140
        opacity = opacity > 1 ? 1 : opacity
        this.opacityStyle = { opacity }
        this.showAbs = false
      } else {
        this.showAbs = true
      }
    }
  },
  activated () {
    window.addEventListener('scroll', this.handleScroll)
  }
}
</script>

<style lang="stylus" scoped>
  @import '~styles/varibles.styl';
  .header-abs
    position absolute
    left .2rem
    top  .2rem
    width .8rem
    height .8rem
    line-height .8rem
    border-radius .4rem
    text-align center
    background rgba(0, 0, 0, .8)
    .header-abs-back
      color #ffffff
      font-size .4rem
  .header-fixed
    position fixed
    top 0
    left 0
    right 0
    height $headerHeight
    line-height $headerHeight
    text-align center
    color #ffffff
    background $bgColor
    font-size .32rem
    .header-fixed-back
      position absolute
      top 0
      left 0
      width .64rem
      text-align center
      font-size .4rem
      color #ffffff
</style>

4.2 渐影渐现的动画组件

<template>
  <transition>
    <slot></slot>
  </transition>
</template>

<script>
export default {
  name: 'FadeAnimation'
}
</script>

<style lang="stylus" scoped>
  .v-enter, .v-leave-to
    opacity 0
  .v-enter-active, .v-leave-active
    transition opacity .5s
</style>

使用

//在使用的地方用它包裹即可
<fade-animation>
      <common-gallary
        :imgs="bannerImgs"
        v-show="showGallarly"
        @close="handlerGallaryClose"
      ></common-gallary>
    </fade-animation>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值