# Vue常用

# 把Vue当成对象添加的私有方法

Vue对象的私有方法

全局过滤器Vue.filter(方法名,方法);相当于给全局过滤器中增加了一个方法(一次只能增加一个)

 Vue.filter('my',data=>{return data})
 <!-- 页面中使用 -->
<div id="app">
  {{count|my}}
</div>

创建一个全局组件Vue.component(自定义标签名,需要配置的参数)

//js代码
Vue.component('my-hand',{
  template:'<h3>{{msg}}</h3>',
  data(){
    return {msg:'我很英俊'}
  }
});
let vm = new Vue({
  el:'#app'
})
<!-- 页面中使用 -->
<div id="app">
  <my-hand></my-hand>
</div>

# vue中数组的变异方法(能改变原数组)

数组方法

如果data中属性的值是一个数组,如果想改变数组中内容,只能使用原生的会修改原数组的方法进行修改,普通的 数组[索引]=值 不行; 操作数组的方法:(以下方法都会修改原数组)

  • unshift、push、shift、pop、splice、reverse、sort

vue中常用的(以下方法都为声明式方法,for循环为编程式方法,能清晰的看到每一步)

  • forEach、filter、map、some、every、reduce、find(ES6)

forEach,for,for in,for of的区别

  • forEach:不支持返回值,只是普通的循环遍历
  • for inkey输出的值为字符串类型,包括把数组当成对象添加的属性也可以遍历出来
  • for of:只返回具有数字索引的属性。这一点跟for...in循环也不一样。**(不能遍历对象)
	let arr = [3, 5, 7];
	arr.foo = 'hello';
	
	for (let i in arr) {
	//for in是把arr当成对象遍历,i是属性名,包括arr的私有属性
	  console.log(i); // "0", "1", "2", "foo"
	}
	
	for (let i of arr) {
	//for of是把arr当成数组遍历,i是数组中的每一项
	  console.log(i); //  "3", "5", "7"
	}
	// for of循环不会返回数组arr的foo属性
	// 如果只想拿到索引,可用keys()方法
	for (let index of ['a', 'b'].keys()) {
	  console.log(index);
	}
	// 0
	// 1

	// 如果两个都想拿到,可用entries()方法
	for (let (index, elem) of ['a', 'b'].entries()) {
	  console.log(index, elem);
	}
	// 0 "a"
	// 1 "b"

# vue中的指令

dom元素的行间属性,vue提供了内置的指令,必须以 v- 开头,后面的值均为变量

# v-cloak

TIP

消除页面刚加载时会看到{{}}闪一下的效果,可加给最外层的根元素;

/* 需要添加对应的css样式 */
[v-cloak]{
  display: none;
}

# v-model

表单元素设置了之后会忽略掉value,checked,selected

让表单元素和数据实现双向绑定(映射关系)

<input type="text" v-model="msg">

# v-text

代替 {{}} 渲染成文本(不会识别html标签)可以防止网速卡慢时{{}}出现在页面上

{{}} 中的值都会解析成文本内容;

<!-- {{msg}}与下列写法等价  -->
<div v-text="msg"><!--此处不能再写内容,防止出现闪的效果--></div>

# v-html

把html字符渲染成html

<div v-html="msg"></div>

# v-once

只绑定一次(不能写成v-once="msg")

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

# v-bind

动态地绑定一个或多个特性

<!-- 绑定一个属性 -->
<img v-bind:src="imageSrc">
<!-- 可缩写为如下形式,此时:src后面的值就可以是变量、表达式、赋值运算、计算、三元运算符(尽量少写逻辑运算) -->
<img :src="imageSrc"><!-- 此时imageSrc就代表一个变量 -->

# v-for

遍历数组、对象、字符串、数字

解决了循环问题,更高效,会在原有的基础上进行修改,会复用原有的结构,不会修改所有DOM

要循环创建哪一个标签就在那一个标签上加v-for,后面的循环最好用in,用of有时会报错循环数组或对象使用v-for指令

<div v-for="(val,index) in msg">
  {{val,index}} <!-- msg为数组时,val为数组中的每一项,index为索引 -->
</div>
<div v-for="(value,key,index) in msg">
  {{key}}={{value}}{{index}}; <!-- msg为对象时,key为对象中的每个属性名,value为属性值,index为索引 -->
