项目四遇到的知识点总结

一、Vue组件之间传值

(一)、父组件向子组件传递数据

  • 1.父组件调用子组件的时候绑定动态属性
  • 2.在子组件里面通过props接收父组件传过来的数据

1、在 Vue 中,可以使用 props 向子组件传递数据。

(1).子组件
<template>
    <div class="children">
        <h5>{{msg}}</h5>
        <ul class="children-list">
            <li>
                <span>姓名</span>
                <span>性别</span>
                <span>年龄</span>
            </li>
            <li  v-for="item in items">
                <span>{{item.name}}</span>
                <span>{{item.sex}}</span>
                <span>{{item.age}}</span>
            </li>
        </ul>
    </div>
</template>
<script>
    export default {
        name: 'children',
        props: ['items'],
        data() {
            return {
                msg: '我是子组件',
            }
        }
    }
</script>

(2).父组件
<template>
    <div class="more">
        <h3>我是父组件</h3>
        <Children :items="itemList"></Children>
    </div>
</template>
<script>
    import Children from './children.vue'
    export default {
        name: 'more',
        data() {
            return {
                itemList:[//itemList这个数据是后端给的
                    {
                        name: '张三',
                        sex: '男',
                        age: '18'
                    },
                    {
                        name: '李四',
                        sex: '女',
                        age: '19'
                    },
                    {
                        name: '王麻子',
                        sex: '男',
                        age: '20'
                    }
                ]
            }
        },
        components: {
            Children
        }
    }
</script>

(3).浏览器运行结果

2、父组件主动获取子组件的数据和方法

(1) 调用子组件的时候定义一个ref
        <Children ref="header"></Children>
(2) 在父组件里面通过
        this.$refs.header.属性
        this.$refs.header.方法

(二)、子组件向父组件传递数据

1、子组件主要通过事件传递数据给父组件

(1).子组件
<template>
    <div class="children">
        <h5>{{msg}}</h5>
        <span>子组件用户名:</span>
        <input type="text" v-model="name" @change="getChange">
    </div>
</template>
<script>
    export default {
        name: 'children',
        data() {
            return {
                msg: '我是子组件',
                name: ''
            }
        },
        methods: {
            getChange() {
                this.$emit('userName',this.name)

            }

        }
    }
</script>
(2).父组件组件
<template>
    <div class="more">
        <h3>我是父组件</h3>
        <Children @userName="getUser"></Children>
        <p>父组件用户名为:{{user}}</p>
    </div>
</template>
<script>
    import Children from './children.vue'
    export default {
        name: 'more',
        data() {
            return {
                user: ''
            }
        },
        methods: {
            getUser(msg) {
                this.user = msg
            }
        },
        components: {
            Children
        }
    }
</script>
(3).运行结果

2、子组件主动获取父组件的数据和方法

    this.$parent.数据
    this.$parent.方法

(三)、非父子组件的传值

  • 架起一个沟通的桥梁,是数据能够传递

1、新建一个js文件 然后引入vue 实例化vue 最后暴露这个实例

    event.js
    import Vue from 'vue';
    var Event = new Vue();
    export default Event;

2、在相应的组件引入刚才的实例

        import Event from './event.js'

3、通过Event.$emit('名称','数据')

4、在接收数据的地方通过$on接收数据

    Event.$on('名称',function(){})

二、vue图片懒加载---vue lazyload插件的简单实用

1、插件地址

2、 npm地址

3、开始使用

(1).安装
  • 安装在所在项目中

      npm install vue-lazyload --save
    
(2).在main.js引入插件
import Lazyload from 'vue-lazyload'
Vue.use(Lazyload,{
	error: './static/images/default.png',
	loading: './static/images/default.png'
});
(3).Vue文件中将需要懒加载的图片绑定v-bind:src(:src)修改为v-lazy
  • 图片懒加载的简单效果已经实现

      <img class="item-pic" v-lazy="items.imgUrl"/>
    

查看更多请看

遇到问题

  • 之前为了加载快把所有的图片做成懒加载
  • 同一个接口渲染列表的时候图片出现问题,取消懒加载就可以了。

