Vue.js

安装

npm 安装

  1. 创建文件夹,在文件夹目录执行指令
  2. vue init webpack myvue (vue2)
  3. 手动创建所需环境在这里插入图片描述
  4. cd 文件夹 : cd myvue
  5. 安装依赖环境 在当前目录: npm install
  6. 运行: npm run dev

引入

	开发环境版本,包含了有帮助的命令行警告
	<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

vue-cli

vue2

vue init webpack project

vue3

vue create project

图形化界面

vue ui

指令

runtime-compiler 和runtime-only

runtime-compiler

template ->(解析) ast(抽象语法树)->(编译) -> render函数 ->虚拟dom - > 渲染到真实dom

runtime-only

具有更好的性能
render -> virtual dom -> ui
在这里插入图片描述

前端路由

以往的后端路由
到现在主流的前后端分流
现在vue路由

  1. location.hash=’ ’
  2. history.pushState({},’ ‘,’ ') data,title,url
  3. history.replaceState({},’ ‘,’ ') data,title,url 无法返回

vue-router

配置

在这里插入图片描述

index.js

在这里插入图片描述

默认路由
export default new Router({
  routes: [
    // 默认路由
    {
        path:'/',
        redirect:'/Home'  //重定向到Home
    },
    {
        path:'/Home', 
        name:'Home',
        component:Home
    },
    {
        path:'/About',
        name:'About',
        component:About
    },
  ]
})
hash模式修改

在这里插入图片描述

main.js

引入相关文件
render函数(相当于el:)
在这里插入图片描述

页面导出

在这里插入图片描述

router-link

  1. 路由定向
    to=“”
<router-link to="/Home">Home</router-link>
  1. 指定渲染 tag
    tag=“button” 将当前元素渲染成buton
<router-link to="/Home" tag="button">Home</router-link>
  1. replace 相当于 replaceState
    将不可返回
<router-link to="/Home" tag="button" replace>Home</router-link>
<router-link to="/About" tag="button"  replace>About</router-link>
  1. active-class(默认类名)
    在vue中router-link 默认触发的类名为
    router-link-class
    在这里插入图片描述
    可以使用active-class修改默认类名
<router-link to="/Home" tag="button" replace active-class="active">Home</router-link>

在这里插入图片描述
5. linkActiveClass 全局修改默认class
在配置路由处

export default new Router({
  routes: [
    // 默认路由
    {
        path:'/',
        redirect:'/Home'  //重定向到Home
    },
    {
        path:'/Home', 
        name:'Home',
        component:Home
    },
    {
        path:'/About',
        name:'About',
        component:About
    },
  ],
  mode:'history',
  linkActiveClass:'linkActive'
})

$router (代码跳转路由)

route 与 router

      //	$router 是 const router = new VueRouter({})
      //	$route 获取当前活跃的路径

代码跳转路由
1.添加事件

<template>
  <div id="app"> 
     <h1>欢迎</h1>
    <button @click="linkToHome">首页</button>
    <button @click="linkToAbout">关于</button>
    <router-view></router-view>
  </div>
</template>

2.使用vue中的$router(每个组件都有的属性)修改路径
this.$router.push/replace无法返回

export default {
  name: 'App',
  methods:{
      linkToHome(){
          this.$router.replace('/Home').catch(err=>err) //需要catch 否则控制台报错
      },
      linkToAbout(){
          this.$router.replace('/About').catch(function(err){return err;})
      }
  }
}

动态路由 (同组件使用不同路径)

默认子路由

在这里插入图片描述

动态路径参数 /user/:userid

1.this.$router
2.this.$route
3.配置路径参数'user/:userid'  冒号后为参数 ,不同路径会跳转到同一个user路由

在某些情况,路径可能不确定,或者需要传递值

index.js
实例化路径配置与导出

// 1.引入相关组件
import Vue from 'vue'
 
 
import Home from '../components/Home'
import About from '../components/About'
import User from '../components/User.vue'
import VueRouter from 'vue-router'

// 2.Vue实例化router
Vue.use(VueRouter)

// 配置路径
const routes=[
    // 默认路径
    {
        path:'',
        redirect:'/home'
    },
    {
        path:'/home',
        component:Home
    },
    {
        path:'/about',
        component:About
    },
    {
        //$route
        path:'/user/:userid',
        component:User
    }
]

//配置路由和组件间的应用关系
const router=new VueRouter({
    routes,
    mode:'history',
    linkActiveClass:'active'
})

 
// 3.导出路由相关配置
export default router

app.vue
拼接data到 router-link 实现 动态path

<template>
  <div id="app">
    <!-- 动态路由
    某些情况需要动态修改path路径,或者传值 -->
    
    <router-link to="/home">首页</router-link>
    <router-link to="/about">关于</router-link>
    <router-link :to="'/user/'+name">用户</router-link>
   				
    <router-view></router-view>
  </div>
</template>

<script>
 
export default {
  name: 'App',
  data(){
      return{
          name:'xwt',
      }
  },
  methods:{
      linkToHome(){
          //$router 是 const router = new VueRouter({})
          //$route 获取当前活跃的路径
          this.$router.replace('/Home').catch(err=>err) //需要catch 否则控制台报错
      },
      linkToAbout(){
          this.$router.replace('/About').catch(function(err){return err;})
      }
  }
}
</script>

User.vue
this.$route获取当前活跃路径

<template>
<div>
   <h1>{{$route.params.userid}}</h1>
   欢迎用户: {{userID}}
</div>

</template>

<script>
export default {
    name:'User',
    computed:{
        userID(){
            // this.$route 获取当前活跃的路由
            console.log(this.$route);
            return this.$route.params.userid
        }
    }
}
</script>

开启props传参

在这里插入图片描述

vue-router懒加载

当打包构建应用时,JS文件会非常大,影响页面加载
如果打包时将不同的路由分割成不同的代码块,
并在需要使用时再引入进来
,这样效率会高很多

传统引入路由方式

import Home from '../components/Home'
import About from '../components/About'
import User from '../components/User.vue'

懒加载

const Home=()=>import('../components/Home.vue')
const About=()=>import('../components/About.vue')
{
    path:'/about',
    component:About
}{
	path:'/about',
	component:()=>import('../components/About.vue')
}

路由嵌套

在这里插入图片描述
News.vue

  1. 子路由导出
<template>
  <ul>
      <li>金泰</li>
      <li>阿斯顿</li>
      <li>官方</li>
      <li>自行车</li>
  </ul>
</template>

<script>
export default {
    name:'News'
}
</script>
<style>
</style>

Home.vue
2. 父组件router-link 指定跳转路由
router-view 显示子路由

<template>
  <div>
      <h2>Home</h2>
     <h3> Welcome my home</h3>
     <router-link  to="/home/main">个性化</router-link>
     <router-link  to="/home/News">新闻</router-link>
     <router-view></router-view>
  </div>
</template>

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

<style>
body{
    background-color:rgb(106, 196, 202);
}
</style>

index.js
3. 在父路由中使用数组嵌套子路由
children:[ ] 一个路由可以有多个子路由,所以为数组[ ]

 {
        path:'/home',
        component:Home,
        children:[
            // 默认路径
            {
                path:'',
                redirect:'main'
            },
            {
                path:'main',
                component:Profile
            },
            {
                path:'News',
                component:News
            }
        ]
    
    }

路由传参

路由参数传递 router-link

在这里插入图片描述

params
  1. index.js 在路由配置中 指定参数名
	{
        path:'/user/:userid',
        component:User
    }
  1. 主页App.vue路由地址拼接上参数
<router-link :to="'/user/'+name">用户</router-link>
export default {
  name: 'App',
  data(){
      return{
          name:'小文涛',
      }
  }
}
  1. User.vue 中可以使用$route.params.参数名 获取参数
<template>
<div>
  <h1>{{$route.params.userid}}</h1>
   欢迎用户: {{userID}}
</div>
</template>
<script>
export default {
    name:'User',
    computed:{
        userID(){
            // this.$route 获取当前活跃的路由
            console.log(this.$route);
            return this.$route.params.userid
        }
    }
}
</script>
<style>
</style>

$this.route 获取当前活跃路由
在这里插入图片描述

query
  1. 配置路由(普通方式)
    {
        path:'/Info',
        component:Info
    }
  1. 指定路径与参数
    <router-link :to="{path:'/Info',
                       query:{name:'dfs',age:18,height:1.88}}">信息
    </router-link>
  1. 获取数据
<template>
<div>
  <ul>
      <li>name:{{$route.query.name}}</li>
      <li>age:{{$route.query.age}}</li>
      <li>height:{{$route.query.height}}</li>
        
  </ul>
  <!-- 获取query -->
    <h1>{{$route.query}}</h1>
    
  <!-- 获取当前活跃路由 -->
    <h2>{{getQuery}}</h2>
</div>
</template>

<script>
export default {
    name:'Info',
    computed:{
        getQuery(){
            return console.log(this.$route);
        }
    }
}
<template>
<div>
  <ul>
      <li>name:{{$route.query.name}}</li>
      <li>age:{{$route.query.age}}</li>
      <li>height:{{$route.query.height}}</li>
        
  </ul>
  <!-- 获取query -->
    <h1>{{$route.query}}</h1>
    
  <!-- 获取当前活跃路由 -->
    <h2>{{getQuery}}</h2>
</div>
</template>

<script>
export default {
    name:'Info',
    computed:{
        getQuery(){
            return console.log(this.$route);
        }
    }
}

路由参数传递 方法形式

params
<button @click="aboutClick">关于 </button>
	aboutClick(){
          // params
          this.$router.push({
              path:'/about',
              params:'小问题'
          })
          console.log(this.$route);
      }
query
<button @click="infoClick">信息</button>
	infoClick(){
          // query
          this.$router.push({
              path:'/Info',
              query:{
                  name:'大番薯',
                  age:18
              }
          })
      }

导航守卫

next的3中调用方式

在这里插入图片描述

[全局前置守卫] beforeEach

to: 将要进入的路由
from: 当前导航将要离开的路由
next: function()

动态添加标题 (同级)
传统js方式 (性能较差)

    // 实例被创建后调用
    created(){
        document.title='信息'
    }

为每个路由添加meta,meta的值将会保存到to中
to.matched[0].meta.title 调用

    {
        path:'/about',
        meta:{title:'关于'},
        component:About
    },
    {
        //$route
        path:'/user/:userid',
        meta:{title:'用户'},
        component:User
    },
    {
        path:'/Info',
        meta:{title:'信息'},
        component:Info
    }

to.matched[0].meta.title

const router=new VueRouter({
    routes,
    mode:'history',
    linkActiveClass:'active'
})
router.beforeEach((to,from,next)=>{
    console.log(this); //VueRouter
    console.log('to',to); 
    console.log('from',from);     
    document.title=to.matched[0].meta.title    
    next()
})

全局后置钩子

没有next 参数

router.afterEach((to,from)=>{
    console.log('after');
})

路由独享守卫

在路由定义,方法与全局相同 Each 改为 Enter

    {
        path:'/about',
        meta:{title:'关于'},
        beforeEnter:(to,from,next)=>{
            console.log('路由守卫to',to);
            console.log('路由守卫from',from);
            next()
        },
        component:About,
    }

组件守卫

权限控制

token

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

封装path 权限控制

  1. 将需要权限控制的路径 模块化
    在这里插入图片描述
  2. 在需要出导入 判断是否存在该路径
    在这里插入图片描述

基本

1. {{}}插值表达式 v-text v-html v-on

v-on=“” 简写
:事件=“方法”

<div id="app">
            {{}}替换部分内容 存在替换不及时问题,需要加入v-cloak.
            使用v-text不会出现这种问题
            <p>{{name}}{{age+'岁:'}} {{}}替换部分内容</p> 

             v-text将会替换所有内容 
            <p v-text="name+':'">替换这里所有内容</p>   

             v-html
             存在安全性问题
            <p v-html="content">将会解析为html标签</p>
            
			 v-on:方法=""  简写 @方法=""		:keyup.enter="num(1,2)" 可以传参
            <div id="colorChange" v-on:click="changeColor" @dblclick="alert"></div>
</div>
    
    <script>
    let app=new Vue({
        el:'#app',		//挂载到id为app
        data:{			//数据
            name:"大番薯",
            age:22,
            content:'<a href="http://www.baidu.com">跳转百度</a>'
        },
        methods:{		//方法
            changeColor:function(){
                let changeColordiv=document.querySelector("#colorChange");
                changeColordiv.style.backgroundColor="blue";
            },
            alert:function(){
               this.name+="很聪明,"   //通过this可以获取到data的数据   
            }
        } 
    })
</script>

在这里插入图片描述

v-cloak 解决{{}} 解析延迟的问题

在某些情况可能出现解析延迟,{{}}闪动

<style>
	[v-cloak]{
		display:none
	}
</style>
<div v-cloak>{{message}}
</div>

事件的传参

传递event 需要将 $event 放在最后一位参数

<div @click="test(1,$event)">{{mes}} </div>
 methods:{
            test:function(a,event){
                console.log(a);
                console.log(event.target);
            }
        }
没有传参可以省略括号
<button @click='btn1()'>btn1 </button>
<button @click='btn1'>btn1 </button>
 	  //有参数,不传参数不会报错,   但传了参数必须声明参数
      //没有传参可以省略()
      btn1(v){
        console.log('btn1');
      },
不传参数默认传递event
<button @click='btn2'>btn2 </button>
//不传参数浏览器默认传递 event
      btn2(event){
        console.log('btn2',event);
      }
传参+传递event

event需要放在最后一位

<button @click='btn3(123,$event)'>btn3 </button>
//传参数,传event 传参时需要加上 $
      btn3(var1,event){
        console.log('btn3',var1,event);
      }

计数器

通过this可以获取到data的数据

<div class="count">
        <button id="pre" @click="pre" >-</button>
        <div>{{num}}</div>
        <button id="next" @click="next">+</button>
</div>
    <script>
        let count=new Vue({
            el:".count",
            data:{
                num:0
            },
            methods: {
                pre:function(){    
                     if(this.num<=0){
                         alert("Err")
                     }
                     else
                     this.num--;   
                },
                next:function(){
                    if(this.num>=10){
                        alert("太大了")
                    }
                    else
                    this.num++; 
                }
            },
        })
    </script>

在这里插入图片描述

v-show v-if

根据表达式判断显示与否

v-show:适合频繁使用
v-if:性能较差

v-show 对表达式进行判断,true为显示,false 不显示
实际上切换display
v-if	
删除dom树

在这里插入图片描述

<div id="app">                     
        <button @click="add">增加</button>
        <button @click="toggle">切换</button>
        <div style="background-color: green;" v-if="isShow">isShow</div>     
        <div style="background-color: greenyellow;" v-show="num>=18">判断num</div>    
    </div>
</body>
<script>
    let app = new Vue({
        el: "#app",
        data: {
             isShow:false,      //boll值
             num:17,            //条件表达式
        },
        methods: {
             add:function(){
                 this.num++;
             },
             toggle:function(){
                 this.isShow=!(this.isShow);
             }  
        },
    })
</script>

在这里插入图片描述

v-bind

v-bind :代替标签属性
简写 :src :title :class 等等

<style>
        .filter{
            filter: invert(1);
        }
    </style>
<div id="app">
    // v-bind  简写:src 可以使用任何属性title,class 等
    // 三目运算符,active为真时,使用filter,否则使用''  
    <img v-bind:src="VBind" :class="!active?'filter':'' "@click="toggle"> 
    
    //filter是否生效,取决于active 
    <img :src="dx" :class="{filter:active}" @click="toggle">
    <img :src="imgSrc" :title="title" :class="changeClass" @click="toggle">   
</div>
</body>
<script>
    let app=new Vue({
        el:"#app",
        data:{
            imgSrc:'https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=394698104,1302019637&fm=26&gp=0.jpg',
            VBind:'https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=4092687158,279235402&fm=11&gp=0.jpg',
            dx:'https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=3197142773,3370367977&fm=26&gp=0.jpg',
            title:'测试一下v-bind',
            active:false,
            changeClass:'filter'
        },
        methods: {
            toggle:function(){
                this.active=!this.active;
            }
        },
    })
</script>
对象操作类的切换

在以往js操作dom修改类过于复杂
在vue里可以使用对象较为简单

 <div id ="app"> 
    <!-- 对象操作类的切换 -->
    <div :class="{greenYellow:greenYellow,skyBlue:skyBlue}"></div>
    <button @click="changeColor">切换</button>
  </div>
data: {
      message:'hello',
      greenYellow:true,
      skyBlue:true
    },
    methods: {
      changeColor:function(){
        this.skyBlue=!this.skyBlue
      }
    }
方法return 类

也可以通过方法 return 返回类名
记得带括号()

<div :class="changeColor()"></div>
changeColor:function(){
        return this.greenYellow;
      }
数组形式

以数组形式也可以添加多个类(不常用)

<div :class="[greenYellow,skyBlue]"></div>
data: {
      greenYellow:'greenYellow',
      skyBlue:'skyBlue'
    },

同样也可以同时添加多个类

<div :class="changeColor()"></div>
changeColor:function(){
        return [this.greenYellow,this.skyBlue]
      }
:class 不会覆盖 原有的class

可以将静态的不改变的类使用class=‘’ 添加
动态则操作数据 :class

:style

style里的属性使用驼峰命名

							拼接
<div :style='{width:width ,height:height+"px",backgroundColor:backgroundColor}'></div>
data:{
	  width:'200px',
      height:200,
      fontSize:'20px',
      backgroundColor:'green'
}

或者使用方法返回

<div :style='getStyle()'></div>
getStyle:function(){
        return {width:this.width ,height:this.height+"px",backgroundColor:this.backgroundColor}
      }

绑定样式2

{ }

对象形式 { 类名 : bool值 }

style{
	border:1px solid black
}

对象的方式添加类名,后接上bool值

<div :class="{style:isActive}"></div>

可以添加多个

<div :class="{style:isActive,bg:isBg}"></div>
data:{
	isActive:true;
},
[ ]

[ data1 , data2 ] 添加数据

<div :class="[data1 ,data2 ]">大番薯</div>

在data 里添加类名 添加

data:{
        data1:'style1',	类名 style1
        data2:'style2'
     },
混合使用
<div :class="[class1,class2,{style:isstyle}]"></div>

不会覆盖原来的class
将会添加两个类 class=" style1 style2 "

<div> class="style1" :class="{style2:isStyle2}" </div>
内联样式添加

在这里插入图片描述
在这里插入图片描述
对象
在这里插入图片描述
在这里插入图片描述
也可以使用 [ ] 添加多个对象形式的样式

v-for

三个值
v-for=" value key index" 值 键 下标
两个值
v-for=" key index " 键 下标

<body>   
    <ul id="app">
    <button  @click="add">添加</button>
    <button @click="remove">删除</button>
        <li v-for="items in arr1">	//items名称可自定义  a in arr1
            {{items}}			
        </li>
        <li v-for="(items,index) in arr2">	//打印下标
           {{index+1}} {{items.name}}		//index从0开始,itmes对象.name取值
        </li>
    </ul>
</body>
<script>
    let app=new Vue({
        el:"#app",
        data: {
            arr1:["大地瓜","小番茄","大头"],
            arr2:[
                {name:"大番薯"},
                {name:"小地瓜"},
                {name:"好好吃"}
            ]   
        },
        methods: {
            add:function(){
                this.arr1.push("香啊~");
            },
            remove:function(){
                this.arr2.shift();
            }
        },
    })
</script>

在这里插入图片描述

key

使用v-for 建议加上key key唯一的
items的增删改查 没有key 将会使diff 算法效率低下

在B后插入F
在这里插入图片描述
没有加上key的执行状况
将C更新为F, D更新为C E更新为D
在这里插入图片描述

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

vue中清除/添加 类

在原生js中,点击添加类需要先清除,后添加
vue中给类添加判断表达式 {类名:CurrentIndex===index}
通过修改CurrentIndex为v-for的 index

  1. 0===0
  2. 1===0
  3. 2===0
<button v-for="(item,index) in page" :class="{green:CurrentIndex===index}" @click="changeColor(index)">{{item}}</button>
data: {
      page:[1,2,3,4,5,6,7,8],
      CurrentIndex:0
    },
    methods: {
      changeColor(index){
        this.CurrentIndex=index
}      

在这里插入图片描述

v-model

便捷设置和获取表单元素的值
绑定的数据会表单元素相关联
数据===表单元素 双向绑定

<body>
   <div id="app">
       <input type="button" value="更改" @click="change">
       <input type="text" v-model="value" @keyup.enter="click"><br>
       {{value}}
   </div>
</body>
<script>
    let app=new Vue({
        el:"#app",
        data:{
            value:"请输入"
        },
        methods: {
            click:function(){
                alert(this.value);
            },
            change:function(){
                this.value="随便改";
            }
        },
    })
</script>

在这里插入图片描述

实际上是v-bind 和v-on的结合

input 有一个 事件 oninput 输入事件
@input=" "
把事件获取的值传给数据mes
在这里插入图片描述

v-model 绑定input其他类型

radio

可以省略name 使用v-model=''绑定data值" v-model相当于替换name
v-model选中值为当前input 的value
设置初始值为value 则默认选中

<!-- for绑定id   相同name 绑定同类, value, 使用v-model可以省略name  -->
    <label for="male">
      <input type="radio" name="sex" id="male" value=""  v-model="picked"></label>
    <label for="famale">
      <input type="radio" name="sex" id="female" value="" v-model="picked"></label>
    <h2>{{picked}}</h2>
data: {
      picked:'男'
    }
  <div id ="app"> 
    <label for="male">
    <!-- v-model 绑定value , 相当于替代name, 只有name相同时,才可以提交,只能提交一个值 , 给v-model赋初始值,则默认选中(设置为value值) -->
      <input type="radio"   id="male" value="男性"  v-model="sex"></label>
    <label for="famale">
      <input type="radio"   id="female" value="女性" v-model="sex"></label>
    <h2>{{sex}}</h2>
  </div>
data: {
      sex:'male', 
    }
checkbox

单选绑定的是bool值,无论data何

<!-- checkbox单选 绑定的是bool值,无论data何值 -->
    <input type="checkbox"  value="check" id="single" v-model="bool">
    <label for="single">是否选中{{bool}}</label>
    <button :disabled="!bool">我已阅读</button>
 data: {
      bool:false,
    }

多选绑定value值

<!-- checkbox多选,绑定value值 -->
    <input type="checkbox"  value="小文涛" id="xwt" v-model="name">
    <label for="xwt">小文涛</label>

    <input type="checkbox" value="林枸杞" id="lgq" v-model="name">
    <label for="lgq">林枸杞</label>

    <input type="checkbox" value="大番薯" id="dfs" v-model="name">
    <label for="dfs">大番薯</label>
    <h2>{{name}}</h2>
data: {
      name:[]
    }

值绑定

<label v-for="item in bind" :for="item">
                          <!-- 值绑定 -->
     <input :id="item" type="checkbox" :value="item" v-model="name">{{item}}
     </label>
     <h2>{{name}}</h2>
data: {
      name:[],
      bind:["可口可乐","百事可乐","雪碧","果粒橙","王老吉"]
    }
select

单选, 绑定给select, 绑定value

<select   v-model="select"> 
      <option value="小文涛">小文涛</option>
      <option value="林枸杞">林枸杞</option>
      <option value="刘德华">刘德华</option>
      <option value="大番薯">大番薯</option>
      <option value="张学友">张学友</option>
    </select>
    <h2>selected:{{select}}</h2>
data: {
      select:"刘德华",
    }

多选

<select v-model="multipleSelect" multiple style="width: 50px;">
      <option value="苹果">苹果</option>
      <option value="香蕉">香蕉</option>
      <option value="菠萝">菠萝</option>
      <option  value="西瓜">西瓜</option>
    </select>
    <h2>多选:{{multipleSelect}}</h2>
data: {
      multipleSelect:[]
    }
v-model修饰符
 <!-- lazy将在 change时改变, 而不是input时 -->
    <input type="text" v-model.lazy="lazy">
    <h2>{{lazy}}</h2>

      <!-- .number将input.value内容转换为number -->
    <input type="text" v-model.number="number">
    {{typeof(number)}}
    <br>
    <br>

    <input type="text" v-model.trim="trim" >
    {{trim}}
data: {
      lazy:'',
      number:'',
      trim:''
    }

v-html

将值解析为html

v-pre

不解析

分支结构 v-if v-else-if v-else

在这里插入图片描述

虚拟dom问题

在vue中 会尽可能复用不改变的内容, 这里如果不加key,不会改变 input框的value 加上key 会重新创建一个input

不加key将会复用

      <div v-if='showForm'>
      用户名: <input type="text" placeholder="请输入账号">
      </div>
      <div v-else>
        邮箱登录: <input type="email" placeholder="请输入邮箱">
      </div>
      <button @click='changeType'>切换登录方式</button>

在这里插入图片描述
vue虚拟dom将会复用相同的内容,导致value值不被改变
在这里插入图片描述
加上key , 将会重新创建

<div v-if='showForm'>
      用户名: <input type="text" placeholder="请输入账号" key='text'>
      </div>

循环结构

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

v-cloak

插值表达式{{}} 存在加载慢导致"闪动"替换不及时等问题
使用[v-cloak]提前设置display:none 在要使用的地方加上v-cloak

css

    [v-cloak]{
        display: none;
        background-color: white;
    }

html

	<div id="app">
        <div v-cloak>{{mes}} </div>
    </div>

js

    let app=new Vue({
        el:'#app',
        data:{
            mes:'测试cloak'
        },
    })

v-pre

v-pre将会跳过编译 {{ }}

<div v-pre>{{mes}} </div>

v-once

v-once将只会渲染一次,不会再更改
应用:不需要再次修改的数据

<div v-once>{{mes}}</div>

事件修饰符

取消冒泡

原生js

function(event){
	 event.stopPropagation();
}

vue

<div @click.stop="test">跳转</div>

取消默认行为

原生js

function(event){
	 event.preventDefault();
}

vue

<a @click.prevent="test" href="http://www.baidu.com">跳转</a> 

按键修饰符

keyup.enter 事件.按键

<div @keyup.enter="method"></div>
<div @keyup.delete="method"></div>

也可以自定义
自定义按键
a键

<input type="text" @keyup.a="test()" >点击</input> 

keyCodes

<input type="text" @keyup.65="test()" >点击</input> 

computed 计算属性

计算属性将会被缓存,具有更好的性能

<h2>{{fullName}}</h2>
computed:{
      fullName:{
        //set 一般不使用    set可以传值
        set:function(setName){
          const name=setName.split(' ');
          this.firstName=name[0],
          this.lastName=name[1]
        },
        get:function(firstName){
          return this.firstName+' '+this.lastName
        }
      }
    }
   });