</div>

# 条件渲染

满足条件才会渲染

# v-if v-else-if v-else

条件满足才渲染 v-if 所在标签以及标签内的内容;(操作的是DOM结构)

  • 设置条件判断的DOM元素必须是连续的
  • 操作的是DOM元素
  • key 管理复用的元素 若不想复用DOM元素,只需要给相应的DOM元素增加不同的key
  • 频繁的显示和隐藏用v-if会很浪费性能(操作的是DOM结构),此时要用v-show(操作的是CSS样式)
<div id="app">
  <button @click="flag=!flag">请点击</button>
  <!-- template标签是vue提供给我们的没有任何实际意义,用来包裹元素用的(v-show不支持template标签) -->
  <template v-if="flag">
    <label>登录</label>
    <!-- key 管理复用的元素 若不想复用DOM元素,只需要给相应的DOM元素增加不同的key值 -->
    <input type="text" key="1">
  </template>
  <template v-else>
    <label>注册</label>
    <input type="text" key="2">
  </template>
</div>
let vm = new Vue({
  el:'#app',
  data:{
    flag:true
  }
});

# v-show

条件满足才让v-show所在标签以及标签内的内容显示(操作的是元素的css样式)

<input type="text" v-show="flag"> <!-- flag为true时,input框才显示 -->

# 事件绑定

# v-on

监听 DOM 事件

v-on:click 可缩写为 @click

可以用 v-on 指令监听 DOM 事件,并在触发时运行一些 JavaScript 代码(在 methods 对象中定义的方法,而且methods中的方法名不能和data中的变量名一样)

<div v-on:click ="fn1('zhaosi,$event')">{{msg}}</div>
<div @click ="fn1('zhaosi,$event')">{{msg}}</div> <!-- 上面的简写  -->
<!-- 
  方法后面可加()可不加。不加的话默认会传入事件对象e,
  加()代表要传参数,如果要用事件对象,则需要传$event 
-->

# 自定义指令

可通过在vue实例的 directives:{} 属性中赋予自定义指令意义

<div id="app">
  <button v-color="flag" @click="flag='blue'">变色</button>
</div>
let vm = new Vue({
  el:'#app',
  data:{
    flag:'red'
  },
  directives:{//在这里赋予对应自定义指令意义
    //可直接写对应的指令不用写v-
    color(el,val){
    //el和val都是默认给的:el指的是指令所绑定的DOM元素,val是一个对象,里面存储的是有关指令的所有信息,只能用val.value获取到指令绑定的变量(或者表达式)所代表的值,这里就是flag所代表的值 'red'
      el.style.background = val.value;
    }
  }
});

# vue中的修饰符

TIP

.sync修饰符是自定义事件中的修饰符 当在组件上对传入组件的prop属性添加.sync修饰符时,相当于给这个属性增加了一个@update:foo="val => bar = val"的事件。它会被自动扩展为自动更新父组件属性的v-on事件监听器。 示例代码如下

<Table :foo.sync="bar"></Table>
// 会被展开为如下形式
<Table :foo="bar" @update:foo="val => bar = val"></Table>

// 在子组件中需要更新`foo`的值时需要手动的触发`update:foo`事件来更新
this.$emit('update:foo', newValue)

# 表单修饰符

  • v-model.number:将用户的输入值转为数值类型
  • v-model.lazy:在表单触发change事件时更新数据,而非触发input事件时更新数据
  • v-model.trim:自动过滤用户输入的首尾空白字符

# 事件修饰符

TIP

-@click.stop:阻止点击事件的传播(往上传播和往下传播都会被阻止) -@submit.prevent:阻止点击提交按钮时的默认行为(阻止事件的默认行为) -@click.capture:点击的时候让事件在捕获阶段执行; -@click.once:只在第一次点击的时候让绑定的事件执行; -@click.self:只有点击的事件源是自己的时候触发事件;(判断事件源) -@keyup.enter:按回车时触发的事件;

element UI组件不支持 @keyup 的解决办法:

下面这样写是监控回车键然后执行事件操作的,但是完全一点反应都没有,然后你会发现你自己写了一个input原样复制进去是没问题 <el-input v-model="SearchData" @keyup.enter="save">