(三)、vue前端开发--图片查看大图插件 vue-photo-preview

1、npm地址

2、开始实用

(1). 安装
npm install vue-photo-preview --save
(2). main.js中使用
import preview from 'vue-photo-preview'
import 'vue-photo-preview/dist/skin.css'
Vue.use(preview)
(3) 直接使用
//在img标签添加preview属性 preview值相同即表示为同一组
<img src="xxx.jpg" preview="0" preview-text="描述文字">
//分组
<img src="xxx.jpg" preview="1" preview-text="描述文字">
<img src="xxx.jpg" preview="1" preview-text="描述文字">
<img src="xxx.jpg" preview="2" preview-text="描述文字">
<img src="xxx.jpg" preview="2" preview-text="描述文字">  
(4)script
var options = {}

(四)、VUE中如何定义全局函数

1、方法1

(1)在main.js写入函数
  • $changeData名字随便定义,加$是为了区分其他函数,可以不加。

      Vue.prototype.$changeData = function() {
      	alert('我是全局函数')
      }
    
(2)在所有组件里可调用函数
this.$changeData();

2、方法2

(1)新建所需要的components.js
  • components.js(名字随便定义)

components.js

export default(Vue) => {
	//格式化手机号码,手机号中间4位加*号
	Vue.prototype.$formatePhone = (phone) => {
		if(!isNaN(phone)) {
			return phone.substr(0, 3) + '****' + phone.substr(7);
		} else {
			return '***********';
		}
	}
}
  • 手机号中间4位加*号
  • var str='1366668888';
  • var str2 = str.substr(0,3)+"****"+str.substr(7);
  • 这样写只能在当前位置使用
(2)main.js引入并使用
import Components from './component'
Vue.use(Components)
(3)在所有组件里可调用函数
$formatePhone(12345678945)

(五)、keep-alive使用

  • <keep-alive>是Vue的内置组件,能在组件切换过程中将状态保留在内存中,防止重复渲染DOM
  • <keep-alive>包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。和<transition>相似,<keep-alive>是一个抽象组件:它自身不会渲染一个DOM元素,也不会出现在父组件链中

1、prop:

  • include:字符串或正则表达式。只有匹配的组件会被缓存
  • exclude:字符串或正则表达式。任何匹配的组件都不会被缓存

2、常见用法:

//组件
export default {
	name: 'test-keep-alive',
	data() {
		return {
			includedComponents: "test-keep-alive"
		}
	}
}

``

 <keep-alive include="test-keep-alive">
    <!-- 将缓存name为test-keep-alive的组件 -->
    <component></component>
</keep-alive>
<keep-alive include="a,b">
    <!-- 将缓存name为a或者b的组件,结合动态组件使用 -->
    <component :is="view"></component>
</keep-alive>

<!-- 使用正则表达式,需使用v-bind -->
<keep-alive :include="/a|b/">
    <component></component>
</keep-alive>

<!-- 动态判断 -->
<keep-alive :include="includedComponents">
    <router-view></router-view>
</keep-alive>

<keep-alive exclude="test-keep-alive">
    <!-- 将不缓存name为test-keep-alive的组件 -->
    <component></component>
</keep-alive>

项目中遇到缓存问题

  • 之前把:include="includedComponents放在最外层的app.vue是不生效的,里面还有一个index.vue

    	<keep-alive :include="includedComponents">
        <router-view class="content"></router-view>
     	</keep-alive>
      data:() =>{
      	return {
      		//缓存界面name值列表
      			'new',
      			'new-detail'
      	}
      }
    

3、结合router,缓存部分页面

  • 使用$router.meta的keepAlive属性:

      <keep-alive>
          <router-view v-if="$router.meta.keepAlive"></router-view>
      </keep-alive>
      <router-view v-if="!$router.meta.keepAlive"></router-view>
    
  • 需要在router中设置router的元信息meta:

      //router.js
      export default new Router({
        routes:[
          {
            path: '/home',
            name: 'Hello',
            component: Hello,
            meta: {
              keepAlive: false //不需要缓存
            }
          },
          {
            path: '/page1',
            name: 'Page1',
            component: Page1,
            meta: {
              keepAlive: true //不需要缓存
            }
          }
      
        ]
      })
    