在这里插入图片描述
调用fullName 相当于调用set 方法
在这里插入图片描述

watch 侦听器

方法侦听器

缺点:

  1. 无法在页面初始化时调用
  2. 无法侦听对象中的属性值

参数 1. 新值 2.旧值

watch:{
	get(newVal,oldVal){
	}
}

对象侦听器

立即执行 immediate

优点:

  1. 可以立即触发 immediate:true
  2. 可以侦听对象中的属性 deep 对象.属性

将侦听器改为对象
使用handle() 作为执行函数
immediate:true
// true 为立即执行
// false

<div id="app">
        <input type="text" v-model="mes"  id="">
        {{mes}}
    </div>
    <script>
        new Vue({
            el:'#app',
            data() {
                return {
                    mes:'你好'
                }
            },
            watch:{
                
               /*  mes(newVal,oldVal){
                    console.log(newVal,oldVal);
                }, */
                // 立即执行侦听器
                mes:{
                    handler(newVal,oldVal){
                        console.log(newVal+'立即执行',oldVal);
                    },
                    immediate:true
                }
            }
        })
    </script>
单个属性侦听
	 watch:{
                // 单属性侦听
                'mes.name':{
                    handler(newVal){
                        console.log(newVal);
                    }
                }
                
            }

在这里插入图片描述

