Vue常用技巧

文章目录

使用gitHub进行版本控制

  • 1、生成本地仓库git init

一、子组件与父组件通信

1、子组件使用父组件的值

在这里插入图片描述在这里插入图片描述

2、子组件通过父组件提供的函数,修改父组件的数据

在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

3、子组件与父组件方法同名,无限调用结果超出最大调用栈(一定要避免子组件函数与父组件传递来的函数同名)

在这里插入图片描述

一点一、获取dom节点(html对象)

在这里插入图片描述在这里插入图片描述

二、根据v-model双向绑定vue数据和html标签(复选框,单选框),可直接影响值

在这里插入图片描述在这里插入图片描述

三、删除选中内容(使用filter函数将数组中满足条件的筛选出来)

在这里插入图片描述在这里插入图片描述在这里插入图片描述

四、全选与全不选(通过forEach方法遍历数组所有元素)

在这里插入图片描述在这里插入图片描述在这里插入图片描述

五、根据选中数量,动态显示数据(根据条件计算数组元素)

	Array.reduce(function(total,item){
    	if(item.flag==true) return total+1;
    	else return total;
    },functionItem)
    * total:初始值和返回值,默认Object,在整个执行过程中,值不会丢失
    * item:当前数组元素
    * functionItem:回调函数初始值,初次调用将值赋值给total,之后不会作用
    * 回调函数执行次数和数组元素数量相同,functionItem会在第一次调用时赋值给total,total会根据函数体做出相应改变,最终total是整个函数返回值
    return this.items.reduce((total,item)=>item.flag==true?total+1:total,0);

在这里插入图片描述在这里插入图片描述在这里插入图片描述

六、实现若所有复选框都选中,则全选按钮选中,若有一个没选中,则全选按钮自动不选中,不影响全选按钮功能(使用监听函数的get和set)

  • 需要了解,这里的计算属性我双向绑定在复选框上,它操作的仅仅是复选框是否勾选上,也就是说与全选功能分离开了,互相不影响,而对于这里的set,有没有都一样,只是语法要求这样写,而input上绑定了click事件用于实现全选功能,不会影响与被影响
    在这里插入图片描述
  • 点击事件如下:需要说明,这里假设没有全选,计算变量的值就是false,而我们现在想让它全选,点击后并不会改值,所有需要传相反的值过去,而传过去后,所有都被选中,num就变为数组长度,这时计算属性也就根据监听条件变成了true在这里插入图片描述

七、本地存储数据,Watch深度监听(JS函数介绍来源于菜鸟教程)

  • 使用Js原生函数Window localStorage 属性

    localStorage 可以创建一个本地存储的 name/value 对

      保存数据语法:
      window.localStorage.setItem("key", "value");
      读取数据语法:返回值为字符串
      var lastname =window.localStorage.getItem("key");
      删除数据语法:
      window.localStorage.removeItem("key");
    

    JSON.parse() 方法用于将一个 JSON 字符串转换为对象。

      JSON.parse(text[, reviver])
      参数说明:
      text:必需, 一个有效的 JSON 字符串。
      reviver: 可选,一个转换结果的函数, 将为对象的每个成员调用此函数。
    

    JSON.stringify() 方法用于将 JavaScript 值转换为 JSON 字符串。

      语法
      JSON.stringify(value[, replacer[, space]])
      参数说明:
      
      value:
      必需, 要转换的 JavaScript 值(通常为对象或数组)。
      
      replacer:
      可选。用于转换结果的函数或数组。
      
      如果 replacer 为函数,则 JSON.stringify 将调用该函数,并传入每个成员的键和值。使用返回值而不是原始值。如果此函数返回 undefined,则排除成员。根对象的键是一个空字符串:""。
      
      如果 replacer 是一个数组,则仅转换该数组中具有键值的成员。成员的转换顺序与键在数组中的顺序一样。
      
      space:
      可选,文本添加缩进、空格和换行符,如果 space 是一个数字,则返回值文本在每个级别缩进指定数目的空格,如果 space 大于 10,则文本缩进 10 个空格。space 也可以使用非数字,如:\t。
    
  • 1、将写死的数据,清除,使用localStorage 动态将本地文件存储到数据中(这里items是个数组,但计算机不知道,所以在localStorage没有值的情况下,存储一个空数组,JSON.parse参数是字符串,所以写’[]’)在这里插入图片描述

  • 2、深度监视数据在这里插入图片描述

