参考:
https://github.com/Panyue-genkiyo/vue-learning
https://www.yuque.com/cessstudy/kak11d/pevvin
安装
初学者建议直接下载js文件直接用script标签引入。
https://v2.cn.vuejs.org/v2/guide/installation.html
1、vue2
1. Vue对象
var vm = new Vue({
el: '#app',//元素选择器
data: obj
})
v.$mount('#root')//也可以通过这种方式替代el指定容器
当一个 Vue 实例被创建时,它将 data 对象中的所有的 property 加入到 Vue 的响应式系统中。当这些 property 的值发生改变时,视图将会产生“响应”,即匹配更新为新的值。
2. 模板语法
插值语法:{{text}} 指定标签体内文本
指令语法:v-bind:属性=“xxx” 简写为 : 指定标签内属性
v-model 只能用于输入类,默认属性是value,v-model:value简写为v-model
每修改一次data中的数据,vue都重新解析一次模板。
3. 数据代理
通过一个对象代理对另一个对象的属性进行操作。
Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty
getter:
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions/get
vm中的数据代理
Vue中的bind就是通过数据绑定实现的。
数据代理:通过数据代理,name=_data.name,方便编程。
4. 事件
事件基础
1.使用v-on:xxx 或 @xxx 绑定事件,其中xxx是事件名;
2.事件的回调需要配置在methods对象中,最终会在vm上;
3.methods中配置的函数,不要用箭头函数!否则this就不是vm了;
4.methods中配置的函数,都是被Vue所管理的函数,this的指向是vm 或 组件实例对象;
5.@click=“demo” 和 @click=“demo($event)” 效果一致,但后者可以传参;
new Vue({
el: "#root",
data(){
},
methods:{
showInfo(e){
// e.preventDefault(); 阻止a标签默认行为
// e.stopPropagation() //阻止事件冒泡
// alert('你好');
console.log(e.target);
},
}
});
事件修饰
1.prevent:阻止默认事件(常用);
2.stop:阻止事件冒泡(常用);
3.once:事件只触发一次(常用);
4.capture:使用事件的捕获模式;
5.self:只有event.target是当前操作的元素时才触发事件;
6.passive:事件的默认行为立即执行,无需等待事件回调执行完毕;
<button @click.stop=“showInfo”>点我提示信息
键盘事件
1.Vue中常用的按键别名:
回车 => enter
删除 => delete (捕获“删除”和“退格”键)
退出 => esc
空格 => space
换行 => tab (特殊,必须配合keydown去使用)
上 => up
下 => down
左 => left
右 => right
2.Vue未提供别名的按键,可以使用按键原始的key值去绑定,但注意要转为kebab-case(短横线命名)
3.系统修饰键(用法特殊):ctrl、alt、shift、meta
(1).配合keyup使用:按下修饰键的同时,再按下其他键,随后释放其他键,事件才被触发。
(2).配合keydown使用:正常触发事件。
4.也可以使用keyCode去指定具体的按键(不推荐)
5.Vue.config.keyCodes.自定义键名 = 键码,可以去定制按键别名
<input type="text" @keyup.enter="showInfo" placeholder="按下回车提示输入"/>
<input type="text" @keyup.delete="showInfo" placeholder="退格或删除提示输入"/>
<input type="text" @keyup.esc="showInfo" placeholder="按下esc提示输入"/>
<input type="text" @keydown.tab="showInfo" placeholder="按下tab示输入"/>
<input type="text" @keyup.ctrl="showInfo" placeholder="按下command提示输入"/>
<input type="text" @keydown.p="showInfo" placeholder="按下p提示输入"/>
<!--键盘事件的修饰符也可以连用-->
<input type="text" @keydown.command.g="showInfo" placeholder="按下command和g提示输入"/>
5. 计算属性
某一绑定属性可以由data中其他两个数据计算得到。
1.定义:要用的属性不存在,要通过已有属性计算得来。
2.原理:底层借助了Objcet.defineproperty方法提供的getter和setter。
3.get函数什么时候执行?
(1).初次读取时会执行一次。
(2).当依赖的数据发生改变时会被再次调用。
4.优势:与methods实现相比,内部有缓存机制(复用),效率更高,调试方便。
5.备注:
1.计算属性最终会出现在vm上,直接读取使用即可。
2.如果计算属性要被修改,那必须写set函数去响应修改,且set中要引起计算时依赖的数据发生改变。
除了数据属性,Vue 实例还暴露了一些有用的实例属性与方法。它们都有前缀,以便与用户定义的属性区分开来。es6中可以采用${XXX}来在字符串中插入变量
const vm = new Vue({
el: '#root',
data: {
//data里的都是属性
firstName: '张',
lastName: '三',
test:'test'
},
//计算属性--> 旧属性加工
computed: {
fullName: {
//get的作用,当读取fullName时get就会被调用,且返回值就做为fullName的值
//defineProperty
//注意vm._data是不存在计算属性的
//计算属性算完之后直接丢到了viewModel实例对象身上
/**
* get的调用时机
* 1.初次读取计算属性时
* 2.所依赖的数据(data中的属性)发生变化时,不改变的话直接读缓存
* 3.methods没有缓存,读几次就调用几次无论要用的数据是否发生变化
* @returns {string}
*/
get(){
//此时get函数中的this指向是vm
console.log('get调用了', this);
return this.firstName + '--' + this.lastName
},
/**
* set什么时候调用
* 1.当fullName被修改时
* @param value
*/
set(value){
//修改计算属性所依赖的普通属性(放在data里面的)
//this === vm
const [ firstName, lastName ] = value.split('-');
this.firstName = firstName;
this.lastName = lastName; //依赖属性发生改变之后,计算属性自动改变
}
}
}
});
//简写
const vm = new Vue({
el: '#root',
data: {
//data里的都是属性
firstName: '张',
lastName: '三',
test:'test'
},
//计算属性--> 旧属性加工
computed: {
//简写形式
//前提:计算属性只考虑读取不考虑修改 set丢了
//简写计算书写为一个函数(这个函数当成getter使用), 注意不要写箭头函数
//执行完getter之后,vm直接保存返回的数据为fullName属性的属性值,此时vm.fullName不是函数而是一个确切的计算值
fullName: function (){
return this.firstName + '--' + this.lastName;
}
}});
6. 监视属性 watch
监视属性,属性值改变时调用回调函数。
监视属性watch:
1.当被监视的属性变化时, 回调函数自动调用, 进行相关操作
2.监视的属性必须存在,才能进行监视!!
3.监视的两种写法:
(1).new Vue时传入watch配置
(2).通过vm.$watch监视
深度监视
(1).Vue中的watch默认不监测对象内部值的改变(一层)。
(2).配置deep:true可以监测对象内部值改变(多层)。
备注:
(1).Vue自身可以监测对象内部值的改变,但Vue提供的watch默认不可以(想让它可以则配置deep:true)!
(2).使用watch时根据数据的具体结构,决定是否采用深度监视。
computed和watch之间的区别:
1.computed能完成的功能,watch都可以完成。
2.watch能完成的功能,computed不一定能完成,例如:watch可以进行异步操作。计算属性依靠返回值。
两个重要的小原则:
1.所被Vue管理的函数,最好写成普通函数,这样this的指向才是vm 或 组件实例对象。
2.所有不被Vue所管理的函数(定时器的回调函数、ajax的回调函数等、Promise的回调函数),最好写成箭头函数,
这样this的指向才是vm 或 组件实例对象。
7. 绑定样式
- class样式
写法 :class=“xxx” xxx可以是字符串、对象、数组。
字符串写法适用于:类名不确定,要动态获取。
对象写法适用于:要绑定多个样式,个数不确定,名字也不确定。
数组写法适用于:要绑定多个样式,个数确定,名字也确定,但不确定用不用。 - style样式
:style="{fontSize: xxx}“其中xxx是动态值。
:style=”[a,b]"其中a、b是样式对象。
总结来说就是需要绑定对象,可以是一个也可以是多个(数组),对象里面要写css样式(驼峰)。
8. 条件渲染:
1.v-if
写法:
(1).v-if=“表达式”
(2).v-else-if=“表达式”
(3).v-else=“表达式”
适用于:切换频率较低的场景。
特点:不展示的DOM元素直接被移除。
注意:v-if可以和:v-else-if、v-else一起使用,但要求结构不能被“打断”。
2.v-show
写法:v-show=“表达式”
适用于:切换频率较高的场景。
特点:不展示的DOM元素未被移除,仅仅是使用样式隐藏掉
3.备注:使用v-if的时,元素可能无法获取到,而使用v-show一定可以获取到。
4.v-if与template的配合使用,不破坏结构。
9. 列表渲染
列表生成(key属性)
v-for指令:
1.用于展示列表数据
2.语法:v-for=“(item, index) in xxx” :key=“yyy”
3.可遍历:数组、对象、字符串(用的很少)、指定次数(用的很少)
面试题:react、vue中的key有什么作用?(key的内部原理)
- 虚拟DOM中key的作用:
key是虚拟DOM对象的标识,当数据发生变化时,Vue会根据【新数据】生成【新的虚拟DOM】,
随后Vue进行【新虚拟DOM】与【旧虚拟DOM】的差异比较,比较规则如下:
2.对比规则:
(1).旧虚拟DOM中找到了与新虚拟DOM相同的key:
①.若虚拟DOM中内容没变, 直接使用之前的真实DOM!
②.若虚拟DOM中内容变了, 则生成新的真实DOM,随后替换掉页面中之前的真实DOM。
(2).旧虚拟DOM中未找到与新虚拟DOM相同的key
创建新的真实DOM,随后渲染到到页面。 - 用index作为key可能会引发的问题:
1. 若对数据进行:逆序添加、逆序删除等破坏顺序操作:
会产生没有必要的真实DOM更新 ==> 界面效果没问题, 但效率低。
2. 如果结构中还包含输入类的DOM:
会产生错误DOM更新 ==> 界面有问题。 - 开发中如何选择key?:
1.最好使用每条数据的唯一标识作为key, 比如id、手机号、身份证号、学号等唯一值。
2.如果不存在对数据的逆序添加、逆序删除等破坏顺序操作,仅用于渲染列表用于展示,
使用index作为key是没有问题的。
问题:就是在列表头部插入一条数据,如果使用index作为key,index是不变的,就会导致部分数据不发生变化。
列表过滤
computed能实现的watch都能实现,computed更方便,所以优先用computed(计算属性)。
列表过滤总结来说,就是通过双向绑定得到用户输入,然后通过watch或computed得到过滤后的数据,修改数据列表并显示出来。
列表排序
arr.sort的参数是一个函数,该函数接收两个参数,确定该两个参数的比较办法。
如上面的sort函数的参数是两个对象,这两个对象的大小是通过其age属性决定的。
10. 数据监测(响应式数据)
vue中data中所有的数据都是响应式数据,即通过数据代理,添加getter和setter方法,当数据改变时,监测到数据的变化。
问题:怎么向data中添加一个响应式的数据?
只有在vm对象创建时,data中的数据才会被vue包装成响应式的,即有getter方法和getter方法,如果想vm中添加数据,我们直接通过vm._data添加数据,所添加的数据不是响应式的,页面上不能监测到。这时应该通过vue.set方法添加。
需要注意的是,如果data中存在数组,那么该数组中的元素是没有getter和setter的,也就是说直接修改list[0]=‘xxx’,无法做到响应式,可以使用posh等函数操作数组做到响应式,但是注意这些方法不是数组对象的,而是vue经过包装得到的。
11. 收集表单数据
<br/>
年龄: <input type="number" v-model.number="age"/>
<br/>
标签中type属性为number,是html提供的,表示输入框只能输入数字类型的数据,但是输入的数字存储到data中之后仍然会为字符串类型,后面的v-model.number表示data中该数据的类型为数字。一般情况下两者同时使用。
总结一下就是在使用表单时,默认绑定的是input的value值,如上年龄中用户输入的value就会绑定到data.age,但是单选框需要配置value值,复选框在没有配置value的情况下会绑定checked的状态,复选框配置value值同时应该将其类型设置为数组。
12. 过滤器
时间格式
dayjs
13. 指令
内置指令
v-text
v-html
v-clock
v-once
v-pre
即不需要使用vue解析的标签可以加v-pre,如
<h2 v-pre>Vue其实很简单</h2>
自定义指令
自定义指令在directive中是一个函数,‘v-函数名’ 表示指令名,标签通过使用v-函数名与指令绑定,函数有两个参数,第一个是dom标签element,第二个是绑定的值badding。
1.指令与元素成功绑定(但注意此时dom元素还没有成功的被弄到页面上去)时会被调用 (首次,类似于dom元素一加载)
2.指令所在的模版被重新解析时会被再次调用
这种情况下会出现一些问题,比如如果一些dom元素在绑定时还未加载到页面,则会出现错误。这时候就需要用到下面这种方式,将该指令定义为一个对象,对象中函数在不同的时候调用。
注意:
- 上例中fbind可以不加引号,但是如果指令名中含有‘-’,不是v-中的-,如big-number这种形式,则必须加引号。
- 函数中this指向window
14. 生命周期
对象简写
生命周期函数
15. 组件
非单文件组件(不常用)
非单文件组件是指一个文件不只是一个组件,而是多个组件,这种方式在之后的组件化编程中很少使用。简单了解即可。
定义组件
注意两点:1)组件的data必须是函数形式,这是因为对象是引用,修改对象中的数据可能会导致其他地方引用时出错。2)组件可以直接通过定义一个对象获得,并将该对象传入Vue中的compotens(常见)。标准的写法是:对象名=Vue.extend()。
组件嵌套
单文件组件
即每个.vue文件都是一个组件,组件中有三个标签,template,script和style。