deep 深度监听

对象中任意一个属性变化,都会触发侦听器
在这里插入图片描述

$nextTick

$nextTick(callback) 将callback推迟到下一下Dom更新周期之后执行
等组件Dom更新完成后再执行callback函数
在这里插入图片描述

自定义指令

私有自定义指令

与data el同级
在这里插入图片描述

bind

bind函数只会触发一次, dom刷新不会继续执行bind函数
在这里插入图片描述

update

dom 更新会触发update函数
在这里插入图片描述

指令简写

当bind 和 update函数相同时 可以将自定义函数写成函数
在这里插入图片描述

全局自定义指令

Vue.directive(‘指令’,{})
也可简写成函数形式
在这里插入图片描述

  • binding在这里插入图片描述

生命周期

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

组件

在这里插入图片描述

在这里插入图片描述

  <div id ="app"> 
    <!-- 3. 使用组件 -->
    <cop></cop>
  </div>
 
  <script>
     1. 创建组件构造器对象
    const comp=Vue.extend({
      template: 
      `<div>hellow compoent</div>`

    })
    2. 注册组件 (这里是全局组件, 可以在多个vue实例下使用)
    Vue.component("cop", comp)
 
   let vm = new Vue({
    el: '#app',
    data: {},
    methods: {},
    
    局部组件, 仅在app下使用
    components:{
      cop:comp // key : value
    }
     
   });
  </script>