八、Ajax请求,使用vue2.x推荐的axios

  • 安装axios:命令npm install axios --save
  • 引入模块并使用在这里插入图片描述

九、SPA(单页面应用)前端路由,动态加载组件

  • 1、创建普通vue-cli文件,然后用npm创建过程中引入Router路由,或者用命令安装路由npm install vue-router --save
  • 2、src文件夹下创建router文件夹(路由文件都在这里名存放),然后在其中创建一个index.js文件在这里插入图片描述
  • 3、在主文件main.js配置路由在这里插入图片描述
  • 4、写一个小案例
    • 效果演示在这里插入图片描述在这里插入图片描述
    • 1、创建路由组件(因为一共两个选项卡,移入不同选项卡,会生成不同组件,所以有对应两个路由)在这里插入图片描述
    • 2、将这两个组件添加到路由在这里插入图片描述在这里插入图片描述
    • 3、在父组件引入路由组件在这里插入图片描述在这里插入图片描述在这里插入图片描述

嵌套路由(一个路由嵌套多个子路由)

  • 1、定义子路由组件在这里插入图片描述
  • 2、注册子组件在这里插入图片描述
  • 3、在父路由中,使用子路由在这里插入图片描述
  • 测试在这里插入图片描述

路由默认重定向,当转到特定路由组件,直接显示默认内容,而不需要选中才出现(注意,每次请求都只生效一次)

在这里插入图片描述在这里插入图片描述在这里插入图片描述

  • 1、定义重定向在这里插入图片描述在这里插入图片描述

切换路由时,不结束刷新路由生命周期,保留数据

  • 使用keep-alive标签套住的view,切换路由时,不会刷新数据
    在这里插入图片描述

路由组件传值

  • 1、先在路由的路径中声明参数在这里插入图片描述
  • 2、使用名字+params传值在这里插入图片描述在这里插入图片描述在这里插入图片描述

根据url参数动态展示路由数据

在这里插入图片描述在这里插入图片描述在这里插入图片描述

通过router-view标签传递参数

在这里插入图片描述在这里插入图片描述在这里插入图片描述

十、触发事件跳转路由(this.$router.replace 或push(path)函数可跳转到指定路由)

在这里插入图片描述

十一、移动端滑动轮播(最外层定义一个div,你希望的轮播大小,里面一个宽度非常大的div,用来容纳图片,如果你有5个轮播图,那么这个div应该正好是最外层div的5倍)

  • 1、创建文档结构在这里插入图片描述
  • 2、编写css在这里插入图片描述
  • 效果在这里插入图片描述
  • 之后就是实现效果,但是怎么实现循环呢?我们可以每次把最后一张轮播复制一份放在最前面,最前面的复制一份放在最后面,当我们在第一张图片往左滑动时,直接就转到复制的最后一张上,然后迅速转移到真正的最后一张,用户看不出来我们这样切换,就实现了循环
  • 但是这样就将代码写死了,所以我们应该用js或vue代码实现动态轮播

vue实现动态轮播

  • 1、给轮播容器(最大的内个div)添加ref属性在这里插入图片描述
  • 2、获取dom节点,并由它获取子节点,然后插入
/* 获取节点*/
	    const routers_wapper =this.$refs.routers_wapper;//获取轮播容器
	    const first = routers_wapper.firstChild;        //获取轮播容器中第一个子节点
	    const last = routers_wapper.lastChild;          //获取轮播容器中最后一个子节点
	    /* 拷贝节点 */
	    const firstClone =first.cloneNode(true);        //获取first的精确拷贝,属于复制一份,如果不拷贝,相当于剪切操作
	    const lastClone =last.cloneNode(true);          //获取last的精确拷贝,包括所有属性
	    /* 将拷贝的第一个节点放在最后,拷贝的最后一个节点放在最前面*/
	    routers_wapper.appendChild(firstClone);        //在最末尾添加一个first(刚刚获取的最前面的节点)
	    //insertBefore可以在当前容器中的指定元素之前插入一个元素
	    routers_wapper.insertBefore(lastClone,first);   //在first元素之前插入last的拷贝
  • 在这里插入图片描述
