Vue的介绍
- 作者:尤雨溪
- vue是一个渐进式的javascript框架
-
渐进式:越来越难学
-
vue是一个个人项目
-
Vue版本发布的时间
-
Vue 1.x 2014
-
Vue 2.x 2016 【 es6 vue 微信小程序 angular2.0 …
-
- MVC
-
MVC是一个软件的架构思维,分为三个部分
- M Model 数据
- V View 视图
- C Controller 控制器
-
- MVC衍生
-
mvc backbone 【 前端框架 】
-
mvp
-
mvvm Vue Angular.ts 【 Angular2.0】
-
ember
- MVVM
-
M Model 数据
-
V View 视图
-
VM ViewModel 视图模型
-
V的变化会反应到VM上,反之同理,也就是vm的改变也会影响V
Vue的源代码
- 行数: 11945 开发环境
- Vue的源代码是通过匿名函数【 自调用函数 】来进行封装
- 匿名函数好处
- 解决了命名冲突
- 规定了一个独立的作用域
- 安全性高
- xss 攻击脚本
- CRSF 攻击脚本
- 格式
//第一个括号表示定义一个匿名函数
//第二个括号表示调用这个函数
//参数: 第一个括号中的参数为 形式参数
//第二个括号中的参数为 实际参数
//this - 指的就是window对象
//factory - 工厂函数 返回值就是Vue构造函数
//el不能是body
//Vue是通过面向对象原型继承 + 工厂函数进行底层代码封装的
(function ( global,factory) {
})( this,function () {})
Vue学习的思路
- Vue有指令和组件系统两个大功能
- 通过js想操作DOM - > Vue也想操作DOM
- 问题: Vue中不建议像二阶段一样直接去操作DOM
- 解决: 方案: 指令
指令
数据展示
v-html 可解读XML标签
v-text
条件渲染
-
单分支 v-if
-
双分支
v-if
v-else 必走一条
-
多分支
v-if = “type === ‘条件1’”
v-else-if = “type ===‘条件2’”
v-else//其他条件
-
条件展示
v-show
-
v-if vs v-show的比较
-
v-if是真正的控制dom的存在与否,v-show 是控制dom的display:none属性
-
如果初始条件都为false,v-if会惰性渲染【 不渲染 】,但是v-show不管条件是什么都会渲染,所以v-show的初始渲染开销较高
-
如果我们要频繁的切换flag,那么我们使用谁? 我们使用 v-show , 反之,使用v-if
-
-
渲染数组
- v-for = “(item,index) in 数组名”
-
对象的渲染
- v-for = “(item,index) in 对象名”
-
JSON的渲染
- v-for = “(item,index) in JSON名”
-
特殊数据的渲染
- v-for = “item in 10”
-
特殊数据的渲染
-
嵌套
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title> 指令 </title> <style> .container{ margin: 20px; } </style> </head> <body> <div id="app"> <div class="container"> <h3> 数据展示 </h3> <p> {{ msg }} </p> <p v-html = "msg"></p> <p v-text = "msg"></p> <hr> <h3> 条件渲染 </h3> <h4> 条件渲染 - 单路分支 </h4> <p v-if = "flag"> 条件 - 单路分支 </p> <h4> 条件渲染 - 双路分支 </h4> <p v-if = "flag1"> 条件 - 双路 - 1 </p> <p v-else> 条件 - 双路 - 2 </p> <h4> 条件渲染 - 多路分支 </h4> <p v-if = " type === 'A'"> 条件 - A </p> <p v-else-if = "type === 'B'"> 条件 - B </p> <p v-else> 条件 - C </p> <hr> <h3> 条件展示 </h3> <p v-show = "flag2"> 条件 - 展示 </p> <hr> <h3> 列表渲染 </h3> <h4> 数组 </h4> <ul> <li v-for = " (item,index) in lists"> {{ item }} -- {{ index }} </li> </ul> <h4> 对象 </h4> <ul> <li v-for = " (value,key,index) in obj "> {{ value }} --- {{ key }} --- {{ index }} </li> </ul> <h4> json </h4> <ul> <li v-for = "(item,index) in json"> <p> 商品名称: {{ item.shopName }} -- {{ index }} -- {{ item.id }} </p> </li> </ul> <h4> 列表渲染特殊数据 </h4> <ul> <li v-for = "item in 10"> {{ item }} </li> </ul> <h4> 列表渲染嵌套 </h4> <ul> <li v-for = "item in banners"> <p> {{ item.name }} </p> <ul> <li v-for = "val in item.child"> {{ val.name }} </li> </ul> </li> </ul> </div> </div> </body> <script src="../../../lib/vue.js"></script> <script> new Vue({ el: '#app', data: { msg: '<div> hello Vue.js</div>', flag: false, flag1: true, type: 'A', flag2: false, lists: [1,2,3,4], obj: { id: 1, name: 'Gabriel Yan', age: 16 }, json: [ { id: 1, shopName: '商品一' }, { id: 2, shopName: '商品二' }, { id: 3, shopName: '商品三' } ], banners: [ { id: 1, name: 'banner1', child: [ { id: 1, name: 'banner1 - 1' } ] }, { id: 2, name: 'banner2', child: [ { id: 2, name: 'banner2 - 2' } ] }, { id: 3, name: 'banner3', child: [ { id: 3, name: 'banner3 - 3' } ] } ] } }) </script> </html>
-
单向绑定数据
v-bind:value= ‘msg’
<input type="text" :value = 'msg'>
样式绑定
:style="{ …}"
<p :style="{width:'100px',height:'100px',background:'yellow'}"></p>
<p :style="{width:w,height:h,background:bg}"></p>//w,h是data中的数据
-
样式绑定 - 数组写法
<p :style="[styhg,stycolor]"></p>
绑定类名
:class = “{…}”
<p :class="{size:true,color:true}"></p> <p :class="{size:flage,color:flage}"></p> <p :class="{size:flage,color:flage}"></p> <p :class="{[size]:flage,[color]:flage}"></p>
数组的写法
<p :class = [size,color]></p>
引申
<p :class = "[ size,flage && bg || color]"></p>
-
其他:可以绑定dom任意一个属性
<img :src="imgUrl" alt="">
双向绑定
-
v-model
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <script src="../vue.js"></script> <title>Document</title> </head> <body> <div class="app"> <h4>双向绑定</h4> <input type="text" v-model = 'msg'> </div> </body> <script> new Vue({ el:'.app', data:{ msg:'panda-pan' } }) </script> </html>
-
单向实现双向效果
-
补充:
-
input身上有哪些事件?
- focus
- blur
- change
- input
-
事件有几种绑定形式
-
js中绑定
var input = document.querySelector('input') input.oninput = function () {} DOM2级事件 事件监听
-
html结构中绑定
function load () {}
-
vue中事件绑定形式选择2
-
-
事件包含哪几个部分?
- 事件源
- 事件类型
- 事件处理程序
-
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <div id="app"> <input type="text" :value = 'val' @input = 'change'> </div> </body> <script src="../vue.js"></script> <script> new Vue({ el: '#app', data:{ val:'' }, methods:{ change:function(e){ this.val = e.target.value } } }) </script> </html>
-
事件
- 业务: 点击button按钮,弹出input的value
- 经验: 看到表单,想要得到它的value值,直接v-model
- vue事件传参
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
<input type="text" v-model = 'val'>
<button @click = 'fn($event,val)'>点击</button>
</div>
</body>
<script src="../vue.js"></script>
<script>
new Vue({
el: '#app',
data:{
val:''
},
methods:{
fn(e,val){
console.log(e);
console.log(val);
}
}
})
</script>
</html>
修饰符
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
.large{
width: 200px;
height: 200px;
background: red;
}
.middle{
width: 100px;
height: 100px;
background: blue;
}
.small{
width: 50px;
height: 50px;
background: purple;
}
</style>
</head>
<body>
<div id="app">
<div class="large" @click = "largeHandler">
<div class="middle" @click = "middleHandler">
<div class="small" @click = "smallHandler"></div>
</div>
</div>
</div>
</body>
<script src="../../lib/vue.js"></script>
<script>
/*
业务: 给每一个盒子都加一个事件
*/
new Vue({
el: '#app',
methods: { //方法: 里面存放的是: 事件处理程序
largeHandler ( e ) {
e.stopPropagation()
alert( 'large' )
},
middleHandler ( e ) {
alert( 'middle' )
e.stopPropagation()
},
smallHandler ( e ) {
alert( 'small' )
e.stopPropagation()
}
}
})
</script>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
.large{
width: 200px;
height: 200px;
background: red;
}
.middle{
width: 100px;
height: 100px;
background: blue;
}
.small{
width: 50px;
height: 50px;
background: purple;
}
</style>
</head>
<body>
<div id="app">
<div class="large" @click.stop = "largeHandler">
<div class="middle" @click.stop = "middleHandler">
<div class="small" @click.stop = "smallHandler"></div>
</div>
</div>
<hr>
<div class="large" @click.self = "largeHandler">
<div class="middle" @click.self = "middleHandler">
<div class="small" @click.self = "smallHandler"></div>
</div>
</div>
</div>
</body>
<script src="../../lib/vue.js"></script>
<script>
/*
业务: 给每一个盒子都加一个事件
*/
new Vue({
el: '#app',
methods: { //方法: 里面存放的是: 事件处理程序
largeHandler ( e ) {
alert( 'large' )
},
middleHandler ( e ) {
alert( 'middle' )
},
smallHandler ( e ) {
alert( 'small' )
}
}
})
</script>
</html>
按键修饰符
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
<input type="text" @keyup = "fn( val,$event )" v-model = 'val'>
</div>
</body>
<script src="../../lib/vue.js"></script>
<script>
/*
业务: 按回车弹出input框的value
键盘事件:
keyup
keydown
keypress
*/
new Vue({
el: '#app',
data: {
val: ''
},
methods: {
fn ( val,e ) {
if ( e.keyCode === 13 ) {
console.log( val )
}
}
}
})
</script>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
<input type="text" @keyup.13 = "fn( val )" v-model = 'val'>
<hr>
<input type="text" @keyup.enter = "fn( val )" v-model = 'val'>
<hr>
<input type="text" @keyup.p = "fn( val )" v-model = 'val'>
</div>
</body>
<script src="../../lib/vue.js"></script>
<script>
/*
业务: 按回车弹出input框的value
键盘事件:
keyup
keydown
keypress
*/
new Vue({
el: '#app',
data: {
val: ''
},
methods: {
fn ( val ) {
console.log( val )
}
}
})
</script>
</html>
模板语法
-
补充
-
数据类型有哪些?【 2种说法 】
-
第一种类型说法
初始数据类型: number string null undefined boolean
引用数据类型: object
-
第二种说法
基本数据类型L: number string boolean
复杂数据类型: object
特殊数据类型: null undefined
-
-
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
<p> number: {{ num }} </p>
<p> string: {{ str }} </p>
<p> boolean: {{ bool && 1 || 2 }}</p>
<p> null: {{ nul && 3 || 4 }}</p>
<p> undefined: {{ und && 5 || 6 }} </p>
<p> array: {{ arr[1] }}</p>
<p> object: {{ obj.name }}</p>
<!-- <p> function: {{ ( function() { console.log('fn')} )() }}</p> -->
</div>
</body>
<script src="../../lib/vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
num: 10,
str: 'Gabriel Yan',
bool: true,
nul: null,
und: undefined,
arr: [1,2,3],
obj: {
name: '老彭'
}
}
})
</script>
</html>
计算属性
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
{{ msg.split('').reverse().join('') }}
<hr>
<p> {{ newMsg }} </p>
</div>
</body>
<script src="../../lib/vue.js"></script>
<script>
/*
业务:将msg这个字符串 反向 输出
思路: 反向 reverse 数组
思考: V应该是用于数据展示,但是我们这么处理,发现V做了一部分逻辑判断,又违背了MVVM
解决: 计算属性
*/
new Vue({
el: '#app',
data: {
msg: 'I Love eat 葡萄 '
},
computed: {
//计算属性中存放的都是方法
newMsg () {
return this.msg.split('').reverse().join('')
}
}
})
</script>
</html>
案列1:用户名
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
<div>
姓: <input type="text" v-model = "firstName">
</div>
<hr>
<div>
名: <input type="text" v-model = "lastName">
</div>
<hr>
<div>
全名: <input type="text" v-model = "fullName">
</div>
</div>
</body>
<script src="../../lib/vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
firstName: '',
lastName: ''
},
computed: {
fullName () {
return this.firstName + this.lastName
}
}
})
</script>
</html>
案列2:用户名(改)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
<div>
姓: <input type="text" v-model = "firstName">
</div>
<hr>
<div>
名: <input type="text" v-model = "lastName">
</div>
<hr>
<div>
全名: <input type="text" v-model = "fullName">
</div>
</div>
</body>
<script src="../../lib/vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
firstName: '',
lastName: ''
},
computed: {
fullName: {
get () { //getter
return this.firstName + this.lastName
},
set ( val ) { //val就是当前绑定元素的value值
// val XXX
this.firstName = val.slice( 0,1 )
this.lastName = val.slice( 1 )
}
}
}
})
</script>
</html>
watch:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
<div>
姓: <input type="text" v-model = "firstName">
</div>
<hr>
<div>
名: <input type="text" v-model = "lastName">
</div>
<hr>
<div>
全名: <input type="text" v-model = "fullName">
</div>
</div>
</body>
<script src="../../person/vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
firstName: '',
lastName: '',
fullName: ''
},
watch: { // 侦听 谁? 谁 -> 指的是data中的数据
// watch中可以存放方法
firstName ( val ) {
// console.log('firstname改变了')
this.fullName = val + this.lastName
},
lastName ( val ) {
this.fullName = this.firstName + val
},
// fullName ( val ) {
// this.firstName = val.slice( 0,1 )
// this.lastName = val.slice( 1 )
// }
fullName: {
deep: true, //深度监听
handler (val) { // 处理程序
this.firstName = val.slice( 0,1 )
this.lastName = val.slice( 1 )
}
}
}
})
</script>
</html>