VUE官方网址
vue的属性和方法
vue的属性和方法
- var data={a:1}
- var vm=new Vue({el:'#app',data:data}) 属性:
- vm.data就是vm中data存储的变量,同vm.a 方法:
- vm.$watch('a',function(newValue,oldValue){ // 观察变量a发生改变时会触发函数,参数1为变化后的值,oldValue为变化前的值}
生命周期钩子
生命周期钩子(因箭头函数没有this,固生命周期钩子不能用箭头函数定义)
- beforeCreate:function(){},// 实例创建之前
- created:function(){}, // 实例创建之后,通常获取ajax
- beforeMount:function(){}, // 数据挂载到模版之前
- mounted:function(){}, // 数据挂载到模版之后,通常写window事件
- beforeUpdate:function(){}, // 数据变化之前
- updated:function(){}, // 数据、结构已经更新完成
- beforeDesdroy(){}, // 实例销毁之前
- destroyed(){} // 实例销毁之后
内置指令
指令 v-xxx
指令即带有v-前缀的特性,当指令的表达式(值)发生改变时,将产生的连带影响响应式地作用于DOM
-
- v-once 只渲染一次,变量发生改变不会进行改变
<span v-once> {{msg}} </span>
-
- v-html 渲染html代码
<p v-html="rawHtml"></p>
-
- v-bind 给原html属性绑定变量
// 所有的v-bind:都可简写为 :
<div v-bind:class="color">test...</div> // 简写 <div :class="color"></div>
// 此时的color为vue的变量 color:'red'而非类名
-
- 条件渲染 v-if、v-else-if、v-else 是否渲染标签
// 一般不频繁更换状态时使用v-if
<p v-if="seen"></p> // seen为true时渲染p标签,false时不渲染
<div v-if="type=='A'"></div> // type为 'A'时
<div v-else-if="type=='B'"></div> // type为 'B'时
<div v-else-if="type=='C'"></div> // type为 'C'时
<div v-else"></div> // type不为A、B、C时
-
- 条件渲染 v-show 标签是否显示
// 一般频繁更换状态时使用v-show
<h1 v-show="ok"></h1> // ok为true时h1标签的display为none
-
- 类名渲染v-bind:class
// 表达式结果的类型可以是字符串、对象、数组
字符串表达式:
<div class="test" :class="activeClass"></div>
// activeClass:'active green'
对象表达式:
<div class="test" :class="{active:isActive,green:true}"></div>
// isActive为true时存在active类名 且与原class可以同时存在
数组表达式:
<div :class="[ 'active','green',{'active2': true}]"></div>
-
- 行内样式渲染 v-bind:style
<div :style="{color:color,fontSize:size,background: isRed ? '#f00' : ''}"></div>
// color:'#f00',size:'50px',isRed:true
// 注意不能写font-size,要改成fontSize
-
- 列表渲染 v-for
数组渲染:
<li v-for="(item,index) in items" :key="item.id">
// items:[{id:1,message:'a'},{id:2,message:'b'}]
// key的作用是数据的唯一标识,item没有id时key采用index
{{ item.message }} // 此时的item.message为'a','b'
{{ index }} // 此时的index为下标0,1
</li>
对象渲染:
<li v-for="value,key,index in object" :key="key">
// object:{title:'a',author:'b','publishedAt:'c'}
{{ value }} // 此时的value为 a,b,c
{{ key }} // 此时的key为 title,author,publishedAt
{{ index }} // 此时的index为下标0,1
</li>
-
- 事件绑定v-on
<button v-on:click="counter+=1"></button>
// data:{counter:0}
<button v-on:click="f1"></button>
// methods:{ f1:function(event){} } // 不传参时参数默认会传event参数
<button v-on:click="f1('abc')"></button>
// methods:{ f1:function(str){ console.log(str); } }
<button v-on:click="f1($event)"></button>
// 传参时$event变量为事件变量
-
- v-model 表单双向数据绑定
原理:
<yxdt-rate v-model="rate"></yxdt-rate>
// v-model="rate" 是 :value="rate" @input="rate = $event.target.value" 的缩写。
// 自定义双向绑定 :val="rate" @input="setRate" setRate(rate){ this.rate=rate; }
输入表单:
<input v-model="message">
// 当input框的值发生改变时 p标签里的内容也会发生改变
<p>{{message}}</p>
复选框:
<input type="checkbox" value="a" v-model="checkedNames">
<input type="checkbox" value="b" v-model="checkedNames">
<input type="checkbox" value="c" v-model="checkedNames">
<p>{{checkedNames}}</p> // 全选中的渲染结果为 ["a","b","c"]
// data:{ checkedNames:[] }
// 可设默认值 data:{ checkedNames:['a','b'] }
单选框:
<input type="radio" value="a" v-model="picked" name="test">
<input type="radio" value="b" v-model="picked" name="test">
<p>{{picked}}</p> // 选中a时 picked为a
下拉框:
<select>
<option v-for="c in citys" :value="c.code" v-model="sh">{{c.name}}</option>
</select> // data:{ citys:[{value:'bj',name:'beijing'},{value:'sh',name:'shanghai'},..
指令的修饰符
让指令以特殊的方式绑定
- 1.stop 阻止冒泡
<div @click="click1">
<div @click.stop="click2">click me</div>
// 此时只执行click2函数不执行click1函数
</div>
- 2.prevent 阻止默认事件
<form v-on:submit.prevent="onSubmit"></form>
// 修饰符可串联
<a v-on:click.stop.prevent="doThat"></a>
// 只有修饰符也可以
<form v-on:submit.prevent></form>
- 3.capture 事件捕获
<div v-on:click.capture="dothis"></div>
- 4.self 只有当自身触发时才执行函数
<div v-on:click.self="dothat"></div>
- 5.once 点击的事件只会触发一次
<div v-on:click.once="dothat"></div>
- 6.passive
修饰符会执行默认方法
- 7.按键修饰符 v-on:keyup.按键名 // @keyup.enter="fn"
定义事件 methods
定义事件
var vm=new Vue({
...,
methods:{
click1:function(){},
click2:function(){},
}
});
注册全局组件 Vue.component
定义:
Vue.component('button-counter',{
// 组件必须在new Vue之前定义 且在挂载标签内调用
data:function(){ // 该组件的数据,必须为函数
return { count:0 }
},
template:'<button v-on:click="count++"> Click Me {{count}} times</button>'
});
var vm=new Vue({...})
调用(组件可复用):
<button-counter></button-counter>
Vue-cli中注册自定义组件:
const myComponent=require('./components/base/base-myComponent.vue');
自动循环添加:
const requireComponent = require.context(
'./components/base',
false,
/base-[a-z]\w+\.(vue|js)$/
)
requireComponent.keys().forEach(fileName => {
const componentConfig = requireComponent(fileName)
// 转化大驼峰命名(./base-autofold.vue -> BaseAutofold)
const componentName = upperFirst(
camelCase(
fileName.replace(/^\.\/(.*)\.\w+$/, '$1')
)
)
Vue.component(
componentName,
componentConfig.default || componentConfig
)
})
组件间通信 父子组件传参
父传子,有三种props向子组件传递数据的方式:
- 父组件:
<my-component :id="id" :name="name" :getEmp="getEmp"></my-component>
- 子组件:
const MyComponent={
template:'<div></div>',
props:['id','name','getEmp'] // 方式1,指定传递属性名
props:{ // 方式2,指定传递属性名和数据类型(Number,String,Array,Object,Function,Promise,Boolean)
id:Number,
name:String,
getEmp:Function
}
props:{ // 方式3,指定属性名、数据类型、必要性、默认值
name:{
type:String, // 数据类型
required:true, // 必要性
default:'mxg' // 默认值
} // 当default为数组时:default(){ return [] }
}
}
子传父,$emit子组件向父组件发送消息(等同于父元素通过props传递函数给子组件)
- 父组件:
<my-component @get_emp="getEmp"></my-component> // 等同 :getEmp="getEmp"
// get_emp为自定义事件名,事件名不能大写,@可以替换为v-on:,getEmp为父组件函数
- 子组件:
const MyComponent={
template:'<div><a @click="myGet">click</a></div>',
methods:{
myGet(){
this.$emit('get_emp','param');// 通过$emit调用执行父组件参数get_emp的函数,第二个参数开始为参数
}// 等同 props:['getEmp'],this.getEmp('param')
}
}
slot插槽,父组件向子组件传递标签、数据
slot插槽,父组件向子组件传递标签、数据(传递的插槽数据需定义在父组件中)
- 单个插槽
父组件:
<button-counter> <h2>h2</h2> </button-counter>
子组件:
Vue.component('button-counter',{
...
template:'<div><h1>h1</h1><slot></slot></div>
});
- 多个插槽
父组件通过slot属性指定替换子组件中的插槽:
<component-a>
<div slot="aaa">aaa</div>
<div slot="bbb">bbb</div>
</component-a>
子组件中定义插槽:
<div>
<slot name="aaa"></slot>
<slot name="bbb"></slot>
</div>
具名插槽v-slot
父组件通过slot属性指定替换子组件中的插槽
<component-a>
<template v-slot:header><div>Header content</div></template>
// 等同于 <h1 slot="header">Header content</h1>
<template v-slot:default><div>Default content</div></template>
// 等同于 <h1>Default content</h1>
<template v-slot:footer><div>Footer content</div></template>
// 等同于 <h1 slot="footer">Footer content</h1>
</component-a>
子组件中定义插槽:
<div>
<slot name="header"></slot>
<slot></slot>
<slot name="footer"></slot>
</div>
作用域插槽slot-scope
旧写法(2.6.0-):
<template slot="header" slot-scope="slotProps">
// 新写法可简写为<template #header="slotProps">
<div>Header content{{slotProps.user.firstName}}</div>
<template>
新写法(2.6.0+):
父组件通过slot属性指定替换子组件中的插槽:
<component-a>
<template v-slot:[zz]="slotProps">
// zz表示动态插槽名,slotProps为子组件中的数据参数对象
<div>Header content{{slotProps.user.firstName}}</div>
</template>
<template v-slot:default><div>Default content</div></template>
<template v-slot:footer><div>Footer content</div></template>
</component-a>
data:{ zz:'header' }
子组件中定义插槽:
<div>
<slot name="header" :user="user"></slot> // 通过自定义属性给父组件的插槽上传参
<slot><h1>无插槽时默认结构</h1></slot>
<slot name="footer"></slot>
</div>
data:{
user:{ firstName:'zheng',lastName:'xiaodong' }
}