/* 1、修改页面样式结构 */
   /* 获取节点*/
   const routers=document.querySelector('div.routers');//获取总容器
   const routers_wapper =this.$refs.routers_wapper;//获取轮播容器
   const first = routers_wapper.firstChild;        //获取轮播容器中第一个子节点
   const last = routers_wapper.lastChild;          //获取轮播容器中最后一个子节点
   /* 拷贝节点 */
   const firstClone =first.cloneNode(true);        //获取first的精确拷贝,属于复制一份,如果不拷贝,相当于剪切操作
   const lastClone =last.cloneNode(true);          //获取last的精确拷贝,包括所有属性
   /* 将拷贝的第一个节点放在最后,拷贝的最后一个节点放在最前面*/
   routers_wapper.appendChild(firstClone);        //在最末尾添加一个first(刚刚获取的最前面的节点)
   //insertBefore可以在当前容器中的指定元素之前插入一个元素
   routers_wapper.insertBefore(lastClone,first);   //在first元素之前插入last的拷贝


   /* 2、设置样式 轮播容器宽度等于 总容器宽度*轮播内容数量 */
   /* 获取容器中所有轮播div节点 */
   const routerArr=routers_wapper.querySelectorAll('div.router');//获取轮播容器中class为router的div
   let index=1;//表示当前轮播索引值
   /* 获取routers的宽度,此参数需要做变换,声明为let */
   let routersWidth=routers.offsetWidth;
   /* 获取轮播div的数量 */
   const routerNumber=routerArr.length;
   /* 动态设置轮播容器宽度 */
   routers_wapper.style.width=routersWidth*routerNumber+'px';
   /* 动态设置每一个轮播内容的宽度(它们的宽度就是总容器的宽度)*/
   routerArr.forEach(item=> routersWidth+'px')

   /* 3、设置默认偏移(要偏移轮播容器,显示第一张图片,而不是我们插入的最后一张的拷贝)而偏移就是总容器宽度*/
   routers_wapper.style.left=-routersWidth+'px';

   /* 4、我们必须保证 当切换不同屏幕时,图片的大小也相应变化,也就是响应式*/
     window.onresize=function(){//监听屏幕是否改变大小
      /* 重新获取routers的宽度 */
     routersWidth=routers.offsetWidth;
     /* 重新动态设置轮播容器宽度 */
     routers_wapper.style.width=routersWidth*routerNumber+'px';
     /* 重新动态设置每一个轮播内容的宽度(它们的宽度就是总容器的宽度)*/
     routerArr.forEach(item=> routersWidth+'px')

     /*  重新设置默认偏移(要偏移轮播容器,显示第一张图片,而不是我们插入的最后一张的拷贝)而偏移就是总容器宽度,当我们正在轮播时,应该根据
         当前的轮播内容设置默认偏移,所以*index
     */
     routers_wapper.style.left=-(index*routersWidth)+'px';
   };

   /* 5、实现自动轮播 */
   setInterval(()=>{//时钟,每秒触发一次
     routers_wapper.style.transition="0.5s"//过渡为0.5s
     index++;
     routers_wapper.style.left=-(routersWidth*index)+'px';//重新根据下标,计算偏移
     if(index>=routerNumber){//如果滚到最后一张图片,瞬间将下标切换到第一张
       index=1;
       routers_wapper.style.transition="none"//这里不能有过渡效果,因为要让用户看不出来,瞬间切换
       routers_wapper.style.left=-(routersWidth*index)+'px';//根据下标计算偏移
     }
   },1000);

   /* 6、实现手指滑动*/
   let startX,startY,moveX,moveY;/* 开始时的坐标,移动时的坐标,结束时的坐标 */
   let distanceX,distanceY;/* 用来记录坐标直接的差异 */
   /* 添加开始触摸监听事件*/
   routers.addEventListener('touchstart',(e)=>{
     /* 获取第一个手指对象的触屏坐标*/
     startX=e.targetTouches[0].clientX;
     startY=e.targetTouches[0].clientY;

   });
   /* 添加滑动事件*/
   routers.addEventListener('touchmove',(e)=>{
     /* 获取每次滑动的触屏坐标*/
     moveX=e.targetTouches[0].clientX;
     moveY=e.targetTouches[0].clientY;
     /* 计算与开始坐标的差异*/
     distanceX=moveX-startX;
     distanceY=moveY-startY;

     /* 设置偏移*/
      if(distanceY<0 && Math.abs(distanceY)>=50){
        this.routersFlag=true;
      }
      else if(distanceY>0 && Math.abs(distanceY)>=50){
        this.routersFlag=false;
      }




   })
   /* 添加结束触摸事件*/
   routers.addEventListener('touchend',(e=>{
     if(distanceX<0 && Math.abs(distanceX)>=50){
       index++
       if(index===routerNumber-1){
         routers_wapper.style.left=-(index*routersWidth)+'px';
         routers_wapper.style.transition="none";
         index=1;
         routers_wapper.style.left=-(index*routersWidth)+'px';
       }
       else{
         routers_wapper.style.transition="0.5s";
         routers_wapper.style.left=-(index*routersWidth)+'px';
       }

     }
     else if(distanceX>0 && Math.abs(distanceX)>=50){
       routers_wapper.style.left=-((index-1)*routersWidth)+'px';
     }
     console.log(distanceX)
   }));

