属性绑定
v-bind:
或简写为:
条件渲染
-
v-if
-
v-else-if
-
v-else
上面3个是直接移除或新增元素
v-show 基于display,元素本身已经渲染,只是隐藏或显示
列表渲染
item in terms 或 item of terms
v-for 也可以渲染对象:
<template>
<p v-for="(value,key,index) of userinfo" :key="">{{value}}-{{key}}-{{index}}</p>
</template>
<script>
export default {
data() {
return userinfo: {
name: "zhangsan",
age: 20
}
}
}
</script>
key和v-for一起使用,确保元素的唯一性,从而重用和重新排序现有的元素,不推荐用index,可以使用后端返回的唯一id
事件处理
v-on或简写为@
v-on:click="methodName"或@click="handler"
事件传参
-
一个参数时传e
<template>
<p @click="handler(e)"></p>
</template>
<script>
export default(){
data(){
},
methods:{
handler(e){
console.log(e);
}
}
}
</script>
-
多个参数时,用$event,并且只能放到最后一个参数上
<template>
<p @click="handler(item,$event)" v-for="(item,index) of names" :key="index">{{item}}</p>
</template>
<script>
export default(){
data(){
return {
names:["张三","李四","王麻子"],
}
},
methods:{
handler(name,e){
console.log(name);
console.log(e);
}
}
}
</script>
事件修饰符
v-on提供以下常见事件修饰符:
.stop 阻止事件冒泡
.prevent 阻止默认事件
.once 事件只会被触发一次
.enter 回车按键触发
数组变化侦测
变更方法
vue能侦测响应式数组的变更方法,并在它们被调用时触发相关的更新,对原数组进行变更,这些变更方法包括:
-
push()
-
pop()
-
shift()
-
unshift()
-
splice()
-
sort()
-
reverse()
替换一个数组
不会更改原数组,而是返回一个新数组,这些方法包括filter(),concat(),slice(),当遇到的是非变更方法时,需要将旧的数组替换成新的
<template>
<button @click="addListHandle">添加数据</button>
<ul>
<li v-for=("(item,index) of names") :key="index">{{item}}</li>
</ul>
</template>
<script>
export default {
data(){
return {
names: ["zhangsan","lisi","wangwu"],
}
},
methods:{
addListHandle(){
// UI自动变更
this.names.push("zhaoliu");
// UI不自动变更
this.names.concat("[liuneng]");
// 用新数组替换旧数组后,UI可以变更
this.names = this.names.concat("[liuneng]");
}
}
}
</script>
计算属性
关键字 computed
计算属性:计算属性值会基于其响应式依赖被缓存。一个计算属性仅会在其响应式依赖更新时才重新计算。
方法:方法调用总是会在重新渲染发生时再次执行函数。
Class绑定
可以绑定对象或数组
绑定对象:
<template>
<p :class="{'active':isActive,'text-danger':hasError}"></p>
<p :class="{classObject}"></p>
</template>
<script>
export default {
data() {
return {
isActive: true,
hasError: true,
classObject: {
'active': true,
'text-danger': true
}
}
}
}
</script>
绑定数组:
<template>
<p :class="[arrActive,arrHasError]"></p>
</template>
<script>
export default {
data() {
return {
arrActive: "active",
arrHasError: "text-danger",
}
}
}
</script>
<style>
.active {
font-size: 30px;
}
.text-danger {
color: red;
}
</style>
style绑定
关键字 :style
用法同class绑定
watch监听器
关键字 watch
在每次响应式属性发生变化时触发一个方法,和methods同级,方法名必须和需要监听的属性名称或对象一致,参数为(newValue,oldValue)
表单输入绑定
关键字 v-model或:model
默认情况下,v-model会在每次input事件后更新数据。也可以添加lazy修饰符来更改为在每次change事件后更新数据,v-model.lazy
scoped
表示当前样式只在当前组件中生效,不是全局样式,不会影响其他页面或组件样式
<style scoped>
</style>
scoped原理
1、当前组件内标签都被添加data-v-hash值的属性
2、css选择器都被添加**[data-v-hash值]**的属性选择器
最终效果:必须是当前组件的元素才会有这个自定义属性,才会被这个样式作用到
父子组件通信
父传子props
-
父中给子添加属性传值
-
子props接收
-
子使用
-
例子
父组件:
<template> <div> 我是App组件 <Son :title="myTitle"></Son> </div> </template> <script> import Son from "./components/Son.vue" export default { data() { return { myTitle: "我是大帅哥" } } } </script> <style> </style>
子组件:
<template> <div> 我是Son组件 {{title}} </div> </template> <script> export default { props: ["title"] } </script> <style> </style>
子传父emit
-
子$emit发送消息
-
父中给子添加消息监听
-
父中实现处理函数
-
例子
父组件:
<template> <div> 我是App组件 <Son :title="myTitle" @changeTitle="handleChange"></Son> </div> </template> <script> import Son from "./components/Son.vue" export default { data() { return { myTitle: "我是大帅哥" } }, methods: { handleChange(newTitle) { this.myTitle = newTitle; } } } </script> <style> </style>
-
子组件:
<template> <div> 我是Son组件 {{title}} <button @click="handleClick"></button> </div> </template> <script> export default { props: ["title"], methods:{ handleClick() { this.$emit("changeTitle","帅滴掉渣") } } } </script> <style> </style>
props和data区别
-
props传过来的数据(外部数据,父组件的),不能直接改
-
data是自己的数据,随便改(谁的数据谁负责)
非父子通信
event bus事件总线
作用:非父子组件之间,进行简易消息传递。(复杂常见->Vuex)
1.创建一个都能访问到的事件总线(空的vue实例)->utils/EventBus.js
import Vue from "vue"
const Bus = new Vue()
export default Bus
2.A组件(接收方)监听Bus实例的事件,可以为多个组件,同时监听
created() {
Bus.$on("sendMsg",(msg)=> {
this.msg = msg
})
}
3.B组件(发送方)触发Bus实例的事件
Bus.$emit("sendMsg","这是一个消息")
provide & inject
作用:跨层级共享数据
1.父组件provide提供数据
export default {
provide() {
return {
// 普通类型(非响应式)
color: this.color,
// 复杂类型(响应式)
userInfo: this.userInfo,
}
}
}
2.子/孙组件inject取值使用
export default {
inject ["color","userInfo"],
created () {
cosole.log(this.color,this.userInfo);
}
}
v-model原理
原理
v-model本质上是一个语法糖。例如应用在输入框上,就是value属性和input事件的合写,在下拉框上就是value属性和change事件的合写。
作用
提供数据的双向绑定
1.数据发生改变,页面会自动变:value
2.页面输入改变,数据会自动变@input
注意:$event用于在模板中获取事件的形参
<template>
<div>
<input v-model="msg" type="text"/>
<input :value="msg" @input="msg = $event.target.value" type="text"/>
</div>
</template>
表单类组件封装
1.表单类组件封装 -> 实现子组件和父组件数据的双向绑定
父传子 数据应该是父组件props传递过来的,v-model拆解绑定数据
子传父 监听输入,子给父传值,父组件修改
2.例子:封装下拉框组件
父组件
<template>
<BaseSelect :cityId="selectId" @事件名="selectId = $event"/>
</template>
<script>
export default {
data() {
return {
selectId: "103"
}
}
}
</script>
子组件
<template>
<select :value="cityId" @change="handleChange">
<option value="101">北京</option>
<option value="102">上海</option>
<option value="103">武汉</option>
<option value="104">深圳</option>
<option value="105">广州</option>
</select>
</template>
<script>
export default {
props: {
cityId: String
},
methods: {
handleChange(e) {
this.$emit("事件名", e.target.value)
}
}
}
</script>
3.父组件v-model简化代码,实现子组件和父组件数据双向绑定
父组件中v-model给组件直接绑数据(:value+@input)
<BaseSelect v-model="selectId"/>
子组件中props通过value接收,事件触发input
<select :value="value" @change="handleChange">...</select>
props: {
cityId: String
}
methods: {
handleChange(e) {
this.$emit("input", e.target.value)
}
}
vue异步更新DOM和nextTick
vue是异步更新DOM的,不是实时的,因为如果执行每一行都要更新一次,影响性能,可以通过nextTick来实现
this.$nextTick(() => {
//业务逻辑
})