--外功篇-《邂逅Vue》-学习笔记(持续更新)--
学习笔记
生命周期
beforeCreate
created
beforeMount
mounted
beforeUpdate
updated
beforeDestroy
destroyed
一些指令
v-once
表示该标签只渲染一次,其数据不会随着数据的改变而改变
v-html
表示当前标签以html方式进行解析
v-text
以文本形式进行加载
v-pre
将内容原封不动的显示出来
v-cloak
将元素内容在解析结束之后再显示出来
v-bind 动态绑定属性
绑定标签的props(属性),则该属性的值依据Vue对象中的值而改变。同样的,在父子组件通信的过程中,同样通过属性的绑定进行传值。
v-bind 动态绑定class
在v-bind绑定class时,可以形如v-bind:class="{类名:boolean, 类名:三元表达式}"
的对象语法
也可以形如v-bind:class="['类名', '类名']"
的数组语法
v-bind 动态绑定style
在v-bind绑定class时,可以形如v-bind:style="{css属性名:属性值}"
的对象语法。(css属性名使用驼峰命名法或者短横线形式)
也可以形如v-bind:style="[{css属性名:属性值}, {css属性名:属性值}]"
的数组语法
v-for (搭配v-bind实现点击列表改变样式的需求)
v-for="(item, index) in array"
遍历数组
v-for="(item, key, index) in obj"
遍历对象
官方推荐使用:key
进行对遍历元素的绑定(不要绑定index):
在绑定之后,如果list进行的变更,则vue会进行对比绑定的元素是否发生变更。能够提升效率。
(diff算法)
v-on 事件监听
在事件监听时,如果没有参数,可以不添加括号。
如果有参数,但不添加括号,则会传入event事件对象。
当我们需要event对象也需要其他参数时:
在调用方法是手动获取event方法:$event
v-on会触发事件冒泡可以使用v-on:click.stop
对事件冒泡进行阻止
v-on:click.prevent
可进行阻止默认事件
v-on:keyup.keyCode|keyAlias
监听键盘按键点击
.once
只触发一次的事件
v-if v-else-if v-else
v-if="boolean"
v-if往往添加bool值。
Vue在处理dom节点时会事先创建一个虚拟dom,存放进内存中。
在虚拟dom中,会检查是否已存在dom,经过判断会直接置换dom节点的属性,并不会重新添加dom。
v-show 是否需要显示
v-if为false,是直接将该dom节点删去
v-show为false时,则是将dom节点的display
属性设置为none
因此切换频率非常高的时候选择v-show避免重复渲染
v-model 双向绑定,绑定表单控件
因为v-model默认绑定表单value属性,所以只能在表单控件中使用
计算属性 computed
计算属性的setter和getter
computedMethods: {
set: function() {
},
get: function() {
return this.movies[0] + ' ' + this.movies[1];
}
}
计算属性一般没有set方法,是一个只读属性。
计算属性的缓存:
计算属性与methods的区别在于,computed的数据存在缓存,因此,其以来的只没有发生变化,其不会再次运行。
数据的响应式
哪些数组的方法是响应式的?
- push 在数组后面添加元素
- pop 移除数组最后一个元素
- unshift 在数组最前面添加元素(可以添加多个)
- shift 删除数组中第一个元素
- splice 删除元素、插入元素、替换元素。传3个参数(start, num, str):start,开始位置;num,删除个数;str,替换元素值
- sort 排序
- reverse 反转
PS直接改变数组值,vue不会对页面进行渲染刷新
若要直接进行修改,可使用splice方法
或者 使用 Vue.set(list, 0, 'newData')
过滤器filter
也是方法的一种
index|过滤器
组件化
创建构造器对象
const cpn = Vue.extend({
template:'<div>Hello World!</div>'
})
注册组件
Vue.component('app-cpn', cpn)
使用组件
<app-cpn></app-cpn>
组件语法糖注册方式
//全局组件
Vue.component('cpn', {
template: '<div>hello</div>',
components: {
}
})
//局部组件
const father = Vue.extend({
template: '<div><child></child></div>',
components: {
child: {
template: '<div>hello world!</div>'
}
}
})
全局组件
全局组件能在多个Vue实例下使用(代码如上创建即可)
局部组件
const app = new Vue({
el: "#app",
data: {},
components: {
appCpn: cpn
}
})
//局部组件需要使用短横线形式的话,可采用驼峰命名法
父组件和子组件
const child = Vue.extend({
template: '<div>hello world!</div>'
})
const father = Vue.extend({
template: '<div><child></child></div>',
components: {
child: child
}
})
Vue.component('father', father);
组件抽离写法
//script 标签写法
<script id="cpn" type="text/x-template">
<div>hello i am cpn</div>
</script>
//...
Vue.component('cpn', {
template: '#cpn'
})
//----------------
//template标签写法
<template id="cpn">
<div>hello i am template component</div>
</template>
//...
Vue.component('cpn', {
template: '#cpn'
})
组件的data
组件是一个单独功能的模块的封装,这个模块有属于自己的HTML模板,也有属于自己的数据data。
因此,组件的data必须返回一个函数形式,进行一个函数作用域的封装,保证其作用域内变量的封闭性。
所以在重复使用组件时,会重新申请多个作用域,对于相同的方法的问题,是因为方法作用于不同作用域的data,所以操作的对象并不相同。
Vue.component('cpn',{
template: '#cpn',
data: function() {
return {
message: 'hello i am a compnent data'
}
}
})
组件间的通讯
通过props向子组件传递数据
在子组件中,声明props属性,并设置属性变量名
例如:
const childCpn = {
template: '#childCpn',
props: ['cmovies', 'cmessage'],
dtat: function(){
return {
cmessage: message,
}
}
}
即cmovies
cmessage
充当组件child-cpn
的属性,通过v-bind
将其属性与父组件中的属性值进行绑定,完成数据由父组件向子组件的传递。
例如:
<div id="app">
<child-cpn v-bind:cmovies="movies" :cmessage="message"></child-cpn>
</div>
<template id="childCpn">
<div>
<p>{{cmessage}}</p>
<div>{{cmovies}}</div>
</div>
</template>
props的写法
1.常见的数组类型
2.对象类型(可以进行类型限制)
2.1 类型限制写法
props: {
cmovies: Array,
cmessage: String
}
2.2提供一些默认值
props: {
type: [String, Number], //传值类型,可传多个类型
default: 'hello world', //设置默认值,如果类型设置为对象,则应用函数返回一个对象
require: true, //标记为必传属性
}
props驼峰标识
在标签中不支持驼峰写法,应改写为短横线法。
例如:
<cpn v-bind:c-movies="movies">{{cMovies}}</cpn>
中c-movies
由驼峰命名改为短横线法
通过事件向父组件发送消息
-
在子组件中添加事件方法,并创建组件的监听属性
例如:<template id="child"> <div> <button @click="childClick(item.name)">{{item.name}}</button> </div> </template>
const childcpn = { template: '#child', data: function() { return { item: { id: 1, name: 'YaHaha' } } }, methods: { childClick(name) { this.$emit('listener-props', name); //监听属性名,用于在使用子组件时,使用v-on对该属性进行绑定 } } }
-
在使用子组件时对该事件进行监听即可
例如(继上述子组件之后):<div id="father"> <child-cpn @listener-props="fatherFunc"></child-cpn> </div>
const fathercpn = { template: '#father', data: function() { return { data: 'this is father component' } }, methods: { fatherFunc(name) { console.log(name); //接收来自子组件的item.name } }, components: { childCpn: childcpn } }
slot插槽
slot插槽的使用
<cpn><span>应用组件时添加内容时,会自动填充并覆盖掉插槽位置</span></cpn>
<!-- -->
<template id="cpn">
<div>
<slot><span>插槽可以使用默认值</span></slot>
</div>
</template>
插槽的定义需要在定义子组件时进行
在使用时,只需向子组件中添加标签元素,即可对插槽默认值进行替换。
若是多条填充内容只有一个插槽,则会将全部内容填充进唯一一个插槽中。
若是一条填充内容多个插槽,则会将全部插槽替换掉。因此需要具名插槽。
具名插槽
通过对插槽署名
例如:
<cpn><span slot='default1'>应用组件时添加内容时,会自动填充并覆盖掉插槽位置</span></cpn>
<!-- -->
<template id="cpn">
<div>
<slot name='default1'><span>插槽可以使用默认值</span></slot>
<slot name='default2'><span>插槽可以使用默认值</span></slot>
</div>
</template>
通过对填充标签设置属性slot='slot的name属性名'
实现对特定插槽的替换
前端模块化
webpack
Vue CLI
render函数。三个参数,(标签名,属性值,内容)
相比于vue1的将template转成抽象语法树ast再进行渲染不同,
vue2中直接将组建进行render处理成虚拟dom。
前端路由
底层
vue中默认是hash模式
history.pushState()
history.replaceState() 无法返回
使用
import VueRouter from 'vue-router';
import Vue from 'vue';
Vue.use(VueRouter);
const routes = [
{
path: '',
redirect: '/home',
component: Home
}
]
const router = new VueRouter({
routes,
mode: 'history',
linkActiveClass: 'active'
})
export default router;
<router-link to='/home' active-class='.active' replace>首页</router-link>
<!--默认渲染成a标签,可通过tag进行修改-->
<router-view></router-view>
class属性 : router-link-active
<!--不使用router-link-->
<button @click="homeclick">
home
</button>
<!--通过代码修改路径-->
<script>
homeclick() {
this.$router.push('/home')
}
</script>