MVVM设计思想
- M(model)
- V(view)
- VM(View-Model)
Vue生命周期
- 挂载(初始化相关属性)
- beforeCreate->在实力初始化之后,数据观测和配置之前被调用
- created->在实力创建完成后被立即调用
- beforeMount->在挂载开始之前被调用
- mounted->被新创建的vm.$el替换,并挂载到实力上之后调用钩子
- 更新(元素或组件的变更操作)
- beforeUpdate->数据更新时调用,发生在虚拟DOM打补丁之前(调用后台接口向模板中填充数据)
- updated->由于数据更改导致的虚拟DOM重新渲染和打补丁,在这之后会调用该狗子
- 销毁(销毁相关属性)
- beforeDestroy->实例销毁之前调用
- destroyed->实例销毁后调用
数据交互方式:
视图层->监听dom->数据层
数据层->根据数据绑定->视图层
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YYIQxm7Z-1596001043673)(/Users/limboaaa/Library/Application Support/typora-user-images/截屏2020-07-26 上午9.30.20.png)]
Vue->helloWorld
<div>
{
{msg}}
</div>
new Vue({
el:'',
data:{
msg:'1'
}
})
el:元素的挂载位置
data:模型数据
{
{}}:差值表达式->将数据填充到HTML标签中,支持基本的计算操作。
Vue 指令
自定义的属性:在标签上定义的data-xxxx/abc = ’ ';
v-cloak 指令
作用:解决差值表达式闪动问题
1.提供样式
[v-cloak]{
display:none;
}
2.在差值表达式所在的标签中添加v-cloak
2.在差值表达式所在的标签中添加v-cloak
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EkZPV8XF-1596001043675)(/Users/limboaaa/Desktop/截屏2020-07-26 上午8.54.22.png)]
v-text 指令
描述:向页面中插入一个纯文本
v-html 指令
描述:填充HTML片段
- 存在安全问题
- 本网站内部数据可以使用,来自第三方的数据不可用
v-pre 指令
**描述:**显示原始信息,跳过编译过程
v-once 指令
**描述:**只编译一次,显示内容后不再具有数据响应式功能
应用场景:显示的信息后续不必再修改,可以使用v-once,可以提高性能。
<div v-once>{
{msg}}</div>
v-model 指令(双向数据绑定)
<input type="text" v-model= 'msg'>
v-model的本质,就是v-bind:value = ‘’,然后Input监听事件,将input的内容复制给该属性;
<input type="text" v-model= 'msg' @input = 'msg = $event.target.value'>
事件绑定
v-on指令
完全体:
<button v-on:click='num++'>点击</button>
简写:
<button @click='num++'>点击</button>
.stop 阻止冒泡
<div id="app">
{
{num}}
<div @click = 'handle'>
<button @click.stop='handle1'>点击1</button>
</div>
</div>
.prevent 阻止默认行为
<a href="https://www.baidu.com" @click.prevent='handle'>跳转至百度</a>
键盘:enter事件/ delete事件
用户名:<input type="text" v-model='name' @keyup.delete = 'delAll'>
密码:<input type="text" v-model='pwd' @keyup.enter = 'submit'>
自定义按键修饰符
全局变量:
config.keyCodes对象
Vue.config.keyCodes.xx = keynum;
使用:
<input type="text" v-model='pwd' @keyup.xx = 'handle'>
xx:别名
keynum:->可使用event.keyCode 获取对应键位的值
属性绑定
v-bind指令
完全体:
<a v-bind:href= 'url'></a>
简写形式:
<a :href= 'url'></a>
样式绑定
默认的class如何处理呢?->保留
数组可以结合对象一起使用
<div v-bind:class="[activeClass,errorClass,{test:isTest}]"></div>
使用:
<Style>
.active {
border: 1px solid red;
width: 100px;
height: 100px;
}
.error{
background-color: yellow;
}
</Style>
// 对象语法
<div v-bind:class="{active:isActive,error:isError}"></div>
// 数组语法
<div v-bind:class="[activeClass,errorClass]"></div>
// 对象简化操作语法
<div v-bind:class="objClasses"></div>
// 数组简化操作语法
<div v-bind:class="arrClasses"></div>
// 内联Style
<div v-bind:style="{
border:borderStyle,width:widthStyle,height:heightStyle}"></div>
// 简化内联Style
<div v-bind:style = 'objStyle'></div>
data() {
return {
/*对象语法 开始**/
isActive:true,
isError:false
/*对象语法 结束**/
-----------------------------------------------------
/*对象简化操作 开始**/
objClasses:{
active:true,
error:true
}
/*对象简化操作 结束**/
-----------------------------------------------------
/*数组语法 开始**/
activeClass:'active',
errorClass:'error'
/*数组语法 结束**/
-----------------------------------------------------
/*数组简化操作 开始**/
arrClasses:['active','error']
/*数组简化操作 结束**/
-----------------------------------------------------
/*内联样式 开始**/
borderStyle:'1px solid blue',
widthStyle:100px,
heightStyle:200px
/*内联样式 结束**/
-----------------------------------------------------
/*简化内联样式 开始**/
objStyle{
border:'1px solid blue',
width:100px,
height:200px
}
/*简化内联样式 结束**/
}
分支结构
- v-if
- v-else
- V-else-if
- v-show
v-if与v-show的区别
- V-if 控制元素是否渲染到页面
- V-show 控制元素是否显示(display:none/’ ')
循环结构
V-for
<ul>
<!-- 遍历数组 -->
<li v-for = 'item in user'>{
{item}}</li>
<!-- 可获取数组下标 -->
<li v-for = '(item,index) in user'>{
{item}}{
{index}}</li>
<!-- 数组对象遍历方式 -->
<li v-for = 'item in user'>{
{item.eName}}------{
{item.cName}}</li>
<!-- key的作用:帮助vue区分不同元素,从而提高性能 -->
<!-- :key -> bind:key; item.id-> 该对象的id(唯一) -->
<li :key = 'item.id' v-for = '(item,index) in user'>{
{item}}</li>
</ul>
data() {
return {
//数组
fruits:['apple','orange','banana']
// 数组对象
user:[{eName:'jack',
cName:"杰克"
},{
eName:'john',
cName:'路西'
},{
eName:'john',
cName:'约翰'
}]
}
}
# item:自定义变量,迭代的元素。
分支循环结构
v-for 遍历对象
<li v-for = '(value,key,index) in obj'></li>
v-for 结合v-if
<li v-if= ’value||key||index‘ v-for = '(value,key,index) in obj'></li>
表单域修饰符
- number:转换为数值
- Trim:去掉开始和结尾的空格
- lazy:将input时间切换为change事件
<input v-model.number = 'num'>
<input v-model.trim = 'info'>
// 输入框失去焦点触发,使用场景:注册用户名,会检测是否已经存在,需要获取该输入框数据
<input v-model.lazy = 'info'>
自定义指令
// 全局指令
Vue.directive('指令名'{
inserted:function(el){
// 获取元素的焦点
el.指令名()
}
})
// 局部指令
directives:{
指令名称:{
insered:function(el){
el.指令名称
}
}
}
// 使用方式
<input v-指令名>
计算属性
将复杂的计算逻辑抽取出来,使模板内容更加简洁。
计算属性与方法的区别?
- 计算属性是基于他们的依赖(data中的数据)进行缓存的(相同的逻辑只执行一次,并将执行的结果缓存)
- 方法不存在缓存
<div id="app">
{
{msg}}
{
{reverseString}}
<input type = 'text' v-model = 'msg'>
</div>
computed: {
reverseString:function(){
// 有返回值 需要return
return this.msg.split('').reverse().join('')
}
}
侦听器
描述:数据变化会触发侦听器锁绑定的方法
使用场景:数据变化时执行异步或开销较大的操作
var vm = new Vue({
el: '#app',
data() {
return {
firstName:'张',
lastName:'桂源',
fullName:'张桂源',
}
},
// 侦听器
watch: {
// 侦听的属性名与data中的属性名一致
// val:变化后的数据
firstName:function(val){
this.fullName = val + ' ' + this.lastName
},
lastName:function(val){
this.fullName = this.firstName + ' ' + val
}
},
})
过滤器
作用:格式化数据,比如讲字符串格式化为首字母大写,将日期转化为指定格式。
// 创建一个全局的过滤器
Vue.filter('filter1',function(val){
return val.charAt(0).toUpperCase()+val.slice(1)
})
// 使用方式
{
{msg | filter1}}
// 可以多个条件
{
{msg | filter1 | filter2}}
// 可以对绑定的数据进行过滤
<div v-bind:id = 'id | filter'></div>
// 局部filter
filters:{
filter1:function(){
},
filter2:function(){
}
}
// 时间格式化
{
{date | dateFormat('yyyy-MM-dd')}}
// 第二个形参为传递的参数
Vue.filter('dateFormat',function(value,arg){
// 时间转换格式
})
变异方法(修改原有数据)
- push()
- pop()
- shift()
- unshift()
- splice()
- sort()
- reverse()
替换数组(生成新的数组)
filter()、concat()、slice() 不会改变原数组,都返回一个心的数组
vm.list[1] = 'lemon' // 通过这种下表修改属性值,不具备响应式
Vue.set(vm.list,index,'lemon') // 具备响应式
vm.$set(vm.list,index,'lenmon') // 具备响应式
// 对象
vm.$set(vm.info,'gender','female');// 具备响应式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<script type="text/javascript" src="./js/vue.js"></script>
<!-- 导入路由js -->
<script type="text/javascript" src="./js/vue-router.js"></script>
<Style>
.active {
border: 1px solid red;
width: 100px;
height: 100px;
}
.error {
background-color: yellow;
}
</Style>
<body>
<div id="app">
<div>
编号:<input class="form-control" type="text" v-model='id' :disabled="flag">
书名:<input class="form-control" type="text" v-model='name'>
<span>{
{total}}</span>
<button @click='handle' :disabled='butFlag'>添加</button>
</div>
<table>
<tr :key='item.id' v-for='(item,index) in books'>
<td>{
{item.id}}</td>
<td>{
{item.name}}</td>
<td>{
{item.now}}</td>
<td>
<a href="" @click.prevent='edit(item.id)'>修改</a>
<span @click.prevent>|</span>
<a href="" @click.prevent='del(item.id)'>删除</a>
</td>
</tr>
</table>
</div>
</body>
<script>
// 第二个形参为传递的参数
Vue.filter('dateFormat', function (value, arg) {
// 时间转换格式
})
var vm = new Vue({
el: '#app',
data: {
id: '',
name: '',
flag: false,
butFlag: false,
books: [
]
},
computed: {
total: function () {
return this