# Vue_basic
**Repository Path**: wangxiaoshuaishuai/vue_basic
## Basic Information
- **Project Name**: Vue_basic
- **Description**: 保存一些vue相关练习和资料
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 1
- **Forks**: 0
- **Created**: 2021-09-27
- **Last Updated**: 2025-01-04
## Categories & Tags
**Categories**: Uncategorized
**Tags**: Vue, vue基础
## README
# Vue-basic-note
### vue初体验总结
##### 关于初体验控制台的提示信息
```js
// 提示信息一:
Download the Vue Devtools extension for a better development experience:
https://github.com/vuejs/vue-devtools
// 大概理解为: 缺少 Vue Devtools扩展工具 需要下载
// 解决方法:
// 在谷歌的商店安装 Vue Devtools扩展工具
// 提示信息二:
You are running Vue in development mode.
Make sure to turn on production mode when deploying for production.
See more tips at https://vuejs.org/guide/deployment.html
// 大概理解为: 在vue 启动时生成生产提示
// 解决方法:
// 阻止 vue 在启动时生成生产提示
Vue.config.productionTip = false;
```
##### 总结
1.想让Vue工作,就必须创建一个Vue实例对象,且必须传入一个配置对象。`new Vue({})`
2.demo容器中的代码,依然符合html规范,只不过其中混入了一些特殊的Vue语法。
3.demo容器中的html代码+Vue语法,我们称之为Vue模板。
### vue 注意点
几个注意点:
1.Vue实例和容器是一一对应的,真实开发中一定只有一个Vue实例,且真实开发中会配合组件一起使用。
2.data中的数据只要发生改变,模板中用到该数据的地方,就会自动更新。
3.{{xxx}}中的xxx要写js表达式,且xxx可以直接读取到data中配置的所有属性。
4.简单理解表达式:可以产生一个值 如果可以使用**const x = 表达式** 接收 来判断是否为表达式
注意区分【js表达式】与【js语句(代码)】
1.表达式:会产生一个值,可以放在任何一个需要值的地方
(1).100
(2).a
(3).demo()
(4).x === y ? 1 : 0
(5). 200 - 2
(6). arr.map()
2.语句(代码): 不会产生值,只是控制代码走向
(1). if(){}
(2). for(){}
(3). try{} catch(err){}
等等.....
##### 分析实例对象
```js
//创建一个Vue实例对象
new Vue({
el:'#demo', //el的值可以是:css选择器字符串(用的多)、写一个真实的DOM元素(几乎不用)
data:{ //data用于配置数据,数据供el所指定的容器去使用,data的值暂时先写成一个对象
name:'尚硅谷',
address:'宏福科技园',
person:{
name:'tom',
age:13
}
}
})
```
### 模板语法
Vue中的模板语法有2大类:
1.插值语法(胡子语法):
功能:用于解析标签体内容(不能用于解析标签属性)
写法:**{{xxx}}**,xxx是js表达式,且可以自动读取到data中的所有属性
2.指令语法:
功能:用于解析标签(标签属性、标签体、绑定事件........)
举例:v-bind:href = "xxx" 或简写为 :href = "xxx" xxx同样要写js表达式
v-bind: 这个必须懂
**: v-bind:的简写** 这个必须会 以后常用
备注1:Vue中有很多指令,且形式都是v-???,此处我们只是拿v-bind举个例子。
备注2:只有v-bind指令,才能简写为:,别的指令不行。
备注3:别的指令,有别的简写方式,但并不是所有的指令都有简写方式。
### 数据绑定
##### 两种数据绑定方式:
1.单向数据绑定(v-bind):数据只能从data流向页面。
```js
单向数据绑定(v-bind):
单向数据绑定(v-bind):
```
2.双向数据绑定(v-model):数据不仅能从data流向页面,也能从页面流回data
```js
双向数据绑定(v-model):
双向数据绑定(v-model):
```
**备注1**:v-model只能应用在表单元素上(输入类元素)
备注2:v-model默认只收集元素的value值,所以v-model:value="xxx" 可以简写成 v-model="xxx"
### MVVM
MVVM模型:
1. M:模型(Model) :对应data中的数据
2. V:视图(View) :模板
3. VM:视图模型(ViewModel) : Vue实例对象
观察发现:
1.vm身上有很多$开头的属性或方法,这些属性或方法一般都是给我们程序员用的(也不都用)。
2.data中配置的属性,最后都出现在了vm身上。
3.vm身上所有的属性,以及Vue.prototype中的属性,在模板中都可以直接使用。
### el和data两种写法
##### el的两种写法
```js
//el的第一种写法——借助el配置项
new Vue({
el:'#demo',
data:{
name:'尚硅谷'
}
})
//el的第二种写法——借助vm.$mount(选择器)
const vm = new Vue({
data:{
name:'尚硅谷'
}
})
vm.$mount('#demo')
```
##### data的两种写法
```js
//data的第一种写法—— 对象式
new Vue({
el:'#demo',
data:{
name:'尚硅谷'
}
})
//data的第二种写法—— 函数式,现阶段我们可以把data直接写成一个对象,但学到了组件后,data就必须是一个函数了!
new Vue({
el:'#demo',
data(){
console.log(this) //data函数必须写成普通函数,这样其中的this才是vm
return {
name:'尚硅谷'
}
}
})
```
##### 关于el和data两种写法的总结
1.el有2种写法
(1).第一种:
new Vue时候配置el属性(css选择器字符串 或 亲自获取的DOM元素)。
(2).第二种:
先创建Vue实例,随后再通过:vm.$mount('#demo')指定服务的容器。
(3).用哪一种呢?随意,只不过第二种更灵活一点
例如:可以在Vue实例对象创建n秒以后,再指定容器。
2.data有2种写法
(1).第一种对象式:
data:{name:'尚硅谷'}
(2).第二种函数式:
data(){
return {
name:'尚硅谷'
}
}
如何选择? 目前哪种写法都可以,以后学习到组件时,data必须使用函数式,否则会报错。
3.一个重要的原则:
由Vue管理的函数(现阶段我们只学了个data函数,别的没学呢),
一定不要写箭头函数,一旦写了箭头函数,this就不再是Vue实例了。
### vue 数据代理
1.前情提要:
我们new Vue(options)时传入的那个data,被Vue收到了,放在了vm上名为_data。
2.Vue中的数据代理:
通过vm对象来对_data中属性的操作(读/写)
2.Vue中的数据代理:
通过vm对象来代理对_data中属性的操作(读/写)
3.**面试题** Vue中数据代理的好处:(或者也可以说为什么要使用数据代理)
模板中可以更加方便的操作_data中的数据,例如:
(1).若无数据代理:{{_data.name}}
(2).若有数据代理:{{name}} ———————— 香!!!
4.基本原理:
遍历_data对象中所有的属性,通过Object.defineProperty()一个一个都添加到vm上。
随后vm上就拥有了_data中所有的属性,且都有自己的getter/setter。
getter/setter内部操作(读/写)的是_data中对应的属性。
### 事件处理
##### 事件绑定
1.使用v-on:xxx 或 @xxx 绑定事件,其中xxx是事件名,原生有的DOM事件都可以写;
2.事件的回调函数需要配置在methods中;
3.methdos中的函数最终也会出现在vm上(但不存在数据代理了,是直接放在vm上的);
4.methods中配置的函数,是Vue所管理的函数,所以务必要写成普通函数;
###### 两种写法
```js
```
###### 事件对象
事件对象:
``
当我们点击button时,Vue会帮我们调用showMsg,并且会自动传入当前的事件对象。
##### 事件传参
1.不传参数,那就写:@click="showMsg" ,showMsg会收到一个event
2.传一个参数,那就写:@click="showMsg(6)" ,showMsg会收到一个6
3.传多个参数,那就写:@click="showMsg(6,7,8)" ,showMsg会收到:6、7、8
4.传参同时还想用事件对象,那就写:@click="showMsg($event,6)",showMsg会收到:事件对象、6
5.注意:传参时,当然也可以传递data中的数据,例如@click="showMsg(name)"
##### 事件修饰符
```js
重要的事件修饰符:
1.prevent:阻止默认事件;
2.stop:阻止事件冒泡;
3.once:事件只触发一次;
不常用的事件修饰符:
1.capture:使用事件的捕获模式
2.self:只有event.target是当前操作的元素时才触发事件
3.passive:事件的默认行为立即执行 无需等待事件回调执行完毕
备注:事件修饰符,可以串联
```
##### 键盘事件
```js
1.Vue中常用的按键别名(牢牢掌握):
回车 => enter
删除 => delete (捕获“删除”和“退格”键)
退出 => esc
空格 => space
换行 => tab(必须配 合keydown才有效果)
上 => up
下 => down
左 => left
右 => right
2.备注:也可以使用keyCode去指定具体的按键(不太推荐)
```
### 计算属性
* 提到计算属性 就应该想到**智能** **缓存**
##### 计算属性标准写法
```js
计算属性:
1.定义:要用的属性(数据)不存在,要计算得来。
2.原理:底层通过Objcet.defineproperty实现的。
3.关于get何时调用?
get函数何时调用?
(1).初次读取fullName时会执行一次。
(2).当计算fullName所依赖的数据发生改变时会被再次调用。
set函数(setter)何时调用?—— 只有一个时候:当计算属性被直接修改的时。
4.优势:与methods实现相比,内部有缓存机制(复用),效率更高,且调试方便。
5.备注:
(1).计算属性最终会出现在vm上,在模板中可直接使用即可
(2).如果计算属性后期要被直接修改,那必须写set函数(setter)去响应修改。
```
代码示例:
```js
computed:{
//声明一个计算属性,名为:fullName,值得看get函数(getter)调用的返回值
fullName:{
//get函数(getter)何时会被调用?—— 1.Vue初次解析模板的时候(模板中得用)2.当该计算属性所依赖的数据发生变化时候
get(){
console.log('fullName-get')
//解构赋值,从vm中读取:姓、名
const {firstName,lastName} = this
return firstName[0].toUpperCase() + firstName.slice(1) + '-' + lastName
},
set(val){
const arr = val.split('-')
this.firstName = arr[0].toLowerCase()
this.lastName = arr[1]
}
}
}
```
##### 计算属性的简单写法
* **前提**是 当计算不被修改时(不用setter时),才能简写
代码如下:
```js
computed:{
fullName(){
//解构赋值,从vm中读取:姓、名
const {firstName,lastName} = this
return firstName[0].toUpperCase() + firstName.slice(1) + '-' + lastName
}
}
```
### 监视属性watch
1.当被监视的属性变化时, 回调函数自动调用, 进行相关操作
2.监视的属性必须存在,才能进行监视!!
3.监视的两种写法:
(1).new Vue时传入watch配置
(2).通过vm.$watch监视(了解即可)
备注:被监视的可以是:属性(data),也可以是计算属性(computed)
```js
```
##### 立即监视
立即监视:
1.配置:immediate:true
2.作用:可以让数据没有发生变化时,Vue初次工作时就执行一次监视的回调
```js
watch:{
isHot:{
immediate:true, // 这里是否需要开启立即监视
handler(newValue,oldValue){
console.log('isHot的值发生变化了~~~',newValue,oldValue)
}
}
}
```
##### 深度监视
深度监视:
(1).watch默认不监测对象内部值的改变(监视一层)。
(2).配置deep:true可以监测对象内部值改变(监视多层)。
备注:
(1).Vue自身可以监测对象内部值的改变(无论多深都可以),但Vue给程序员提供的watch默认不可以!
(2).使用watch时根据数据的具体结构,以及需求,决定是否采用深度监视。
```js
watch:{
//监视某个对象中某个属性的变化
/* 'age.foreignAge':{
handler(){
console.log('foreignAge被改变了')
}
}, */
//监视某个对象的改变(地址值),不监测对象中属性的改变
/* age:{
handler(){
console.log('age被改了')
}
} */
//监视某个对象的改变(地址值),且也可以监视到对象中属性的改变
age:{
deep:true, //开启深度监视
handler(){
console.log('age被改了 或 age中的某个属性改了')
}
}
}
```
##### 监视属性的标准写法和简写
```js
watch:{
//标准写法
/* isHot:{
handler(value){
if(value) this.url = './imgs/re.jpg'
else this.url = './imgs/cool.jpg'
}
} */
//简写
isHot(value){
if(value) this.url = './imgs/re.jpg'
else this.url = './imgs/cool.jpg'
}
}
```
### computed计算属性和watch监视属性的总结(面试相关)
```txt
computed和watch之间的区别:
1.computed能完成的功能,watch都可以完成。
2.watch能完成的功能,computed不一定能完成,最具代表性的:watch可以进行异步操作。
computed:
(1).侧重在【算】,核心是:计算出来的值。
(2).靠return来输出计算的结果。
(3).不能开启异步任务。
watch:
(1).侧重在【监视】,核心是:xxx变了,我要做???事。
(2).无需return,靠内部逻辑去完成要做的事。
(3).可以开启异步任务。
两个重要的原则:
1.所被Vue管理的函数,要写成普通函数,这样this的指向才是vm 或 组件实例对象。
2.所有不被Vue所管理的函数(定时器的回调函数、ajax的回调函数等、Promise的回调函数),
要写成箭头函数,这样this的指向才是vm 或 组件实例对象。
```
### 绑定样式
绑定class样式
写法为: :class="xxx" xxx可以是字符串、对象、数组。
(1).字符串写法适用于:要绑定的样式,类名不确定。
(2).对象写法适用于:要绑定的样式,个数确定,类名也确定,但不确定用不用。
(3).数组写法适用于:要绑定的样式,个数不确定、类名也不确定。
### 条件指令
v-if
写法:
(1).v-if="表达式"
(2).v-else-if="表达式"
(3).v-else
适用于:切换频率较低的场景。
特点:不展示的DOM元素直接被移除。
注意1:v-if可以和:v-else-if、v-else一起使用,但要求结构不能被“打断”。
注意2:如果使用v-if,可能会出现无法获取元素的问题。
v-show
写法:v-show="表达式"
适用于:切换频率较高的场景。
特点:不展示的DOM元素依然在,仅仅是使用样式隐藏掉
### 数据代理与数据劫持(面试相关)
数据代理:
1.目的:让程序员更加方便的读取到_data中属性;
2.原理:Object.defineProperty;
3.体现:vm身上有每一个属性的proxyGetter、proxySetter;
4.当修改vm上的属性时,该属性对应的proxySetter就会调用,去修改_data中对应的属性;
5.当读取vm上的属性时,该属性对应的proxyGetter就会调用,去读取_data中对应的属性;
数据劫持(_data里的那点事):
1.目的:为了捕获到数据的改变,进而重新解析模板;
2.原理:Object.defineProperty;
3.体现:_data身上的每一个属性不直接给值,而是都有对应的:reactiveSetter、reactiveGetter;
4.当修改_data上的属性时,该属性对应的reactiveSetter就会调用;
且在reactiveSetter中Vue会:更新数据、重新解析模板;
5.当读取_data上的属性时,该属性对应的reactiveGetter就会调用,返回对应的值;