十二、分模快构建路由(不同功能分离路由)

  • 1、创建子路由文件,构建数组即可(路由主文件的主旨就是个数组)在这里插入图片描述
  • 2、index.js中添加子路由文件在这里插入图片描述
  • 3、子路由(如何构建子路由)在这里插入图片描述
  • 子模块路由如何重定向在这里插入图片描述

十三、ES6的Promise配合axios处理ajax的封装js

Object.keys(Obj):返回一个由给定对象自身可枚举属性组成的数组

//数组
	var arr = ['a', 'b', 'c'];
	console.log(Object.keys(arr)); // console: ['0', '1', '2']
	
	// 对象
	var obj = { key1: 'a', key2: 'b', key3: 'c' };
	console.log(Object.keys(obj)); // console: ['key1', 'key2', 'key3']

stringObject.substring(start,stop): 方法用于提取字符串中介于start和stop两个指定下标之间的字符。
stringObject.lastIndexOf(str[,index]):方法可返回子串str在父串stringObject中最后出现的位置,在一个字符串中的指定位置从后向前搜索。

str:表示需要查找的子串
index:可选参数,指定从哪个下标开始,从后往前找,不指定就从最后一个找
/*
  ajax请求封装

  @param:
          url:请求地址
          data:请求参数
          type:请求类型
  return:Promise对象

*/

import axios from 'axios'
export default function ajax(url,data={},type='GET'){
    /*
      Promise用来处理ajax请求问题,有3个状态,Pending(进行中)、Resolved(已完成)、Rejected(已失败)
      3个状态都是根据ajax请求结果而决定
     */
    return new Promise(function(resolve,reject){
      /* 1、执行异步*/
      let promise;
      if(type==='GET')
      {
        let dataStr='';//存储用data数据拼接成字符串

        Object.keys(data).forEach(key=>{//将data中的key遍历成一个新数组,然后循环遍历key,根据key将data中数据拼接成字符串
          dataStr+=key+'='+data[key]+'&';//将data中数据都以json的格式拼接到dataStr中,末尾用&,是为了标识结尾
        });

        if(dataStr !=''){
          dataStr=dataStr.substring(0,dataStr.lastIndexOf('&'));
          url=url+'?'+dataStr;
        }
        //发送ajax请求
        promise=axios.get(url);
      }else{
        //发送post请求
        promise=axios.post(url,data);
      }
      promise.then(function(response){
        /* 2、请求成功,执行resolve()*/
        resolve("session");
      }).catch(function(error){
        /* 3、请求失败,执行reject()*/
        reject('error');
      });
    })
}

十四、封装交互接口

在这里插入图片描述

/* 接口请求封装模块
    所有接口用req开头
    接口基本用ajax和后台进行交互
    所以所有接口都用固定模板
*/

import ajax from './ajax.js'
/* 1、根据经纬度获取位置详情 */
export function reqAddress(geohash)=>ajax(`/position/${geohash}`);
/* 2、获取食品分类列表 */
export function reqFoodTypes=()=>ajax('/index_category');
/* 3、根据经纬度获取商铺列表 */
/* 这里参数传递用的是ES6语法,longitude:longitude 可以简写成longitude  而传入b,后台规定参数名字为latitude,就得写出latitude:b */
export function reqFoodTypes=(longitude,b)=>ajax('/shop',{longitude,latitude:b});
/* 4、根据经纬度和关键字搜索商铺列表 */

/* 5、获取一次性验证码 */

/* 6、用户名密码登陆 */

/* 7、发送短信验证码 */

/* 8、手机号验证码登陆 */

/* 9、根据会话获取用户信息 */

/* 10、用户登出 */

鼠标事件

