初识Vue
什么是vue
- 构建数据驱动的web应用开发框架;
- Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架;
- Vue 被设计为可以自底向上逐层应用;
- Vue 的核心库只关注视图层;
- 便于与第三方库或既有项目整合;
- Vue 不支持 IE8 及以下版本;
在之此之前先去安装vue.js的环境,可以去https://cn.vuejs.org/v2/guide/下载
在学习之前先来了解一下MVC,MVVM吧
1、MVC是后端分层开发的概念
M(model):主要处理数据(ajax/jsonp/数据解析)的传递,可以复用。
V(view):看作前端页面
C(control):控制层(串业务,事件驱动) 一般不复用
2、MVVM
MVVM是前端视图层的概念,分为了三部分,Model、View、VM(View Model)
Vue中,Vue实例相当于VM,其中的data相当于M,页面中显示的部分为V。
声明式渲染
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="./vue.js"></script>
</head>
<body>
<!-- 注:模板和new出来的实例必须在同一个作用域里,如:#app和vm在同一个作用域 -->
<!-- view层 -->
<!-- <div id="app">
<h3>111</h3>
<p>000</p>
</div> -->
<!-- vue渲染页面用mustache,即两个大括号{{}} -->
<div id="app">
<h3>{{this.title}}</h3> this在模板当中可以省略
<p>{{duanluo}}</p>
<span>{{message}}</span>
</div>
</body>
<script>
/* vm层 是new出来的vue实例 */
let vm = new Vue({ //配置选项
//key:value
//el:'选择器'
el:'#app',
data:{ //moduel M层
title:'标题', //vm.$data.title或vm.title都可以获得
message: 'Hello Vue!'
duanluo:'一个段落,一个段落,一个段落',
}
})
</script>
</html>
从上面看出数据和DOM都已经被建立了关联,所有的东西都是响应式的(如何看出是响应式的?可直接打开这个网页的控制台,然后输入vm.title = ‘123’,这样就可以直接在页面上看到title变化了,也就是V层变化了)
model不同的数据类型在view层的渲染
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="./vue.js"></script>
</head>
<body>
<!-- view层 -->
<div id="app">
<h3>model不同的数据类型在view层的渲染结果</h3>
<div>string:{{str}}</div>
<div>num转变为字符:{{num}}</div>
<div>bl转变为字符:{{bl}}</div>
<div>arr转变为字符:{{arr}}</div>
<div>json转变为字符:{{json}}</div>
<div>fn转变为字符:{{fn}}</div>
<div>fn2:{{fn()}}</div>
<div>un转变为空字符:{{un}}</div>
<div>fn转变为空字符:{{nu}}</div>
<div>str空字符不作为:/{{str2}}/</div>
</div>
</body>
<script>
/* vm层 是new出来的vue实例 */
let vm = new Vue({ //配置选项
//key:value
//el:'选择器'
el:'#app',
data:{ //moduel M层
title:'标题',
duanluo:'一个段落,一个段落,一个段落',
str:'你好',
num:123,
bl:true,
arr:['a','b','c'],
json:{aa:1,bb:2},
fn:function(){alert(1)},
un:undefined,
nu:null,
str2:''
}
})
</script>
</html>
view层的元素绑定
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="./vue.js"></script>
</head>
<body>
<div id="app">
<h3>数据绑定的形式(model放到view层去渲染)</h3>
<h4>mustach(innerHTML动态化)</h4>
<div>string:{{str}}</div>
<h4>指令绑定(innerHTML动态化,写法不依赖于mustach)</h4>
<div v-text="str"></div>
<h4>属性绑定(能让属性名或值动态化)</h4>
<!-- <img src="{{url}}" alt="" /> vue1.x -->
<img v-bind:src="url" alt="" />
<img :src="url" alt="" />
<h4>动态组件绑定(标签动态化,后面单独说)</h4>
</div>
<script>
let vm = new Vue({
el:'#app',
data:{
str:'picture1',
url:'https://cn.vuejs.org/images/vant.png'
}
})
</script>
</body>
</html>
view特殊情况
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="./vue.js"></script>
</head>
<body>
<div id="app">
<h3>转义</h3>
<div>{{strong}}</div>
<div v-text="strong"></div><hr />
<h3>非转义</h3>
<div v-html="strong"></div><hr />
<h3>按需渲染|列表渲染|列渲</h3>
<div>{{arr}}</div>
<ul>
<li v-for="val in arr">{{val}}</li><br />
<li v-for="val in this.arr">{{val}}</li>
</ul>
<h3>条件渲染 | 条渲</h3>
<div v-show="bl">box</div> <!-- 当布尔值为true时才显示出来 -->
</div>
</body>
<script>
let vm = new Vue({
el:'#app',
data:{
strong:'<strong>加粗</strong>',
arr:['aa','bb','cc'],
bl:false
}
})
</script>
</html>
事件
* 事件简写形式 v-on:click =》 @click
<button onclick="fn()">click</button> ---- 原生js
<button v-on:click="fn()">click</button> --- vue
<button @click="fn()">click</button> --- vue简写
* 属性的简写形式 v-bind:class =》 :class
<div class="test"></div> --- 原生,test就是一个固定的值
<div v-bind:class="test"></div> --- vue中,test可以是一个变量
<div :class="test"></div> --- vue简写形式
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="./vue.js"></script>
</head>
<body>
<div id="app">
<h3>事件</h3>
<div>{{count}}</div>
<!-- <input type="button" value="+" v-on:click="指定vue对的methods,即方法" /> -->
<!-- <input type="button" value="+" v-on:click="show" /> -->
<!-- 上面的v-on可以直接用@代替 -->
<input type="button" value="+" @click="showadd" />
<input type="button" value="-" @click="show"/>
<input type="button" value="事件对象" @click="show2"/>
<input type="button" value="this指向" @click="show3"/>
<input type="button" value="传参" @click="show4(12,'qwe',$event)"/>
<!-- $event代表实例身上的属性,代表当前触发的事件的事件对象 (事件排名分先后)-->
</div>
</body>
<script>
let mv = new Vue({
el:'#app',
data:{
count:1,
},
methods:{
// key:value,
// 方法:fn
showadd:function(){
// this == vm
this.count ++
},
show:function(){
// this == vm
this.count --
},
show2:function(ev){ //事件对象默认接收
console.log('事件对象',ev);
},
show3:function(){
console.log('this指向',this);
},
show4:function(arg1,arg2,ev){//传参数时,事件对象,需要手动传递 $event
console.log('参数',arg1,arg2);
console.log('事件对象',ev);
},
}
})
</script>
</html>
vue里的箭头函数
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="./vue.js"></script>
</head>
<body>
<div id="app">
<!-- 注意:vue提供的选项的值如果是函数时,不可用箭头函数
-->
<h3>事件</h3>
<!-- <input type="button" value="按钮" @click="show"/> -->
<input type="button" value="按钮" @click="show($event,'qwe',11)"/>
</div>
</body>
<script>
let vm = new Vue({
el:'#app',
data:{
arr:[1,2,3,4]
},
methods:{
// show:function(){},
// show:()=>{alert(1)},
// show:(ev)=>{console.log('事件对象',ev)}
// show:(ev,str,num)=>{console.log('事件对象',ev,str,num,this)} //this的指向指到了Windows
//上面的可简写为:
show(ev,str,num){
console.log('事件对象',ev,str,num,this)
this.arr.forEach(()=>{console.log('forEach',this)})
}
}
})
</script>
<script>
/*
var a = 1;
var b = 'qwe'
//对象表达式
var obj = {
a,b,
// c:function(){}
c(){}
}
console.log('obj',obj.a,obj.b);
obj.c()
*/
/*
class App{
constructor() {
this.xx=11;
}
show(){}
}
*/
</script>
</html>
三种绑定方式
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="./vue.js"></script>
</head>
<body>
<div id="app">
<!-- 单向绑定 -->
<!-- <input type="text" :value="iptName" /> -->
<h3>v-model双向绑定</h3>
<input type="text" v-model:value="iptName" />
{{iptName}}
<h3>手动实现双向绑定</h3>
<!-- 修改model层可以影响view层,但是修改view层不能影响model层 -->
<input type="text" :value="iptName2" @input="changeIptName2"/>
{{iptName2}}
</div>
</body>
<script>
let vm = new Vue({
el:'#app',
data:{
iptName:'hello',
iptName2:'world',
},
methods:{
changeIptName2(ev){
this.iptName2 = ev.target.value
}
}
})
</script>
</html>
列表渲染_条件渲染
1.v-for列渲
可以为数组索引指定别名 (或者用于对象的键):
(item, index) in items
(val, key) in object
(val, name, index) in object
当和 v-if 一起使用时,v-for 的优先级比 v-if 更高
跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一 key 属性 :key=‘item.id’
2.v-show条渲
根据表达式之真假值,切换元素的 display CSS 属性
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="./vue.js"></script>
</head>
<body>
<div id="app">
<h3>列表渲染</h3>
<ul>
<!-- <li v-for="val in arr">{{val}}</li> -->
<!-- 也可以把上面的in改成of,结果不变 -->
<li v-for="val of arr">{{val}}</li>
<!-- 可以拿到对应的索引 -->
<li v-for="(val,idx) of arr">{{val}}/{{idx}}</li>
</ul><hr />
<ul>
<li v-for="val in arr2">{{val}}</li><!-- 对象强行转成字符串 -->
</ul><hr />
<!-- 嵌套 -->
<ul>
<li v-for="item in arr2">
<span>{{item.name}}</span>
<span>{{item.age}}</span>
<span>{{item.id}}</span>
</li>
</ul><hr />
<!-- 嵌套时有子集 -->
<ul>
<li v-for="item in arr3">
<span>{{item.name}}</span>
<span>{{item.age}}</span>
<span>{{item.id}}</span>
<ul>
<li v-for="item2 in item.children">
<span>{{item2.name}}</span>
<span>{{item2.age}}</span>
<span>{{item2.id}}</span>
</li>
</ul>
</li>
</ul><hr />
<h3>条件的渲染条件要的是一个布尔值,不是会转换</h3>
<div v-show="bl">box1</div>
<div v-show="''">box2</div>
<div v-show="' '">box3</div> <!-- true -->
<div v-show="0">box4</div>
<div v-show="undefined">box5</div>
<div v-show="null">box6</div>
<div v-show="{}">box7</div> <!-- true -->
<div v-show="[]">box8</div> <!-- true -->
<hr />
<input type="button" value="按钮" @click="bl = !bl" />
<div style="width: 50px;height: 50px;background: red;" v-show="bl">盒子</div>
</div>
</body>
<script>
let vm = new Vue({
el:'#app',
data:{
arr:['aa','bb','cc'],
arr2:[
{id:1,name:'wang',age:18},
{id:2,name:'ting',age:19},
],
arr3:[
{id:1,name:'wang',age:18,children:[
{id:1,name:'John',age:20},
{id:2,name:'Lili',age:21},
]},
{id:2,name:'ting',age:19},
],
bl:'false',
item:'qwe'
},
methods:{
}
})
</script>
</html>
总结
标签上v-html,就会把它的值插入到该标签内部 v-text
v-if 条件判断 v-else-if v-else
v-show 条件判断
v-for 遍历循环使用
v-on 绑定事件
v-bind 绑定属性
不常用的
v-slot
v-pre
v-cloak
v-once