4、使用效果

  • 以上面router的代码为例

      <!-- Page1页面 -->
      <template>
        <div class="hello">
          <h1>page页面</h1>
          <h2>{{msg}}</h2>
          <input placeholder="输入框"></input>
        </div>
      </template>
      <script>
          export default {
              data:() => {
                  return {
                      msg: 'Keep-alive'
      
                  }
              }
          }
      </script>
    

``

<!-- Hello页面 -->
<template>
  <div class="hello">
    <h1>{{msg}}</h1>
  </div>
</template>
<script>
    export default {
        data() {
            return {
                msg: '我是hello页面'
            }
        }
    }
</script>
  • 进入Page1页面,并输入‘说点什么’

  • 跳转到Hello

  • 进入Page1页面,输入框数据会被保留

原文地址

(六)vue-router中$route和$router

1、$route对象

  • route是一个跳转的路由对象,每一个路由都会有一个route对象,是一个局部的对象,可以获取对应的name,path,params,query等。
(1)$route表示当前路由信息对象
  • 路由对象表示当前活动路由的状态。它包含当前URL的解析信息以及URL匹配的路由记录。

  • 路由对象是不可改变的。每次成功导航都会产生一个新的路线对象

  • 路径对象可以在多个位置找到:

  • 1.内部组件为this.$route

  • 2.内部$route观察者回调

  • 3.作为调用的返回值router.match(location)

  • 内部导航守卫作为前两个参数

      router.beforeEach((to, from, next) => {
        // `to` and `from` are both route objects
      })
    
  • scrollBehavior函数内部作为前两个参数

      const router = new VueRouter({
        scrollBehavior (to, from, savedPosition) {
          // `to` and `from` are both route objects
        }
      })
    