@mousedown:当用户单击鼠标按钮而元素有焦点时触发。
@mousemove:当鼠标移动而指针指向元素时触发。
@mouseout:当鼠标指针离开元素时触发。
@mouseover:当鼠标指针移动到元素上时触发。
@mouseup:当元素有焦点时,用户释放鼠标按钮时触发。
@mousewheel:当用户旋转鼠标滚轮而元素有焦点时触发。

@mouseenter:当鼠标指针进入元素时触发。这俩在元素中,移动到子元素上不会失去焦点
@mouseleave:当鼠标指针离开元素时触发。

动态添加事件为 <button> 元素添加点击事件。 当用户点击按钮时,在 id="demo" 的 <p> 元素上输出 "Hello World" :

document.getElementById("myBtn").addEventListener("click", function(){
	    document.getElementById("demo").innerHTML = "Hello World";
	});

十五、跳转路由,带有自己的激活样式

<router-link to="/" tag="a" active-class="current" exact>首页</router-link>

active-class:当前路由激活时的样式
exact:避免选择其它路由时,当前路由的激活样式还在

十六、事件传递当前节点

<a href="javascript:;" @click="getChildren($event,item,0)">{{item.title}}</a>

$event是点击对象,

getChildren(e,item,index){//e是当前点击元素,item是每一个课程分类对象,index是层级,0表示根层级
console.log(e.target)
e.target.style.color="red";

e.target 是当前点击元素

十七、操作style

<div class="L-c-form" :style="{'display':(!activeFlag?'block':'none')}">
				
</div>

十八、Vue强制刷新页面

this.$router.go(0)//强制刷新页面

组件刷新有v-if和改变:key的值两种方法

十九、store操作

store文件代码

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
	  input:"",//全局搜索关键字
	  publicSearchFlag:true,//全局搜索true表示搜索课程名,false表示搜索讲师名
	  publicSearchWatch:true,//全局搜索监听函数,解决相同路由点击搜索按钮不刷新的问题
	  
	  token:localStorage.getItem("token"),//全局存放token,这里直接通过localSrotage获取,这样就省去了get的过程
	  userInfo:JSON.parse(sessionStorage.getItem("userInfo")),//全局存放用户信息,通过JSON反序列化,将用户数据拿到
	  loginFlag:false,//用来标识当前登录状态,false表示没有登陆
	  
  },
  mutations: {//这个就相当于java的set方法
	  SET_TOKEN:(state,token)=>{//设置值到token
		  state.token=token;
		  localStorage.setItem("token",token);//将token存储到localStorage中,就是存储在客户端
	  },
	  SET_USERINFO:(state,userInfo)=>{//设置用户信息
		  state.userInfo=userInfo;
		  sessionStorage.setItem("userInfo",JSON.stringify(userInfo));//将用户信息存放到session会话中,这个方法不能穿对象,所以通过JSON序列化
	  },
	  SET_LOFIN_Flag:(state,loginFlag)=>{//设置登陆状态
		  state.loginFlag=loginFlag;
	  },
	  SET_LOGOUT:(state)=>{//退出时,清除所有数据
		  state.token='';
		  state.userInfo={};
		  state.loginFlag=false;
		  state.avatar='';
		  localStorage.setItem("token",'');
		  localStorage.setItem("Access-Token",'');
		  sessionStorage.setItem("userInfo",JSON.stringify(''));
	  }
  },
  getters:{
	  //get
	  getUserInfo:state=>{
		 return state.userInfo
	  },
	  getToken:state=>{
		 return state.token
	  }
  },
  actions: {
  },
  modules: {
  }
})

store设置值,获取值

this.$store.commit("SET_USERINFO",response.data);//通过set方法设置值
this.$store.getters.getUserInfo//通过get方法获取值
this.$store.state.publicSearchFlag//通过state获取

二十、深度监听,解决路由地址没变的情况下,数据无法动态刷新

在这里插入图片描述在这里插入图片描述在这里插入图片描述

二十一、跳转路由从新页面打开

用这个语句代替this.$router.push等跳转语句即可

let routeData = this.$router.resolve({
   name: "Player",
   query: {courseId:this.$route.query.courseId,minutiaName},
   params:{id:videoPath}
});
window.open(routeData.href, '_blank')

二十二、vue网络请求会自动带上localhost:8080/

直接写会默认带上localhost
192.168.10.105:8888/
需要加上协议http://
http://192.168.10.105:8888/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

殷丿grd_志鹏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值