子组件

构造父子两个组件
父组件内注册子组件
vue实例中 注册父组件

 <div id ="app"> 
    <Parent></Parent>
  </div>
const son=Vue.extend({
      template:`
        <h2>son</h2>
      `
    })

    // 父组件内注册子组件    哪里注册,哪里使用 
    const parent=Vue.extend({
      template:`<div class="parent">
          		<sonWrap></sonWrap>
       	 		</div>`
        ,
      components:{
        sonWrap:son
      }
    })
    //Vue实例 为根组件
   let vm = new Vue({
    el: '#app',
    data: {},
    methods: {},
    // 调用父组件
    components:{
      Parent:parent,
    }
   })

组件语法糖

 (自定义组件名,{template:'绑定id'})
    Vue.component('head',{
      template:'#head'
    })
components:{
      'head1':{
        template:'#head'
      }
    }
 <div id ="app"> 
    <template id="head">
      <div>
        <h2>这里是header</h2>
      </div>
    </template>
  </div>

components:{
‘自定义标签名’:{
template : ’ #id ’
}
}

let vm = new Vue({
    el: '#app',
    data: {},
    methods: {},
    components:{
      'head1':{
        template:'#head'
      }
    }
   })

为什么组件data 是一个函数

如果vue使用对象保存data:{}
那么每次使用的组件将会共用这个data

