Vue基础
学习目的:
1.Vue简介
-
Vue.js 是目前最火的一个前端框架,React是最流行的一个前端框架(React除了开发网站,还可以开发手机App, Vue语法也是可以用于进行手机App开发的,需要借助于Weex)
-
Vue.js 是前端的主流框架之一,和Angular.js、React.js 一起,并成为前端三大主流框架!
-
Vue.js 是一套构建用户界面的框架,只关注视图层,它不仅易于上手,还便于与第三方库或既有项目整合。(Vue有配套的第三方类库,可以整合起来做大型项目的开发)
-
前端的主要工作?主要负责MVC中的V这一层;主要工作就是和界面打交道,来制作前端页面效果;
2.模板语法
2.1插值语法
2.1.1文本
数据绑定最常见的形式就是使用“Mustache”语法 (双大括号){{ }}
的文本插值:
<div>
<h1>{{ msg }}</h1>
</div>
Mustache 标签将会被替代为对应数据对象上msg property
的值。无论何时,绑定的数据对象上 msg property 发生了改变,插值处的内容都会更新。
只能用在文本节点,不能使用在属性节点, <input type=‘text’ placeholder=‘{{ tips }}’>是没有用的
export default {
data() {
return {
msg: 'hello'
}
}
}
v-once指令
只能进行一次赋值,数据发生变化时插值处的内容不会更新
2.1.2 原始html
v-text指令和插值表达式只能渲染纯文本内容,如果包含html标签的字符串
渲染为页面的html元素,则需要v-html
指令
<h1>{{ msg }}</h1>
<p v-text="info"></p>
<p>{{ info }}</p>
<p v-html="info"></p>
export default {
data() {
return {
msg: 'hello',
info: '<h1 style="color: red">nihao</h1>'
}
}
}
2.1.3 v-text
v-text指令的缺点:会覆盖元素内部原有的内容
<p v-text="info"></p>
2.2属性绑定指令
双大括号不能在 HTML 属性中使用。想要响应式地绑定一个属性,应该使用v-bind
指令:
<input type="text" v-bind:placeholder="tips"/>
v-bind
是非常常用的指令,可以简写成:
<input type="text" v-bind:placeholder="tips"/>
等价于
<input type="text" :placeholder="tips"/>
2.3使用JavaScript表达式
但是 Vue 实际上在所有的数据绑定中都支持完整的 JavaScript 表达式
{{ number + 1 }}
{{ ok ? 'YES' : 'NO' }}
{{ message.split('').reverse().join('') }}
<div :id="`list-${id}`"></div>
2.4事件绑定
使用v-on事件绑定指令
,为dom元素绑定事件监听
<button v-on:click="count++">加一</button>
v-on
可以简写成为@
<button @click="count++">加一</button>
通过this
来访问数据中的数据
add() {
this.count++
}
2.5事件$event
vue提供了$event
来操作dom对象
add(e) {
this.count++
console.log(e)
if (this.count%2 === 0) {
e.target.style.backgroundColor="red"
} else {
e.target.style.backgroundColor = 'blue'
}
}
事件方法中如果提供了参数则会覆盖掉原生的event
,
<button @click="add(1)">+1</button>
add(e)
如果既想传参又想操作事件,则需要$event
<button @click="add(1, $event)">+1</button>
add(n,e)
2.6事件修饰符
在事件处理函数中调用event.preventDefault()
和event.stopPropagation
是非常常见的需求,vue提供事件修饰符
的概念,辅助对事件的触发进行控制
-
.stop 阻止冒泡()
-
.prevent 阻止默认事件
<a href="www.baidu.com" @click.prevent="show">百度</a>
-
.capture 添加事件侦听器时使用事件捕获模式
-
.self 只当事件在该元素本身(比如不是子元素)触发时触发回调
-
.once 事件只触发一次
<button @click.once="add">+1</button>
2.7按键修饰符
在监听键盘事件
时,需要判断详细的按键
,此时可以为键盘相关的事件
添加按键修饰符
<input @keyup.enter="submit"/>
<input @keyup.esc="submit"/>
2.8双向绑定指令
vue提供了v-model双向数据绑定指令
,用来辅助开发者在不操作dom的前提下,快速获取表单
的数据
<input type="text" v-model="username"/>
当数据发生改变时,数据也会发生改变
v-model指令修饰符
- number:自动将用户的输入值转为数值类型
<input v-model.number='age'/>
- trim:自动过滤用户输入的首尾空白字符
<input v-model.trim=""/>msg
- lazy:在“change”时而非“input”时更新
<input v-model.lazy="msg"/>
2.9条件渲染指令
条件渲染指
用来辅助开发按需控制dom的显示和隐藏
v-if
v-if是通过动态的创建和移除元素
<p v-if="flag">v-if的内容</p>
v-else-if和v-else
v-else-if和v-else指令必须
和v-if一起使用
<p v-if="flag">v-if的内容</p>
<p v-else-if="type==='b'">v-if的内容</p>
<p v-else>v-if的内容</p>
v-show
v-show本质上是用display
来控制标签的显示和隐藏
<p v-show="!flag">v-show的内容</p>
<p style="display: none;">v-show的内容</p>
2.10列表渲染指令
vue提供了v-for
列表渲染指令,用来辅助基于一个数组循环渲染一个列表结构
item in items
item是被循环的mei每一项
items是待循环的数组
<tr v-for="item in list" >
<td>{{item.username}}</td>
<td>{{ item.age }}</td>
</tr>
(item, index) in items
<tr v-for="(item, index) in list" >
<td>{{ index }}</td>
<td>{{item.username}}</td>
<td>{{ item.age }}</td>
</tr>
key属性值
- key的值只能是
字符串
或数字
类型 - key的值必须具有
唯一性
(即:key的值不能重复) - 建议把数据项
id属性
的值作为key的值(因为id属性的值具有唯一性) - 使用
index的值
当作key的值没有任何意义
(因为index的值不具有唯一性) - 建议使用v—for指令时
一定
要指定key的值(既提升性能、又防止列表状态紊乱)
<tr v-for="(item, index) in list" :key="item.id">
<td>{{ item.id }}</td>
<td>{{item.username}}</td>
<td>{{ item.age }}</td>
</tr>
3.过滤器(vue3已取消掉)
概念:Vue.js 允许你自定义过滤器,可被用作一些常见的文本格式化。过滤器可以用在两个地方:mustache 插值和 v-bind 表达式。过滤器应该被添加在 JavaScript 表达式的尾部,由管道符 |
指示;
过滤器函数,必须定义在filters节点上
<p>{{ msgF | capi }}</p>
filters:{
capi(val) {
console.log(val.trim().split().reverse().join())
return val.trim().split().reverse().join()
}
}
4.侦听器
watch侦听器
允许开发者监视数据的变化,从而针对数据的变化做特定的操作,侦听器本质是一个函数,要监视那个数据的变化,就把数据名作为方法名即可
方法式监听器无法在刚进入页面的时候,自动触发
如果侦听的是一个对象,如果对象中的属性发生变化,不会触发侦听器
data() {
return {
msg: 'hello'
}
},
watch:{
msg(newVal, oldVal) {
console.log("数据发生改变" + newVal + " " + oldVal)
}
}
immediate选项
对象式侦听器可以通过immediate
,让侦听器自动触发
immediate的默认值是false
作用是让侦听器是否自动触发一次
watch:{
msg: {
handler(newVal, oldVal) {
console.log("数据发生改变" + newVal + " " + oldVal)
},
immediate: true
}
}
deep选项
deep选项可以侦听到对象中属性发生的变化
开启深度监听,只要对象中任何一个属性变化了,都会触发对象的侦听器
info: {
deep: true,
handler(newVal, oldVal) {
console.log("数据发生改变" + newVal.age + " " + oldVal.age)
}
}
侦听子属性
如果要监听对象的子属性的变化,则必须包裹一层单引号
'info.username'(newVal, oldVal) {
console.log("数据发生改变" + newVal + " " + oldVal)
}
5.计算属性
计算属性指的是通过一系列运算之后,最终得到一个属性值,这个动态计算出来的属性值可以被模板或者methods方法使用
原理:底层借助了Objcet.defineproperty方法提供的getter和setter。
get函数什么时候执行?
- 初次读取时会执行一次。
- 当依赖的数据发生改变时会被再次调用。
只要计算属性依赖的数据源变化了,则计算属性会自动重新求值
computed: {
fullName() {
return this.lastName + this.firstName
}
}
watch不仅能监视data的普通属性,也可以检测计算属性
6.vue组件
使用步骤
-
使用import语法导入所需要的组件
-
使用components节点注册组件
-
以标签形式使用刚才注册的组件
6.1全局组件注册
在vue项目的main.js入口文件,通过vue.components()方法,可以注册全局组件
import xxxx from '@/components/'
Vue.component('xxxx', xxxx)
6.2组件的props
props是组件的自定义属性
,在封装通用组件的时候,合理使用props可以极大的提高组件的复用性
props: ['msg'],
data() {
return {
}
}
使用
<MyCount msg="hello"></MyCount>
<MyCount v-bind:msg="10"></MyCount>
结合v-bind属性可以传递数值类型
props中的数据,可以直接在模板结构中使用
组件中封装的自定义属性是只读的
,程序员不能直接修改,否则报错
只读解决方法
props: ['msg'],
data() {
return {
info: this.msg
}
}
props的default默认值
在声明定义属性时,可以通过default
来定义props的默认值
props: {
msg: {
default: 2000
}
}
props的type值类型
用type
属性定义属性的值类型,如果传递过来的值不符合此类型,则会报错
props: {
msg: {
default: 2000,
type: Number
}
}
props的required必填项
required
规定使用该组件必须要传值
props: {
msg: {
default: 2000,
type: Number,
required: true
}
}
7.组件的生命周期
生命周期是指一个组件从创建->运行->销毁的整个过程,强调的是一个时间段
8.组件之间的数据共享
8.1父子组件之间的数据共享
父组件向子组件传递数据
父组件向子组件传递数据需要用到props自定义属性
父组件
<son :msg="msg" :user="user"></son>
data(){
return {
msg: 'hello',
user: {
name: 'xin',
age: 20
}
}
},
components: {
Son
}
子组件
props: {
msg: {
require: true,
type: String
},
user: {
require: true,
type: Object
}
}
不建议修改props属性的值
子组件向父组件传递数据
子组件向父组件传递数据使用自定义事件
使用$emit
向上发送数据
子组件
this.$emit(‘自定义事件’, 传递的数据)
data() {
return {
count: 0
}
},
methods: {
add() {
this.count++
this.$emit('numChange', this.count)
}
}
父组件
<div>
<p >{{countFromSon}}</p>
<son @numChange="getNewCount"></son>
</div>
getNewCount(val) {
this.countFromSon = val
console.log("hfoahe")
}
8.2兄弟组件之间的数据共享
在vue2.x
中,兄弟组件之间数据共享的方案时EventBus
- 创建
eventBus.js
模块,并向外共享一个Vue的实列对象
- 在发送方和接收方导入模块
- 在数据发送方,调用
bus.$emit('事件名称', 要发送的数据)
方法触发自定义事件 - 在数据接收方,调用
bus.$on('事件名称', 事件处理函数)
方法注册一个自定义事件
eventBus.js
import Vue from 'vue'
export default new Vue()
发送方
import bus from './eventBus'
<button @click="send">发送</button>
methods: {
send() {
bus.$emit('share', this.msg)
}
}
接收方
import bus from './eventBus'
created() {
bus.$on('share', (val)=>{
console.log("被触发了" + val)
} )
}
9.ref引用
$ref
用来辅助开发者不依赖jquery的情况
,获取DOM元素或组件的引用
每一个vue的组件实列上,都包含一个$ref对象
,里面存储着对应的DOM元素或组件的引用,默认情况下,组件的$ref指向一个空对象
在标签上添加ref
属性
<h1 ref="tet">hello vue</h1>
change() {
this.$refs.tet.style.color = 'red'
}
ref引用组件实例
ref可以操作组件中的方法和数据
<Ref ref="Ft"></Ref>
zero() {
this.$refs.Ft.change()
this.$refs.Ft.count = 0
}
this.nextTick的应用
组件的$nextTick(cb)
方法,会把cb回调推迟到下一次DOM更新周期之后执行,等组件DOM更新完成之后,在执行cb回调函数,从而保证cb回调函数可以操作到最想的DOM元素
10.动态组件
动态组件指的是动态切换组件的显示和隐藏
vue提供了一个内置的<components>
组件,专门用来实现动态组件的渲染
is
属性里是要渲染的组件
<components is="Son"></components>
<components :is="com"></components>
keep-alive使用
keep-alive
可以让组件不被销毁,组件会被缓存
<keep-alive>
<components :is="com"></components>
</keep-alive>
keep-alive对应的生命周期函数
当组件被缓存
时,会自动触发组件的deactivated
生命周期函数
当组件被激活
时,会自动触发组件的activated
生命周期函数
当组件第一次被创建的时候,即会执行created,也会执行activated
当组件被激活时,只会触发activated,不会触发created,因为组件没有被重新创建
deactivated() {
console.log("组件被缓存")
},
activated() {
console.log("组件被激活")
}
keep-alive的include属性
include属性用来指定:只有名称匹配的组件
会被缓存,多个组件之间使用英文的逗号
分隔
<keep-alive include="Kid">
<components :is="com"></components>
</keep-alive>
keep-alive的exclude属性
exclude属性用来排除组件
<keep-alive exclude="Kid">
<components :is="com"></components>
</keep-alive>
include和exclude不能同时使用
11.插槽
插槽slot是vue为组件的封装者
提供的能力,允许开发者在封装组件时,把不确定的,希望由用户指定的部分定义为插槽
可以放置默认内容,如果添加了则会覆盖
<slot name="default">
<h1>默认内容</h1>
</slot>
父组件
<Son>
<p>插槽的使用</p>
</Son>
子组件
<template>
<div>
<p>{{ msg }}</p>
<hr/>
<slot></slot>
</div>
</template>
vue规定,每一个slot插槽都有一个name名称,如果省略则默认是default
v-slot:指令
v-slot指定填充的插槽,只能放在template标签下,不能用在元素下
简写形式:#
<Son>
<template v-slot: default>
<p>插槽的使用</p>
</template>
</Son>
作用域插槽的使用
可以在插槽中定义数据,相当于子传父
<slot name="default" msg="hello vue">默认内容</slot>
<Son>
<template #default="obg">
<p>插槽的使用</p>
<p>{{ obg }}</p>
</template>
</Son>