现在我这样写了可以运行事件了,问题得到了解决,你会发现有点不同了后面多了.native后面查了下度娘才知道,上面那种写法只适合原生,像组件是不适合用的, 加.native的原因就是为了转成原生 <el-input v-model="SearchData" @keyup.enter.native="save">

# Vue中的动态 class 与 style 绑定

动态的优先级高于静态的

# 动态 class

class

:class="{}"或者:class="[]" 通过:class="{}"或者:class="[]"来绑定动态class,与原来的class样式不冲突,而且优先级高于静态class

有两种方式:

  • 1、对象的方式绑定
  • 2、数组的方式绑定
<div id="app">
  <!--以对象的方式动态绑定class样式:当flag为true时,z样式生效。y样式不生效-->
  <div class="x" :class="{z:flag,y:false}">我的世界</div>
  <!--以数组的方式动态绑定class样式:y,z两个样式都会生效-->
  <div class="x" :class="[y,z]">我的世界</div>
</div>
let vm = new Vue({
  el:'#app',
  data:{
    flag:true
  }
});

# 动态 style

style

:style="{}"或者:style="[]" 来绑定动态行内样式

通过上述的方式来动态绑定行内的样式

<div id="app">
  <!-- 第一种是对象的方式 -->
  <div :style="{backgroundColor:'red',color:'pink'}">我是谁</div>
  <!-- 第二种是数组的方式 -->
  <div :style="[str1,str2]">我的世界</div>
</div>
let vm=new Vue({
  el:'#app',
  data:{
    str1:{backgroundColor:'blue'},
    str2:{color:'yellow'}
  }
});

# 根据hash实现单页面开发

通过hash记录跳转的路径(可以产生历史管理)

浏览器自带的历史管理方法historyhistory.pushState(),push到哪里就跳转到哪里),可能会导致404错误(因为用户可能会随意输入路径)

开发时使用hash的方式,上线的时候使用history的方式

[使用hash存储]

//存储:存储的时候要把存储的对象转换成字符串
localStorage.setItem('todo',JSON.stringify(obj));
//获取:获取的时候要把字符串转换成对象
JSON.parse(localStorage.getItem('todo'));

# ElementUI中表单的校验方式

# 循环类型的校验

<!-- html写法 -->
<el-form-item 
  v-for="(answer,index) in temp.answers"
  :rules="rules.content"  
  :prop="'answers['+index+'].content'"
  :key="answer.sequence" 
  :label="answer.sequence | toChinese">
  <el-input :autosize="{ minRows: 2, maxRows: 4}" v-model.trim="answer.content" type="textarea" placeholder="请输入要发送的内容" />
</el-form-item>
<!-- data中的属性 -->
<!-- 在data的rules中定义校验规则 -->

# 二级对象的校验(深度校验)

<el-form-item label="角色" prop="role.id">
  <el-select v-model="temp.role.id">
    <el-option v-for="role in roleInfo" :key="role.id" :label="role.name" :value="role.id" />
  </el-select>
</el-form-item>
rules:{
  "role.id":[
    { required: true, message: "角色是必须的", trigger: "change" } // 下拉框要用change
  ]	
}

# 原生标签清除校验

<el-form ref="module" class="module" :rules="rules" :model="module" label-position="right" label-width="80px">
	<el-form-item label="背景颜色" prop="bgColor">
    <div class="colors">
      <div class="color" @click="colorChange(item)" :class="module.bgColor == item ?' el-icon-success':''" v-for="item in colors" :key="item" :style="'background:'+item"></div>
    </div>
  </el-form-item>
</el-form>
/* 清除单个校验 */
this.$refs['module'].clearValidate('bgColor');

/* 清除整个表单的校验 */
this.$refs['module'].clearValidate();

# Vue 中的 $set

# 数组中使用 $set

对于数组来说,通过数组下标来修改数据时,是无法被监听到的

此时可采用this.$set(Array,index,newValue)的形式或者用数组的splice方法来修改,以此强制视图更新。

# 对象中使用 $set

对于对象来说,给对象新增初始化时不存在的属性时,也是无法被监听到的

此时可采用this.$set(this.data,key,value)来强制更新视图;

上次更新: 7/1/2021, 10:08:38 PM