<div id="app">
    <!--  使用自定义组件 -->
    <count></count>
    <count></count>
    <count></count>
</div>


  <template id="counter">
    <!-- template要包含一层div -->
    <div>
      <h2>{{num}}</h2>
      <button @click="num++">+</button>
      <button @click="num--">-</button>
    </div>

  </template>
    // 注册全局组件
    Vue.component('count', {
      template: '#counter',
      // 如果组件的data 不是函数,而是以对象形式,组件的data将会被每一个相同的组件使用  
      // 相当于定义了一个const 类型的变量 
      data() {
        return {
          num: 0,
        }
      }
    })

    let vm = new Vue({
      el: '#app',
    });

不同的作用域
在这里插入图片描述

数据共享的六种方案

在这里插入图片描述

provide inject

  • 原理 Object.create()
    在这里插入图片描述

父子组件的通信

在这里插入图片描述

父->子 props(自定义属性)

props只读属性
父->子传递数据 props
vue 向子组件child 传递 parent,age数组

不建议改变props的值

  <div id ="app"> 
    <child :parent="parent" :age="age"></child>
  </div>
 <template id="child">
   <div>
     <ul>
       <li v-for="item in parent ">
        {{item}}
       </li>
     </ul>
     <h2>{{age}}</h2>
   </div>
 </template>
