Vue2.0
一、Vue核心
1. Vue是什么?
一套用于构建用户界面 的渐进式 JavaScript框架
尤雨溪开发
2. Vue的特点
采用组件化 模式,提高代码复用率,且让代码更好维护
声明式 编码,让编码人员无需直接操作DOM,提高开发效率
使用虚拟DOM + 优秀的Diff算法 ,尽量复用DOM节点
3. Vue的安装
4. 初识Vue
< div id = " root" >
< h1> Hello,{{name}} h1>
div>
new Vue ( {
el: '#root' ,
data: {
name: '小帽'
}
} )
5. 模板语法
模板
html中包含了一个js语法代码,语法分为两种:
插值语法(双大括号表达式)
用于解析标签体内容
{{xxx}},xxx 会作为js表达式解析
指令语法(以v-开头)
解析标签属性、解析标签体内容、事件
v-bind:href = ‘xxxx’, xxxx 会作为js表达式被解析
< div id = " root" >
< h1> 插值语法 h1>
< h3> 你好,{{name}} h3>
< hr/>
< h1> 指令语法 h1>
< a v-bind: href= " school.url.toUpperCase()" > 点我去{{school.name}}学习1 a>
< a :href = " school.url" > 点我去{{school.name}}学习2 a>
div>
< script type= "text/javascript" >
Vue. config. productionTip = false
new Vue ( {
el: '#root' ,
data: {
name: 'jack' ,
school: {
name: '小帽学堂' ,
url: 'http://www.baidu.com' ,
}
}
} )
< / script>
6. 数据绑定
单向数据绑定
v-bind:value=“xxx” 或简写为 :value
数据只能从data流向页面
双向数据绑定
v-model:value=“xxx” 或简写为 v-model = “xxx”
数据不仅能从data流向页面,还能从页面流向data
只能应用在表单类元素 (输入类元素)上
7. el与data的两种写法
8. MVVM模型
M:模型(Model)对应data中的数据
V:视图(View)模板
VM:视图模型(ViewModel)Vue实例对象
9. 数据代理
< script type= "text/javascript" >
let number = 18
let person = {
name: '张三' ,
sex: '男' ,
}
Object. defineProperty ( person, 'age' , {
get ( ) {
console. log ( '有人读取age属性了' )
return number
} ,
set ( value) {
console. log ( '有人修改了age属性,且值是' , value)
number = value
}
} )
console. log ( person)
< / script>
< script type= "text/javascript" >
let obj = { x: 100 }
let obj2 = { y: 200 }
Object. defineProperty ( obj2, 'x' , {
get ( ) {
return obj. x
} ,
set ( value) {
obj. x = value
}
} )
< / script>
10. 事件处理
< body>
< div id = " root" >
< h2> 欢迎来到{{name}}学习 h2>
< button @click = " showInfo1" > 点我提示信息1(不传参) button>
< button @click = " showInfo2($event,66)" > 点我提示信息2(传参) button>
div>
body>
< script type = " text/javascript" >
Vue. config. productionTip = false
const vm = new Vue ( {
el: '#root' ,
data: {
name: '小帽学堂' ,
} ,
methods: {
showInfo1 ( event ) {
alert ( '帅哥你好!' )
} ,
showInfo2 ( event, number ) {
console. log ( event, number)
alert ( '美女你好!' )
}
}
} )
script>
Vue中的事件修饰符:
prevent:阻止默认事件(常用)
stop:阻止事件冒泡(常用)
once:事件只触发一次(常用)
例子:@click.prevent=“showInfo”
例子:@keyup.enter=“showInfo”
11. 计算属性
computed
要显示的数据不存在,要通过计算得来。
在 computed 对象中定义计算属性。
在页面中使用{{方法名}}来显示计算的结果。
< body>
< div id = " root" >
姓:< input type = " text" v-model = " firstName" > < br/> < br/>
名:< input type = " text" v-model = " lastName" > < br/> < br/>
全名:< span> {{fullName}} span> < br/> < br/>
div>
body>
< script type = " text/javascript" >
const vm = new Vue ( {
el: '#root' ,
data: {
firstName: '张' ,
lastName: '三' ,
} ,
computed: {
fullName ( ) {
console. log ( 'get被调用了' )
return this . firstName + '-' + this . lastName
}
}
} )
script>
12. 监视属性
< body>
< div id = " root" >
< h2> 今天天气很{{info}} h2>
< button @click = " changeWeather" > 切换天气 button>
div>
body>
< script type = " text/javascript" >
const vm = new Vue ( {
el: '#root' ,
data: {
isHot: true ,
} ,
computed: {
info ( ) {
return this . isHot ? '炎热' : '凉爽'
}
} ,
methods: {
changeWeather ( ) {
this . isHot = ! this . isHot
}
} ,
watch: {
isHot ( newValue, oldValue ) {
console. log ( 'isHot被修改了' , newValue, oldValue, this )
}
}
} )
script>
< body>
< div id = " root" >
姓:< input type = " text" v-model = " firstName" > < br/> < br/>
名:< input type = " text" v-model = " lastName" > < br/> < br/>
全名:< span> {{fullName}} span> < br/> < br/>
div>
body>
< script type = " text/javascript" >
const vm = new Vue ( {
el: '#root' ,
data: {
firstName: '张' ,
lastName: '三' ,
fullName: '张-三'
} ,
watch: {
firstName ( val ) {
setTimeout ( ( ) => {
console. log ( this )
this . fullName = val + '-' + this . lastName
} , 1000 ) ;
} ,
lastName ( val ) {
this . fullName = this . firstName + '-' + val
}
}
} )
script>
13. 绑定样式
< body>
< div id = " root" >
< div class = " basic" :class = " mood" @click = " changeMood" > {{name}} div> < br/> < br/>
< div class = " basic" :class = " classArr" > {{name}} div> < br/> < br/>
< div class = " basic" :class = " classObj" > {{name}} div> < br/> < br/>
< div class = " basic" :style = " styleObj" > {{name}} div> < br/> < br/>
< div class = " basic" :style = " styleArr" > {{name}} div>
div>
body>
< script type = " text/javascript" >
const vm = new Vue ( {
el: '#root' ,
data: {
name: '小帽学堂' ,
mood: 'normal' ,
classArr: [ 'lemon1' , 'lemon2' , 'lemon3' ] ,
classObj: {
lemon1: false ,
lemon2: false ,
} ,
styleObj: {
fontSize: '40px' ,
color: 'red' ,
} ,
styleObj2: {
backgroundColor: 'orange'
} ,
styleArr: [
{
fontSize: '40px' ,
color: 'blue' ,
} ,
{
backgroundColor: 'gray'
}
]
} ,
methods: {
changeMood ( ) {
const arr = [ 'happy' , 'sad' , 'normal' ]
const index = Math. floor ( Math. random ( ) * 3 )
this . mood = arr[ index]
}
} ,
} )
script>
14. 条件渲染
< body>
< div id = " root" >
< h2> 当前的n值是:{{n}} h2>
< button @click = " n++" > 点我n+1 button>
< template v-if = " n === 1" >
< h2> 你好 h2>
< h2> 小帽学堂 h2>
< h2> 北京 h2>
template>
div>
body>
< script type = " text/javascript" >
const vm = new Vue ( {
el: '#root' ,
data: {
name: '小帽' ,
n: 0
}
} )
script>
15. 列表渲染
< body>
< div id = " root" >
< h2> 人员列表(遍历数组) h2>
< ul>
< li v-for = " (p,index) in persons" :key = " index" >
{{p.name}}-{{p.age}}
li>
ul>
< h2> 汽车信息(遍历对象) h2>
< ul>
< li v-for = " (value,k) of car" :key = " k" >
{{k}}-{{value}}
li>
ul>
< h2> 测试遍历字符串(用得少) h2>
< ul>
< li v-for = " (char,index) of str" :key = " index" >
{{char}}-{{index}}
li>
ul>
< h2> 测试遍历指定次数(用得少) h2>
< ul>
< li v-for = " (number,index) of 5" :key = " index" >
{{index}}-{{number}}
li>
ul>
div>
body>
< script type = " text/javascript" >
new Vue ( {
el: '#root' ,
data: {
persons: [
{ id: '001' , name: '张三' , age: 18 } ,
{ id: '002' , name: '李四' , age: 19 } ,
{ id: '003' , name: '王五' , age: 20 }
] ,
car: {
name: '奥迪A8' ,
price: '70万' ,
color: '黑色'
} ,
str: 'hello'
}
} )
script>
< body>
< div id = " root" >
< h2> 人员列表 h2>
< input type = " text" placeholder = " 请输入名字" v-model = " keyWord" >
< ul>
< li v-for = " (p,index) of filPersons" :key = " index" >
{{p.name}}-{{p.age}}-{{p.sex}}
li>
ul>
div>
body>
< script type = " text/javascript" >
new Vue ( {
el: '#root' ,
data: {
keyWord: '' ,
persons: [
{ id: '001' , name: '马冬梅' , age: 19 , sex: '女' } ,
{ id: '002' , name: '周冬雨' , age: 20 , sex: '女' } ,
{ id: '003' , name: '周杰伦' , age: 21 , sex: '男' } ,
{ id: '004' , name: '温兆伦' , age: 22 , sex: '男' }
]
} ,
computed: {
filPersons ( ) {
return this . persons. filter ( ( p ) => {
return p. name. indexOf ( this . keyWord) !== - 1
} )
}
}
} )
script>
< body>
< div id = " root" >
< h2> 人员列表 h2>
< input type = " text" placeholder = " 请输入名字" v-model = " keyWord" >
< button @click = " sortType = 2" > 年龄升序 button>
< button @click = " sortType = 1" > 年龄降序 button>
< button @click = " sortType = 0" > 原顺序 button>
< ul>
< li v-for = " (p,index) of filPersons" :key = " p.id" >
{{p.name}}-{{p.age}}-{{p.sex}}
li>
ul>
div>
body>
< script type = " text/javascript" >
new Vue ( {
el: '#root' ,
data: {
keyWord: '' ,
sortType: 0 ,
persons: [
{ id: '001' , name: '马冬梅' , age: 30 , sex: '女' } ,
{ id: '002' , name: '周冬雨' , age: 31 , sex: '女' } ,
{ id: '003' , name: '周杰伦' , age: 18 , sex: '男' } ,
{ id: '004' , name: '温兆伦' , age: 19 , sex: '男' }
]
} ,
computed: {
filPersons ( ) {
const arr = this . persons. filter ( ( p ) => {
return p. name. indexOf ( this . keyWord) !== - 1
} )
if ( this . sortType) {
arr. sort ( ( p1, p2 ) => {
return this . sortType === 1 ? p2. age- p1. age : p1. age- p2. age
} )
}
return arr
}
}
} )
script>
< body>
< div id = " root" >
< h1> 学生信息 h1>
< button @click = " student.age++" > 年龄+1岁 button> < br/>
< button @click = " addSex" > 添加性别属性,默认值:男 button> < br/>
< button @click = " student.sex = ' 未知' " > 修改性别 button> < br/>
< button @click = " addFriend" > 在列表首位添加一个朋友 button> < br/>
< button @click = " updateFirstFriendName" > 修改第一个朋友的名字为:张三 button> < br/>
< button @click = " addHobby" > 添加一个爱好 button> < br/>
< button @click = " updateHobby" > 修改第一个爱好为:开车 button> < br/>
< button @click = " removeSmoke" > 过滤掉爱好中的抽烟 button> < br/>
< h3> 姓名:{{student.name}} h3>
< h3> 年龄:{{student.age}} h3>
< h3 v-if = " student.sex" > 性别:{{student.sex}} h3>
< h3> 爱好: h3>
< ul>
< li v-for = " (h,index) in student.hobby" :key = " index" >
{{h}}
li>
ul>
< h3> 朋友们: h3>
< ul>
< li v-for = " (f,index) in student.friends" :key = " index" >
{{f.name}}--{{f.age}}
li>
ul>
div>
body>
< script type = " text/javascript" >
const vm = new Vue ( {
el: '#root' ,
data: {
student: {
name: 'tom' ,
age: 18 ,
hobby: [ '抽烟' , '喝酒' , '烫头' ] ,
friends: [
{ name: 'jerry' , age: 35 } ,
{ name: 'tony' , age: 36 }
]
}
} ,
methods: {
addSex ( ) {
this . $set ( this . student, 'sex' , '男' )
} ,
addFriend ( ) {
this . student. friends. unshift ( { name: 'jack' , age: 70 } )
} ,
updateFirstFriendName ( ) {
this . student. friends[ 0 ] . name = '张三'
} ,
addHobby ( ) {
this . student. hobby. push ( '学习' )
} ,
updateHobby ( ) {
this . $set ( this . student. hobby, 0 , '开车' )
} ,
removeSmoke ( ) {
this . student. hobby = this . student. hobby. filter ( ( h ) => {
return h !== '抽烟'
} )
}
}
} )
script>
16. 收集表单数据
< body>
< div id = " root" >
< form @submit.prevent = " demo" >
账号:< input type = " text" v-model.trim = " userInfo.account" > < br/> < br/>
密码:< input type = " password" v-model = " userInfo.password" > < br/> < br/>
年龄:< input type = " number" v-model.number = " userInfo.age" > < br/> < br/>
性别:
男< input type = " radio" name = " sex" v-model = " userInfo.sex" value = " male" >
女< input type = " radio" name = " sex" v-model = " userInfo.sex" value = " female" > < br/> < br/>
爱好:
学习< input type = " checkbox" v-model = " userInfo.hobby" value = " study" >
打游戏< input type = " checkbox" v-model = " userInfo.hobby" value = " game" >
吃饭< input type = " checkbox" v-model = " userInfo.hobby" value = " eat" >
< br/> < br/>
所属校区
< select v-model = " userInfo.city" >
< option value = " " > 请选择校区 option>
< option value = " beijing" > 北京 option>
< option value = " shanghai" > 上海 option>
< option value = " shenzhen" > 深圳 option>
< option value = " wuhan" > 武汉 option>
select>
< br/> < br/>
其他信息:
< textarea v-model.lazy = " userInfo.other" > textarea> < br/> < br/>
< input type = " checkbox" v-model = " userInfo.agree" > 阅读并接受< a href = " http://www.baidu.com" > 《用户协议》 a>
< button> 提交 button>
form>
div>
body>
< script type = " text/javascript" >
new Vue ( {
el: '#root' ,
data: {
userInfo: {
account: '' ,
password: '' ,
age: 18 ,
sex: 'female' ,
hobby: [ ] ,
city: 'beijing' ,
other: '' ,
agree: ''
}
} ,
methods: {
demo ( ) {
console. log ( JSON . stringify ( this . userInfo) )
}
}
} )
script>
17. 内置指令
< body>
< div id = " root" >
< div> 你好,{{name}} div>
< div v-text = " name" > div>
< div v-text = " str" > div>
div>
body>
< script type = " text/javascript" >
new Vue ( {
el: '#root' ,
data: {
name: '小帽学堂' ,
str: '你好啊! '
}
} )
script>
< html>
< head>
< meta charset = " UTF-8" />
< title> v-cloak指令 title>
< style>
[v-cloak] {
display : none;
}
style>
head>
< body>
< div id = " root" >
< h2 v-cloak > {{name}} h2>
div>
< script type = " text/javascript" src = " http://localhost:8080/resource/5s/vue.js" > script>
body>
< script type = " text/javascript" >
console. log ( 1 )
Vue. config. productionTip = false
new Vue ( {
el: '#root' ,
data: {
name: '尚硅谷'
}
} )
script>
html>
< html>
< head>
< meta charset = " UTF-8" />
< title> v-once指令 title>
< script type = " text/javascript" src = " ../js/vue.js" > script>
head>
< body>
< div id = " root" >
< h2 v-once > 初始化的n值是:{{n}} h2>
< h2> 当前的n值是:{{n}} h2>
< button @click = " n++" > 点我n+1 button>
div>
body>
< script type = " text/javascript" >
Vue. config. productionTip = false
new Vue ( {
el: '#root' ,
data: {
n: 1
}
} )
script>
html>
< html>
< head>
< meta charset = " UTF-8" />
< title> v-pre指令 title>
< script type = " text/javascript" src = " ../js/vue.js" > script>
head>
< body>
< div id = " root" >
< h2 v-pre > Vue其实很简单 h2>
< h2 > 当前的n值是:{{n}} h2>
< button @click = " n++" > 点我n+1 button>
div>
body>
< script type = " text/javascript" >
Vue. config. productionTip = false
new Vue ( {
el: '#root' ,
data: {
n: 1
}
} )
script>
html>
18. 自定义指令
DOCTYPE html >
< html>
< head>
< meta charset = " UTF-8" />
< title> 自定义指令 title>
< script type = " text/javascript" src = " ../js/vue.js" > script>
head>
< body>
< div id = " root" >
< h2> {{name}} h2>
< h2> 当前的n值是:< span v-text = " n" > span> h2>
< h2> 放大10倍后的n值是:< span v-big = " n" > span> h2>
< button @click = " n++" > 点我n+1 button>
< hr/>
< input type = " text" v-fbind: value= " n" >
div>
body>
< script type = " text/javascript" >
Vue. config. productionTip = false
new Vue ( {
el: '#root' ,
data: {
name: '小帽学堂' ,
n: 1
} ,
directives: {
big ( element, binding ) {
console. log ( 'big' , this )
element. innerText = binding. value * 10
} ,
fbind: {
bind ( element, binding ) {
element. value = binding. value
} ,
inserted ( element, binding ) {
element. focus ( )
} ,
update ( element, binding ) {
element. value = binding. value
}
}
}
} )
script>
html>
19. 生命周期
DOCTYPE html >
< html>
< head>
< meta charset = " UTF-8" />
< title> 引出生命周期 title>
< script type = " text/javascript" src = " ../js/vue.js" > script>
head>
< body>
< div id = " root" >
< h2 v-if = " a" > 你好啊 h2>
< h2 :style = " {opacity}" > 欢迎学习Vue h2>
div>
body>
< script type = " text/javascript" >
Vue. config. productionTip = false
new Vue ( {
el: '#root' ,
data: {
a: false ,
opacity: 1
} ,
methods: {
} ,
mounted ( ) {
console. log ( 'mounted' , this )
setInterval ( ( ) => {
this . opacity -= 0.01
if ( this . opacity <= 0 ) this . opacity = 1
} , 16 )
} ,
} )
script>
html>
DOCTYPE html >
< html>
< head>
< meta charset = " UTF-8" />
< title> 引出生命周期 title>
< script type = " text/javascript" src = " ../js/vue.js" > script>
head>
< body>
< div id = " root" >
< h2 :style = " {opacity}" > 欢迎学习Vue h2>
< button @click = " opacity = 1" > 透明度设置为1 button>
< button @click = " stop" > 点我停止变换 button>
div>
body>
< script type = " text/javascript" >
Vue. config. productionTip = false
new Vue ( {
el: '#root' ,
data: {
opacity: 1
} ,
methods: {
stop ( ) {
this . $destroy ( )
}
} ,
mounted ( ) {
console. log ( 'mounted' , this )
this . timer = setInterval ( ( ) => {
console. log ( 'setInterval' )
this . opacity -= 0.01
if ( this . opacity <= 0 ) this . opacity = 1
} , 16 )
} ,
beforeDestroy ( ) {
clearInterval ( this . timer)
console. log ( 'vm即将驾鹤西游了' )
} ,
} )
script>
html>
二、Vue组件化编程
1. 模块与组件、模块化与组件化
模块
理解: 向外提供特定功能的 js 程序, 一般就是一个 js 文件
为什么: js 文件很多很复杂
作用: 复用 js, 简化 js 的编写, 提高 js 运行效率
组件
理解: 用来实现局部(特定)功能效果的代码集合(html/css/js/image……)
为什么: 一个界面的功能很复杂
作用: 复用编码, 简化项目编码, 提高运行效率
模块化
当应用中的 js 都以模块来编写的, 那这个应用就是一个模块化的应用。
组件化
当应用中的功能都是多组件的方式来编写的, 那这个应用就是一个组件化的应用
2. 非单文件组件
DOCTYPE html >
< html>
< head>
< meta charset = " UTF-8" />
< title> 基本使用 title>
< script type = " text/javascript" src = " ../js/vue.js" > script>
head>
< body>
< div id = " root" >
< hello> hello>
< hr>
< h1> {{msg}} h1>
< hr>
< school> school>
< hr>
< student> student>
div>
< div id = " root2" >
< hello> hello>
div>
body>
< script type = " text/javascript" >
Vue. config. productionTip = false
const school = Vue. extend ( {
template: `
学校名称:{{schoolName}}
学校地址:{{address}}
点我提示学校名
` ,
data ( ) {
return {
schoolName: '尚硅谷' ,
address: '北京昌平'
}
} ,
methods: {
showName ( ) {
alert ( this . schoolName)
}
} ,
} )
const student = Vue. extend ( {
template: `
学生姓名:{{studentName}}
学生年龄:{{age}}
` ,
data ( ) {
return {
studentName: '张三' ,
age: 18
}
}
} )
const hello = Vue. extend ( {
template: `
你好啊!{{name}}
` ,
data ( ) {
return {
name: 'Tom'
}
}
} )
Vue. component ( 'hello' , hello)
new Vue ( {
el: '#root' ,
data: {
msg: '你好啊!'
} ,
components: {
school,
student
}
} )
new Vue ( {
el: '#root2' ,
} )
script>
html>
DOCTYPE html >
< html>
< head>
< meta charset = " UTF-8" />
< title> 几个注意点 title>
< script type = " text/javascript" src = " ../js/vue.js" > script>
head>
< body>
< div id = " root" >
< h1> {{msg}} h1>
< school> school>
div>
body>
< script type = " text/javascript" >
Vue. config. productionTip = false
const s = Vue. extend ( {
name: 'atguigu' ,
template: `
学校名称:{{name}}
学校地址:{{address}}
` ,
data ( ) {
return {
name: '尚硅谷' ,
address: '北京'
}
}
} )
new Vue ( {
el: '#root' ,
data: {
msg: '欢迎学习Vue!'
} ,
components: {
school: s
}
} )
script>
html>
3. 单文件组件
一个文件中只包含有1个组件。
一个.vue 文件的组成(3 个部分)
基本使用