(2)路由对象属性
1. $route.path:  对应当前路径的字符串,始终解析为绝对路径。例如'/trust'.
2. $route.params: 一个key/value对象,包含了动态片段和全匹配片段,如果没有路由参数,就是一个空对象。
3. $route.query:  一个key/value对象,表示URL查询参数。
例如,对于路径/trust?id=1,则有$route.query.id == 1,如果没有查询参数,则是个空对象
4. $route.hash: 当前路由的哈希值(#如果有)。如果没有哈希值,则为空字符串。
5. $route.fullPath: 完成解析后的URL,包含查询参数和hash的完整路径。
6. $route.matched: 数组,包含当前匹配的路径中所包含的所有片段所对应的配置参数对象
7. $route.name: 当前路径名字
8. $route.meta: 路由元信息

2、$router对象

  • router是VueRouter的一个对象,通过Vue.use(VueROuter)和VueRouter构造函数得到一个router的实例对象,这个对象中是一个全局的对象,它包含所有的路由包含了许多关键的对象和属性

(1) 路由器实例属性
  • router.app: router注入的根Vue实例
  • router.mode: 路由器正在使用的模式
  • router.currentRoute: 当前路由表示为路由对象
(2)、路由器实例方法
  • this.$router.push()
  • this.$router.replace()
  • this.$router.go()
  • this.$router.back()
  • this.$router.forward()

(七)、Vue.js实现tab切换效果

<ul>
     <li v-for="(item,index) in items" :class="{'actived': curIndex == index}" @click="isShow(index)">{{item.value}}</li>
</ul>
<div v-for="(item,index) in items" v-show="curIndex == index">
      <div v-for="list in item.lists">
           {{list.text}}
       </div>
 </div>

<script>
export default{
	data:()=>{
		return {
 			curIndex: 0,
            items: [
                {
                    value: '我是A标题',
                    lists: [
                        {
                            text: '我是A1内容',
                        },
                        {
                            text: '我是A2内容',
                        }
                    ]
                },
                {
                    value: '我是B标题',
                    lists: [
                        {
                            text: '我是B的内容'
                        },
                        {
                            text: '哈哈我也是B的内容'
                        }
                    ]
                }
            ]
},
methods: {
    isShow(index){
        this.curIndex = index;
    }
}
}

css

.actived {
    color: red;
}

(八)、css修改滚动条默认样式

1、滚动条

::-webkit-scrollbar {} //滚动条整体部分
::-webkit-scrollbar-track{} //滚动条滑轨
::-webkit-scrollbar-track-piece{} //内层轨道,滚动条中间部分
::-webkit-scrollbar-thumb{}//滚动条滑块
::-webkit-scrollbar-button{} //滑轨两头的监听按钮
::-webkit-scrollbar-button:start {}//滑轨顶部的监听按钮
::-webkie-scrollbar-button:end{}//滑轨底部的监听按钮
::-webkit-scrollbar-corner{}//横向滚动条和纵向滚动条相交处的尖角
::-webkit-resizer{}//两个滚动条的交汇处上用于通过拖动调整元素大小的小控件

//还可设置鼠标移动上去时的变化
::-webkit-scrollbar-track:hover{}
::-webkit-scrollbar-thumb:hover{}
::-webkit-scrollbar-button:start:hover{}
::-webkit-scrollbar-button:end:hover{}
  • html代码

      <div class="inner">
          <div class="inner-box">
              <p style="height:100px;">我是内容1</p>
              <p style="height:300px;">我是内容2</p>
              <p>那我就是内容3</p>
          </div>
      </div>
    
  • css代码

      .inner {
          position: absolute;
          top: 50%;//根据实际需求写
          left: 15px;
          overflow: hidden;
          width: 300px;
          height: 300px;
      }
      .inner-box {
          overflow-x: hidden;
          overflow-y: auto;
          color: #000;
          height: 100%;
      }
       /*滚动条样式*/
      .inner-box::-webkit-scrollbar {/*滚动条整体样式*/
          width: 4px;     /*高宽分别对应横竖滚动条的尺寸*/
          height: 4px;
      }
      .inner-box::-webkit-scrollbar-thumb {/*滚动条里面小方块*/
          border-radius: 5px;
          -webkit-box-shadow: inset 0 0 5px rgba(0,0,0,0.2);
          background: rgba(0,0,0,0.2);
      }
      .inner-box::-webkit-scrollbar-track {/*滚动条里面轨道*/
          -webkit-box-shadow: inset 0 0 5px rgba(0,0,0,0.2);
          border-radius: 0;
          background: rgba(0,0,0,0.1);
      }
    

原文地址:

### (九)、css点击放大1.2倍

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <title>阳台飘窗实例</title>
    <style type="text/css">
        * {
            margin: 0;
            padding: 0;
        }
        .box {
            margin: 100px auto;
        }
        .top {
            width: 1170px;
            height: 100px;
            line-height: 100px;
            background: #eee;
            margin: 0 auto;
            text-align: center;
            font-size: 24px;
            color: #000;
        }
        .bay-window {
            position: relative;
            width: 1308px;//width*子元素的个数+margin*6 300*3+68*6
            margin: 0 auto;
        }
        .bay-list {
            width: 300px;
            height: 300px;
            float: left;
            margin: 68px;
            background: pink;
            font-size: 24px;
            text-align: center;
            line-height: 300px;
        }
        .bay-list:hover{
            transform: scale(1.2);
            transition: all .25s;
            background: cyan;
        }
        .bay-list:hover:before {
            position: absolute;
            top: 0;
            right: 0;
            content: '';
            width: 15px;
            height: 15px;
            margin: 5px;
            background: red;
            z-index: 1;

        }
    </style>
</head>
<body>
<div class="box">
    <div class="top">我是1170的宽度</div>
    <div class="bay-window">
        <div class="bay-list">飘窗1</div>
        <div class="bay-list">飘窗2</div>
        <div class="bay-list">飘窗3</div>
        <div style="clear:both;"></div>
    </div>
</div>
</body>
</html>

(十)判断是PC还是客户端

  • pc首页写

        created(){
          this.initData();
        },
        methods: {
          initData() {
            //判断手机还是pc
              var MOBILE_WEB = '客户端地址';
              var userAgentInfo = navigator.userAgent;
              var Agents = ["Android","iPhone","SymbianOS","Windows Phone","iPad","iPod"];
              var isPc = true;
              for(var v = 0; v < Agents.length; v++){
                  if(userAgentInfo.indexOf(Agents[v]) > 0){
                      isPc = false;
                      break;
                  }
              }
              if (!isPc) {
                location.href = MOBILE_WEB;
              }
          }
      
        }
    
  • 客户端首页写

      <script>
      	//判断手机还是pc
          var PC_WEB = 'pc地址'
          var userAgentInfo = navigator.userAgent;
          var Agents = ["Android","iPhone","SymbianOS","Windows Phone","iPad","iPod"];
      
          var isPc = true;
          for(var v = 0; v < Agents.length; v++){
              if(userAgentInfo.indexOf(Agents[v]) > 0){
                  isPc = false;
                  break;
              }
          }
          if (isPc) {
              location.href = PC_WEB;
          }
      </script>
    

零碎知识点

Safari3D 变换会忽略z-index 解决方法

  • 父级,任意父级,非body级别,设置overflow:hidden可恢复和其他浏览器一样的渲染。

  • 不能给父级设置overflow:hidden,怎么办呢?

      .bar {
          position: fixed;
          z-index: 99;
          /* 以毒攻毒 */
          transform: translateZ(100px);
      }
    

屏幕滚动到一定位置div显示

  • top是div的class类,fixed固定位置

      $(window).scroll(function(){
      	var winHeight = $(window).height();
      	var top = $(this).scrollTop();
      	var isVisible = top >= winHeight;
      	if(isVisible){
      		$('.top').addClass('fixed');
      	}else{
      		$('.top').removeClass('fixed');
      	}
      });
    

监听鼠标,超过一分钟鼠标没有移动,弹框

var that = this;

  document.onmousemove = function () {
    window.lastMove = new Date().getTime();
  }
  window.lastMove = new Date().getTime();
  window.setInterval(function() {
    var now = new Date().getTime();
    if(now - lastMove > 60000 ){
        alert('超过一分钟我出现了')
    }
  },1000)

需求在首页出现弹框,其他页不出现,用vue写的项目

    export default {
          name: 'home',
          data: ()=>{
            return {
                      lastMoveTimer: null
            }
      },
      mounted() {
                  var that = this;
                  //监听鼠标,鼠标没有移动超过1分钟,弹销售扫码。
                  document.onmousemove = function () {
                        window.lastMove = new Date().getTime();
                  }
                  window.lastMove = new Date().getTime();
                  that.lastMoveTimer = setInterval(function() {
                   var now = new Date().getTime();
                   if(now - lastMove > 120000){
                        //两分钟后出现弹框
           
                   }
          },1000)

      },
       // 生命周期销毁
      beforeDestroy:function(){
            clearInterval(this.lastMoveTimer);
            this.lastMove = null;
      }
}

路由跳转新窗口

  • home 详情页

      let routeData = this.$router.resolve({ path: '/home/'+item.id});
          window.open(routeData.href, '_blank');
    
  • 点击按钮打开邮箱的代码

      	点击按钮打开邮箱:<input type="button" value="邮件" onclick="mailto:xxx@163.com">
        点击按钮发送邮件(以126邮箱为例): <a href="mailto:XXX@126.com">Email</a>
    
  • 解决input获得焦点时边框没有border-radius

  • -webkit-appearance —— webkit外观样式属性

      input {
       	border-radius: 8px;
          outline: 0;
          -webkit-transition:.2s border-color;//属性渐变
          -webkit-appearance: none;//来移除原生控件样式
      }
      input:focus {
      	border-color: #20a0ff;
      }
    
posted @ 2018-10-12 18:40  不完美的完美  阅读(238)  评论(0编辑  收藏  举报