let vm = new Vue({
    el: '#app',
    data: {
      parent:['小文涛','林枸杞','大番薯'],
      age:[21,22,20]
    },
    components:{
      'child':{
        template:'#child' ,
        // props 使用数组或对象
        props:['parent','age']
    }
多个传值
		{
         props:['parent','age']
        }

类型限制
components:{
      'child':{
       template:'#child' ,
         props:{
	         parent:String,
	         age:Number
         }
       }
}
必传值

required:true

 	props:{
          age:{
            // 必填字符串
            required:true
          },
        }
自定义验证函数
props:{
        // 5.自定义验证函数
        validator:function(value){
          return ["success","error","null"].indexOf(value)!=-1
        }
}
默认值

当数据为 Array 或 Object 时
默认值必须是函数

	 age:{
             // 4. 类型是对象或数组时, 默认值必须是函数
            type:Array,
            // vue2.* 版本以下  
            // default:[] , 将会报错 ,使用函数形式return
            default(){
              return [6,8,10]
            },
          }
驼峰命名需要使用- 连接
  <div id ="app">
    <!-- html Attribute 不区分大小写,如果使用驼峰命名,需要使用 -连接 -->
    <cmessage :c-info="info"></cmessage>
  </div>
<template id="cmes">
  <div>
    {{cInfo}}
  </div>
</template>
<script>
   const cmessage={
     template:'#cmes',
     props:{
       cInfo:{
         type:Array
       }
     }
   }
 
   let vm = new Vue({
    el: '#app',
    data: {
      info:[{
        class:1,
        name:'小文涛'
      },{
        class:2,
        name:'林枸杞'
      }]
    },
  
    components:{
       cmessage
    },

   });
</script>
$parent

获取当前组件的上一级组件

$root

获取根组件 vue实例

子->父 this.$emit

事件接收

在使用组件出监听 @自定义事件=‘接收事件’
接收事件使用形参获取 值

<div @send="get"></div>
methods:{
	get(val){
		console.log(val);
	}
}
<div id ="app">
    <!-- 在使用组件处 监听   @自定义事件="接收事件"  -->
    <child :childid="father"  @childsend="ParentGet"></child>
</div>
  <template id="childcomp">
    <div>
      <button v-for="item in childid" @click="send">{{item.name}}</button>
    </div>
  </template>
  <!-- 子组件向父组件发送信息,父组件接收信息返回 -->
<script>
    // 构造组件
    const child={
      template:'#childcomp',
      data(){
        return{
          childId:[1,2]
        }
      },
      props:{
        'childid':{
          type:Array
        }
        
      },
      methods:{
         send(){
           console.log('发射!',this.childId);
           //子组件 发送 this.$emit   
           
           return this.$emit('childsend',this.childId)
         }
      }
    }
   let vm = new Vue({
    el: '#app',
    data: {
      father:[{
        id:1,
        name:'大番茄'
      },
      {
        id:2,
        name:'小地瓜'
      },
      {
        id:3,
        name:'林枸杞'
      }]
    },
    components:{
      child
    },
    // 接收子组件的数据
    methods:{
      ParentGet(childId){
        console.log("爸爸接收到啦~",childId);
      }
    }
   });
  </script>
$event接收

$event 可接收子组件发给父组件的值
在这里插入图片描述

在这里插入图片描述

获取组件

$children

this.$children获取所有子组件 (基本不使用)

<div id ="app">
        <cpn ref="message"></cpn>
        <cpn></cpn>
        <button @click="click">点击</button>
    </div>
<template id="cpn">
    <div >
        子组件
    </div>
</template>
<script>
        const cpn={
            template:'#cpn'
        }
     let vm = new Vue({
        el: '#app',
        data: {
            message:'大番薯'
        },
        components:{
            cpn
        },
        methods:{
            click(){
                // 1.$this.children 获取所有子组件
                console.log(this.$children);
                // 2.this.$refs 默认为空对象  需要在子组件处 声明 ref=""
                console.log("$refs",this.$refs);
            }
        }
     });
    </script>
$refs (dom,组件)

this.$refs 在子组件处添加 ref=“”
默认为空对象

可设置 ref=“” 相当于设置id选择器
通过this.$ref. 获取

动态组件component

在这里插入图片描述

keep-alive

不执行destory 生命周期 仅调用actived 保留了组件状态
初次使用时created 失活时deactived

<keep-alive>
	<btn></btn>
</keep-alive>

include exclude

指定需要被缓存/不缓存 的组件

<keep-alive @include="Left">
	<btn></btn>
</keep-alive>

默认组件名

组件没有声明(导出名)名字时,组件名默认为注册组件名
components:{ Left }
在这里插入图片描述

插槽slot

在template定义slot 作为替换内容 slot内容将作为默认值
在使用组件处填充

每一个插槽都需要指定一个 name 没有则默认default
v-slot 指定渲染插槽

<tempalte v-slot:Left> </template>

简写形式

<tempalte #Left> </template>

在这里插入图片描述

<div id ="app">
        <!-- 替换slot内容 -->
        <cpn><button>更多</button></cpn>
        <cpn> <button>关闭</button></cpn>
        <cpn>
            <!-- 添加多值 -->
            <button>分享</button>
            <div class="body">内容 </div>
        </cpn>
    </div>
<template id="cpn">
    <div class="header">
        <!-- 除了slot都作为默认值 -->
        <button>返回</button>
        welcome
        <slot></slot>

    </div>
</template>
<script>
     const cpn={
        template:'#cpn'
     }
     let vm = new Vue({
        el: '#app',
        data: {

        },
        components:{
            cpn
        }
     });
    </script>

在这里插入图片描述

具名插槽

div id ="app">
        <cpn>
            <!-- 在使用出引用 slot="" -->
            <button slot="left">返回</button>
            <input slot="center" type="text" placeholder="请输入">
            <button slot="right">更多</button>
        </cpn>
        <cpn>
            <button slot="left">关闭</button>
            <div slot="center">欢迎光临</div>
            <button slot="right">分享</button>
        </cpn>
   
    </div>
    <template id="cpn">
        <div class="nav-bar">
            <!-- 具名插槽 -->
            <slot name="left"></slot>
            <slot name="center"></slot>

            <slot name="right"></slot>

        </div>
    </template>

在这里插入图片描述

作用域插槽 (有名字,带数据)

父组件替换插槽的标签,内容由子组件决定
内容在子组件,需要父组件告诉如何处理

<slot :data=“”>传递给 <cpn v-slot=“slot”>

接收数据

  1. 自定义接收所有数据 <template #content=“Obj”>
  2. 解构参数 <template #content=“{ msg, name }”>
    在这里插入图片描述
	<div id ="app">
         <!-- 2.6以上废弃 slot-scoped  使用 v-slot-->
        <cpn v-slot="slot">
            <!-- 必要的template -->
            <template>
                <!-- slot获取插槽,data获取插槽的data属性 ,-->
                <h3 v-for="item in slot.data">{{item}}</h3>
            </template>
        </cpn>
    </div>
    <template id="cpn">
        <div>
            <ul>
                <li v-for="item  in star">{{item}}</li> 
            </ul>
            <!-- :data名字任意 person获取data()的数据 -->
            <slot :data="star"></slot>
        </div>
    </template>
    <script>
    const cpn={
        template:'#cpn',
        data(){
            return{
                star:['刘德华','梁朝伟','大番薯','张国荣']
            }
        }
    }
     let vm = new Vue({
        el: '#app',
        data: {
        },
        components:{
            cpn
        }
     });
    </script>

递归组件

内置组件

transition

生命周期
<Transition
  @before-enter="onBeforeEnter"
  @enter="onEnter"
  @after-enter="onAfterEnter"
  @enter-cancelled="onEnterCancelled"
  @before-leave="onBeforeLeave"
  @leave="onLeave"
  @after-leave="onAfterLeave"
  @leave-cancelled="onLeaveCancelled"
>
  <!-- ... -->
</Transition>
// 在元素被插入到 DOM 之前被调用
// 用这个来设置元素的 "enter-from" 状态
function onBeforeEnter(el) {},

// 在元素被插入到 DOM 之后的下一帧被调用
// 用这个来开始进入动画
function onEnter(el, done) {
  // 调用回调函数 done 表示过渡结束
  // 如果与 CSS 结合使用,则这个回调是可选参数
  done()
}

// 当进入过渡完成时调用。
function onAfterEnter(el) {}
function onEnterCancelled(el) {}

// 在 leave 钩子之前调用
// 大多数时候,你应该只会用到 leave 钩子
function onBeforeLeave(el) {}

// 在离开过渡开始时调用
// 用这个来开始离开动画
function onLeave(el, done) {
  // 调用回调函数 done 表示过渡结束
  // 如果与 CSS 结合使用,则这个回调是可选参数
  done()
}

// 在离开过渡完成、
// 且元素已从 DOM 中移除时调用
function onAfterLeave(el) {}

// 仅在 v-show 过渡中可用
function leaveCancelled(el) {}
配合动画库使用

在这里插入图片描述

TransitionGroup

Vuex

state

相当于data 用于保存数据

访问state

通过$store.commit 触发定义在mutations中的方法
Home.vue

<template>
  <div>
    <button @click="mul">按钮{{$store.state}} </button>
    <h2>{{$store.state.count}}</h2>
    <h2>{{count}}</h2>
  </div>
</template>
<script>
export default {
  methods: {
    mul(){
      this.$store.commit('add')
    }
  },
}
</script>

main.js

const store= new Vuex.Store({
  state:{
    count:0
  },
  mutations:{
    add(state){
      state.count++
    }
  },
})

mapState 组件中访问state的第二种方式

将mutations函数映射为当前组件的computed函数

在这里插入图片描述

<template>
  <div>
    <button @click="mul">按钮{{$store.state}} </button>
    <h2>{{$store.state.count}}</h2>
    <h2>{{count}}</h2>
  </div>
</template>

<script>
import { mapState } from 'vuex'

export default {
  methods: {
    // 使用方法调用mutations方法
    mul(){
      this.$store.commit('add')
    }
  },
  computed:{
    // 获取state的值
    ...mapState(['count']),
  }
}

mutations

在mutations中定义方法
在使用时调用this.$state.commit(params)
main.js

const store= new Vuex.Store({
  state:{
    count:0
  },
  mutations:{
    add(state){
      state.count++
    }
  }
})

更改state的唯一方式 提交mutation
$store.commit(mutation)
Home.vue

  methods: {
    add(){
      this.$store.commit('add')
    }
  }

mapMutations() 调用mutations第二种方式

import { mapMutations } from 'vuex'
将mutations函数 映射为当前组件的methods函数
在使用mutations处导入mapMutations

import { mapMutations } from 'vuex'

export default {
  methods: {
    ...mapMutations(['add']),
    mul(){
      // 调用mutations中的add函数
      this.add()
    }
  },
}
const store= new Vuex.Store({
  state:{
    count:0
  },
  mutations:{
    add(state){
      state.count++
    }
  },
 
})

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

actions 异步处理mutations

  1. 异步操作处理数据必须使用actions
  2. 仍旧通过mutations间接操作数据 通过context.commit(‘’)
  3. 使用this.$store.dispatch(‘decAsync’) 使用
    在这里插入图片描述
const store= new Vuex.Store({
  state:{
    count:0
  },
  mutations:{
    add(state){
      state.count++
    }
  },
  actions:{
    // 异步操作数据必须使用actions 仍然需要通过mutations间接改变数据
    decAsync(context){
      setTimeout(() => {
        console.log(context);
        context.commit('dec')
      }, 1500);
    }
})
methods: {
    handle(){
      //触发actions 异步操作
      this.$store.dispatch('decAsync')
    }
  }

mapActions 调用actions的第二种方式

import { mapActions} from 'vuex'
将actions映射为组件的methods

也可以直接使用映射过来的方法

<button @click="decAsync">减少{{$store.state}}</button>
import { mapState,mapActions } from 'vuex'

export default {
  methods: {
    ...mapActions(['decAsync']),
  },
}
  actions:{
    // 异步操作数据必须使用actions 仍然需要通过mutations间接改变数据
    decAsync(context){
      setTimeout(() => {
        context.commit('dec')
      }, 1500);
    }
  }

Getter

用于对Store数据进行加工处理

  1. 不会修改state中的数据,仅对state包装处理
    在这里插入图片描述
    调用$store.getters中的函数
   <h2>{{$store.getters.multiple}}</h2>
  getters:{
    multiple(state){
      return  '1*10 ' +state.count*10
    }
  }

mapGetter getter第二种方式

import { mapGetters } from 'vuex'

    <h2>{{multiple}}</h2>
  computed:{
    ...mapGetters(['multiple'])
  }

modules

当state中数据过多时,单一的文件不易维护
因此可以将不同的store封装成独立的模块
home.js home模块

const Home={
    namespaced:true,
    state:{
        username:'xwt',
        age:18
    },
    mutations:{},
    getters:{},
    actions:{},
    modules:{} 
}
export default Home

car.js

const Car={
    namespaced:true,
    state:{},
    mutations:{},
    getters:{},
    actions:{},
    modules:{}
}
export default Car

main.js 根store

import Car from './store/cart'
import Home from './store/home'
const store= new Vuex.Store({
  state:{},
  mutations:{},
  actions:{},
  getters:{},
  modules:{
    homeModule:Home,
    carModule:Car
  }
})

调用模块

在这里插入图片描述

<button @click="$store.commit('carModule/add')">psuh</button>
    <div>{{$store.state.carModule}}</div>
const Car={
    namespaced:true,
    state:{
        Purchase:['香蕉','苹果'],
        num:0
    },
    mutations:{
        add(state){
            state.Purchase.push('牛奶')
        }
    },
    getters:{},
    actions:{},
    modules:{}
}
export default Car

样式冲突

style scoped

在使用组件时,css可能重复导致样式的覆盖
style scoped
本质上为每个标签添加了自定义属性 data-v 使选择样式唯一

.header[data-1] 为包含data-1属性的header类添加样式

/deep/ 深度选择器 (父组件修改子组件样式)

/deep/ h5 查找为 [属性] 标签
在这里插入图片描述

global 全局选择器

在这里插入图片描述

:slotted 插槽选择器在这里插入图片描述

axios 全局配置(挂载到Vue原型中)

将axios挂载到Vue原型

在main.js 为Vue实例添加axios到原型中
使用时 this.axios
在这里插入图片描述

默认路径与缺点

在这里插入图片描述

request封装

可以将不同请求封装成独立js文件
在这里插入图片描述

记事本实例

<body>
    <h1>记事本</h1>
    <div class="container">
        <input type="text" @keyup.enter="addList" v-model="value" placeholder="请输入">
        <ul>
            <li v-for="(items,index) in List">
                    <span>{{index+1}}</span>            
                    {{List[index]}}     
                    <span  @click="remove(index)" class="remove">x</span>
            </li>
        </ul>			
        <li class="left" v-show="List.length>0" >//List数组长度大于0
                    <span > {{List.length+' left in items'}} </span>
                    <span @click="clear">clear</span>
        </li>
    </div>
</body>
<script>
    let app=new Vue({
        el:".container",
        data:{
            List:["起床","刷牙洗脸","吃早饭","上课"],
            value:""
        },
        methods:{
            addList:function(){
                if(this.value!="")          
                this.List.push(this.value)  //在队尾插入v-model值
                this.value="";              
            },
            remove:function(index){         //需要传参index
                console.log(index);
                this.List.splice(index,1)  //这里写错了shift固定删除第一个,应该使用splice(开始位置,几位)
            },
            clear:function(){
                this.List=[]                //清空数组
            }
        }
    })
</script>

在这里插入图片描述

天气预报

<body>
    <div class="container">
        <h1>天知道</h1>
        <div class="input-form">
            <input type="text" placeholder="请输入城市" v-model="city" @keyup.enter="search">
            <input type="button" value="搜索"  @click="changeCity(city)" >
        </div>
        <ul class="hotCity">
            <li @click="changeCity('北京')">北京</li>
            <li @click="changeCity('上海')">上海</li>
            <li @click="changeCity('广州')">广州</li>
            <li @click="changeCity('深圳')">深圳</li>
        </ul>
        <div class="wheather">  
            <div class="wheatherList" v-for="items in weatherList" >
                <h2>{{items.type}}</h2>
                <span>{{items.low}}  {{items.high}}</span>
                <span>{{items.date}}</span>
            </div>
            
             
        </div>
    </div>

</body>
<script>
    let app=new Vue({
        el:".container",
        data:{
            city:'',
            weatherList:[]
        },
        methods: {
            search:function(){
                console.log(this);      //this 指向vue
                var that=this;        
                
                axios.get("http://wthrcdn.etouch.cn/weather_mini?city="+this.city)
                .then(function(res){
                    console.log(this);  //this 指向window
                    that.weatherList=res.data.data.forecast;   //回调函数这里的this和search函数的this不一样,应该保存上一次的this才能得到正确的数据
                    // console.log(res.data.data.forecast);     
                },function(err){
                    console.log(err);
                }) 
            },
            changeCity:function(city){
                this.city=city;
                this.search();          //this指向vue整个项目,所以能够执行search方法    
            }
        },
    })
</script>

在这里插入图片描述

Tabbar

准备

  1. vue init webpack tabbar
  2. 删除不必要的文件
  3. npm run dev

模块化

  1. 将html css代码抽取到独立vue文件
  2. 新建组件文件用于用插槽替换

Vue2

Filters

私用过滤器

常用于文本格式化 用于插值表达式和v-bind
与el,data同级 申明filters:{} 将方法定义到filters
filters本质是个函数 必须有返回值

<div id="app">
        // 插值 v-bind
        //  mes为uppercase方法的形参   值 | 方法
        <p>{{mes | uppercase}}</p>
    </div>
    <script>
        new Vue({
            el:'#app',
            data() {
                return {
                    mes:'hello filters'
                }
            },
            filters:{
                // 用任意值接收mes  
                uppercase(val){
                    return val.toUpperCase()
                }
            }
        })
    </script>

全局过滤器

私有过滤器只能在filters定义的实例内使用
Vue.filter() 定义全局过滤器 1.过滤器名 2.回调函数
全局过滤器和私有过滤器命名冲突时,就近原则

<div id="app">
        <!-- // 插值 v-bind -->
        <!-- mes为uppercase方法的形参   值 | 方法 -->
        <p>{{mes | uppercase}}</p>
        <p>{{Info | lowercase}}</p> 就近原则使用私有过滤器
    </div>
    <div id="app2">
        <!-- <p>{{mes | uppercase}}</p>  无法被app1中的过滤器所执行  -->
        <p>{{Info | lowercase}}</p> 全局过滤器
    </div>
    <script>
        // 参数     1.过滤器名  2.回调函数
        Vue.filter('lowercase',function(val){
            return val.toLowerCase()+'全局'
        })
        new Vue({
            el:'#app',
            data() {
                return {
                    mes:'hello filters',
                    Info:'Info'
                }
            },
            filters:{
                // 用任意值接收mes  
                uppercase(val){
                    return val.toUpperCase()
                },
                lowercase(val){
                    return val.toLowerCase()
                }
            }
        })
        new Vue({
            el:'#app2',
            data(){
                return{
                    Info:'Info'
                }
            },
            
        })
    </script>

可连续调用

在这里插入图片描述

传参

在这里插入图片描述

Problems

Vue中赋值会变为双向绑定

	handleEdit(index, row) {
      this.EditFormVisible = true;
      //  绑定row会影响编辑与展示
      // this.editInfo = row;
      this.editInfo=JSON.parse(JSON.stringify(row))
      console.log(index, row);
    }

解决:
将v-model JSON.parse(JSON.stringify())

相同组件路由跳转不会重复创建

vue会复用相同组件,不重新创建
解决:
1.在routeview中添加 :key=“$route.path”
2. 使用watch 监听路由变化

深拷贝

res.data.data

在使用ElementUi,Cascader时,想要为两个选择器赋予不同值,
但实际上他们被赋予了相同的地址,可以理解为绑定了this.data 使用
JSON.parse(JSON.stringify) 取消深拷贝

this.seOptions=res.data.data
let arr = res.data.data;
arr.unshift({ label: "全选", value: "全选" });
this.options = arr;

在这里插入图片描述

$route监听

立即执行侦听器

  watch: {
    $route: {
      handler() {
        if (this.currentView == "Left" && this.$route.path == "/category")
          this.currentView = "typeLeft";
      },
      immediate: true,
    },
  },

$router.resolve

Vue 中没有新窗口Api

let {href} =this.$router.resolve({
	path:''
})
window.open(href,'_blank')
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值