模板
- 引入Vue.js
- 创建Vue对象
el : 指定根element(选择器)
data : 初始化数据(页面可以访问) - 双向数据绑定 : v-model
- 显示数据 : {{xxx}}
- 理解vue的mvvm实现
<!--模板-->
<div id="test">
<input type="text" v-model="msg"><br><!--指令-->
<input type="text" v-model="msg"><!--指令-->
<p>hello {{msg}}</p><!--大括号表达式-->
</div>
<script type="text/javascript" src="../js/vue.js"></script>
<script type="text/javascript">
const vm = new Vue({ // 配置对象 options
// 配置选项(option)
el: '#test', // element: 指定用vue来管理页面中的哪个标签区域
data: {
msg: 'atguigu'
}
})
</script>
模板语法
- 模板的理解:
动态的html页面
包含了一些JS语法代码
大括号表达式
指令(以v-开头的自定义标签属性) - 双大括号表达式
语法: {{exp}} 或 {{{exp}}}
功能: 向页面输出数据
可以调用对象的方法 - 指令一: 强制数据绑定
功能: 指定变化的属性值
完整写法:
v-bind:xxx=‘yyy’ //yyy会作为表达式解析执行
简洁写法:
:xxx=‘yyy’ - 指令二: 绑定事件监听
功能: 绑定指定事件名的回调函数
完整写法:
v-on:click=‘xxx’
简洁写法:
@click=‘xxx’
<div id="app">
<h2>1. 双大括号表达式</h2>
<p>{{content}}</p>
<p>{{content.toUpperCase()}}</p>
<h2>2. 指令一: 强制数据绑定</h2>
<a href="url">访问指定站点</a><br>
<a v-bind:href="url">访问指定站点2</a><br>
<a :href="url">访问指定站点2</a><br>
<h2>3. 指令二: 绑定事件监听</h2>
<button v-on:click="test">点我</button>
<button @click="test">点我</button>
</div>
<script type="text/javascript" src="../js/vue.js"></script>
<script type="text/javascript">
new Vue({
el: '#app',
data: {
content: 'NBA I Love This Game',
url: 'http://www.atguigu.com'
},
methods: {
test () {
alert('好啊!!!')
}
}
})
</script>
计算属性和监视
- 计算属性
在computed
属性对象中定义计算属性的方法
在页面中使用{{方法名}}来显示计算的结果 - 监视属性:
通过通过vm对象的$watch()
或watch
配置来监视指定的属性
当属性变化时, 回调函数自动调用, 在函数内部进行计算 - 计算属性高级:
通过getter/setter实现对属性数据的显示和监视
计算属性存在缓存, 多次读取只执行一次getter计算
<div id='app'>
姓:<input type="text" placeholder="fistname" v-model="fistname"><br>
名:<input type="text" placeholder="lastname" v-model="lastname"><br>
姓名1(单向):<input type="text" placeholder="Full name1" v-model="fullname1"><br>
姓名2(单向):<input type="text" placeholder="Full name2" v-model="fullname2"><br>
姓名3(双向):<input type="text" placeholder="Full name3" v-model="fullname3"><br>
</div>
<script>
let vm = new Vue({
el: '#app',
data: {
fistname: 'a',
lastname: 'b',
fullname2: 'a b'
},
// 计算属性配置: 值为对象
computed: {
fullname1() {
return this.fistname + " " + this.lastname;
},
fullname3: {
// 当获取当前属性值时自动调用, 将返回值(根据相关的其它属性数据)作为属性值
get() { // 属性的get()
return this.fistname + " " + this.lastname;
},
// 当属性值发生了改变时自动调用, 监视当前属性值变化, 同步更新相关的其它属性值
set(value) {// fullName3的最新value值
// 更新firstName和lastName
const names = value.split(' ')
this.fistname = names[0]
this.lastname = names[1]
}
}
},
watch: {
// 配置监视firstName
fistname: function (value) {// 相当于属性的set
// 更新fullName2
this.fullname2 = value + " " + this.lastname;
},
},
methods: {
},
});
// 监视lastName
vm.$watch('lastname', function (value) {
// 更新fullName2
this.fullname2 = this.fistname + " " + value;
})
</script>
class与style绑定
- 理解
在应用界面中, 某个(些)元素的样式是变化的
class/style绑定就是专门用来实现动态样式效果的技术 - class绑定: :class=‘xxx’
xxx是字符串
xxx是对象
xxx是数组 - style绑定
:style="{color:mycolor,fontSize: mysize}"
其中mycolor/mysize是data属性
<style>
.pas {
width: 100px;
height: 50px;
background-color: aqua;
}
.pa {
width: 50px;
height: 20px;
background-color: blueviolet;
}
ul {
margin: 0;
padding: 0;
list-style: none;
}
.a {
background: rgb(153, 67, 67);
}
.b {
background: #8a5ec5;
}
.c {
font-size: 50px;
}
</style>
<!-- <script src="/JS/vuetext.js"></script> -->
</head>
<body>
<div id='app'>
<!-- :class='字符' -->
<p :class="myclass">lllllllllll</p>
<!-- :class='对象' -->
<p :class="{pas:isA,pa:isB}"> jjjssssssss</p>
<!-- :class='数组' -->
<p :class="['a','c']"> 4444444</p>
<button @click="update">aa</button>
<!-- style绑定 -->
<p :style="{color:mycolor,fontSize: mysize}">kkkkkkkkkkk</p>
</div>
<script>
let vm = new Vue({
el: '#app',
data: {
isA: true,
isB: false,
myclass: 'a',
mycolor: 'red',
mysize: '20px'
},
methods: {
update() {
//:class='字符'
this.myclass = 'b'
//:class='对象'
this.isA = !this.isA;
this.isB = !this.isB;
//style绑定
this.mycolor = 'yellow';
this.mysize = '10px'
},
},
});
</script>
</body>
条件渲染
v-if
<div id='app'>
{{name}} {{age}}
<div v-if="vip">
<div id="pas">用户类型:VIP</div>
</div>
<div v-else="vip">
<div id="pas">用户类型:普通用户</div>
</div>
</div>
<script>
let app = new Vue({
el: '#app',
data: {
vip: false,
name: '刘峰',
age: 19,
},
});
</script>
v-show
<div id='app'>
{{name}} {{age}}
<input type="text" v-show="name" v-model="name">
<div v-show="vip">
<div id="pas">用户类型:VIP</div>
</div>
<button @click='qiehuan' id='btn'>切换</button>
</div>
<script>
let app = new Vue({
el: '#app',
data: {
vip: false,
name: '刘峰',
age: 19,
},
methods: {
qiehuan() {
app.vip = !app.vip;
}
},
});
</script>
列表渲染
v-for
<div id='app'>
<ul>
<li v-for="item in username">
{{item.user}}
</li>
<li v-for="item in te">
姓名:{{item.username}}
年龄:{{item.age}}
学校:{{item.school}}
</li>
</ul>
</div>
<script>
let app = new Vue({
el: '#app',
data: {
username: [
{ user: 'ss' },
{ user: 'aa' },
{ user: 'ee' },
{ user: 'ww' }
],
te: [{
username: 'ss',
age: 16,
school: '加州大学'
},
{
username: 'aa',
age: 16,
school: '杭州大学'
},
{
username: 'ee',
age: 16,
school: '北京大学'
},
{
username: 'ww',
age: 16,
school: '欧洲大学'
}]
},
});
</script>
v-for加增删改
<div id='app'>
<ul>
<li v-for="(item, index) in persons" :key="index">
姓名:{{item.name}} -------
年龄:{{item.age}} -------
<button @click="deleteP">删除</button>
<button @click="update(index,{name:'风铃',age:33})">更新</button>
<button @click="add({name:'风铃',age:33})">添加</button>
</li>
</ul>
</div>
<script>
let vm = new Vue({
el: '#app',
data: {
persons: [
{ name: '凤千羽', age: 25 },
{ name: '零', age: 22 }
],
},
methods: {
deleteP(index) {
this.persons.splice(index, 1)
},
update(index, newP) {
this.persons.splice(index, 1, newP);
},
add(newP) {
this.persons.push(newP);
}
},
});
</script>
过滤与排序
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="/JS/vue.js"></script>
</head>
<style>
ul {
margin: 0;
padding: 0;
list-style: none;
}
</style>
<body>
<div id="app">
<input type="text" v-model="Serach">
<ul>
<li v-for="(item, index) in items" :key="index">
{{item.name}}
{{item.age}}
</li>
</ul>
<div>
<button @click="setOrderType(2)">年龄升序</button>
<button @click="setOrderType(1)">年龄降序</button>
<button @click="setOrderType(0)">原本顺序</button>
</div>
</div>
<script>
let vm = new Vue({
el: '#app',
data: {
Serach: '',
ordertype: 0,// 0代表不排序, 1代表降序, 2代表升序
persons: [
{ name: 'Tom', age: 18 },
{ name: 'Jack', age: 17 },
{ name: 'Bob', age: 19 },
{ name: 'Mary', age: 16 }
]
},
computed: {
items() {
//const {Serach, persons,ordertype} = this; //结构
//不解构
const persons=this.persons;
const Serach=this.Serach;
const ordertype=this.ordertype;
let Pfilters;
Pfilters = persons.filter(p => p.name.indexOf(Serach) != -1)
if (ordertype!=0) {
Pfilters.sort(function (p1, p2) {
if (ordertype === 2) {
return p2.age - p1.age;
} else {
return p1.age - p2.age;
}
})
}
return Pfilters
}
},
methods: {
setOrderType(ordertype){
this.ordertype=ordertype
}
},
}
);
</script>
</body>
</html>
事件处理
- 绑定监听:
v-on:xxx=“fun”
@xxx=“fun”
@xxx=“fun(参数)”
默认事件形参: event
隐含属性对象: $event - 事件修饰符:
.prevent : 阻止事件的默认行为 event.preventDefault()
.stop : 停止事件冒泡 event.stopPropagation() - 按键修饰符
用@keyup来绑定事件监听
.keycode : 操作的是某个keycode值的健
.enter : 操作的是enter键
<div id="app">
<div>
<!-- 绑定监听 -->
<button @click="test1">test1</button>
<button @click="test2(123)">test2</button>
<button @click="test3(123,$event)">test3</button>
<!-- 事件修饰符 -->
<div style="width: 200px;height: 200px;background: red;" @click="test5">
<div style="width: 100px;height: 100px;background: rgb(44, 173, 130);" @click.stop="test6"></div>
</div>
<a href="https://www.baidu.com" @click.prevent="test7">baiduyixia</a>
<!-- 按键修饰符 -->
<input type="text" @keyup.13="test8">
</div>
</div>
<script>
let vm = new Vue({
el: '#app',
data: {
},
computed: {
},
methods: {
test1(event) {
alert(event.target.innerHTML);
},
test2(number) {
alert(number)
},
test3(number, event) {
alert(number + event.target.innerHTML)
},
test5() {
alert('out')
},
test6() {
alert('inner')
},
test7() {
alert('点击了超链接')
},
test8(event) {
alert(event.keyCode + event.target.value)
}
},
}
);
</script>
表单输入绑定
- 使用v-model(双向数据绑定)自动收集数据
text/textarea
checkbox
radio
select
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="/JS/vue.js"></script>
</head>
<style>
ul {
margin: 0;
padding: 0;
list-style: none;
}
</style>
<body>
<div id="app">
<form action="javascript:;" method="GET" @submit.prevent="submit">
姓名<input type="text" name="name" id="" value="" v-model="name"><br>
密码<input type="password" v-model="pwd"><br>
男<input type="radio" value="男" name="radio" v-model="sex">
女<input type="radio" value="女" name="radio" v-model="sex"><br>
体育竞技<input type="checkbox" value="体育竞技" v-model="likes">
电子竞技<input type="checkbox" value="电子竞技" v-model="likes">
音乐鉴赏<input type="checkbox" value="音乐鉴赏" v-model="likes"><br>
城市<select v-model="cityId"><br>
<option :value="ctiy.id" v-for="(ctiy, index) in ctiys" :key="ctiy.id">
{{ctiy.name}}
</option>
</select><br>
个人简介<textarea name="" id="" cols="30" rows="10" v-model="text"></textarea>
<input type="submit" value="提交">
</form>
</div>
<script>
let vm = new Vue({
el: '#app',
data: {
name: '',
pwd: '',
sex: '女',
likes: [],
ctiys: [{ id: 1, name: '北京' }, { id: 2, name: '上海' }, { id: 3, name: '苏州' }],
cityId: 1,
text: '',
},
methods: {
submit() {
alert("您提交的数据:" + this.name + '\n' + this.pwd + '\n' + this.sex + '\n' + this.likes + '\n' + this.cityId + '\n' + this.text)
}
},
});
</script>
</body>
</html>
Vue实例_生命周期
- vue对象的生命周期
1). 初始化显示- beforeCreate()
- created()
- beforeMount()
- mounted()
2). 更新状态 - beforeUpdate()
- updated()
3). 销毁vue实例: vm.$destory() - beforeDestory()
- destoryed()
- 常用的生命周期方法
mounted(): 发送ajax请求, 启动定时器等异步任务
beforeDestory(): 做收尾工作, 如: 清除定时器
<body>
<div id="app">
<button type="button" @click="stopVue">stopVue</button>
<p v-show="isShow">aaaaaa</p>
</div>
<script type="text/javascript">
let vm = new Vue({
el: '#app',
data: {
isShow: true,
},
mounted() {
this.intervalId = setInterval(() => {
console.log('-------------------')
this.isShow = !this.isShow
}, 1000)
},
beforeDestroy() {
clearInterval(this.intervalId)
},
methods: {
stopVue() {
this.$destroy()
}
}
});
</script>
</body>
过渡&动画
- vue动画的理解
操作css的trasition或animation
vue会给目标元素添加/移除特定的class - 基本过渡动画的编码
1). 在目标元素外包裹
2). 定义class样式
1>. 指定过渡样式: transition
2>. 指定隐藏时的样式: opacity/其它 - 过渡的类名
xxx-enter-active: 指定显示的transition
xxx-leave-active: 指定隐藏的transition
xxx-enter: 指定隐藏时的样式
指定过渡样式
.xxx-enter-active, .xxx-leave-active {
transition: opacity 1s
}
指定隐藏时的样式
.xxx-enter, .xxx-leave-to {
opacity: 0;
}
例子
<head>
<meta charset="utf-8" />
<title></title>
<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
<style type="text/css">
/*指定过渡样式*/
.move-enter-active,
.move-leave-active {
transition: all 1s
}
/*指定隐藏时的样式*/
.move-enter,
.move-leave-to {
opacity: 0;
transform: translateX(1.25rem);
}
</style>
</head>
<body>
<div id="app">
<button type="button" @click="stopVue">stopVue</button>
<transition name="move">
<p v-if="isShow">aaaaaa</p>
</transition>
</div>
<script type="text/javascript">
let vm = new Vue({
el: '#app',
data: {
isShow: true,
},
methods: {
stopVue() {
this.isShow = !this.isShow
}
}
});
</script>
</body>
过滤器
- 理解过滤器
功能: 对要显示的数据进行特定格式化后再显示
注意: 并没有改变原本的数据, 可是产生新的对应的数据 - 编码
1). 定义过滤器
Vue.filter(filterName, function(value[,arg1,arg2,…]){
// 进行一定的数据处理
return newValue
})
2). 使用过滤器{{myData | filterName}}{{myData | filterName(arg)}}
对当前时间进行指定格式显示
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="/JS/vue.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/moment.js/2.27.0/moment.js"></script>
</head>
<body>
<div id="app">
{{time | datestr}} <br>
{{time | datestr('YYYY-MM-DD')}} <br>
{{time | datestr('HH:mm:ss')}} <br>
</div>
<script>
Vue.filter('datestr', function (value, format) {
return moment(value).format(format || 'YYYY MM DD h:mm:ss a');
});
let vm = new Vue({
el: '#app',
data: {
time: new Date()
},
})
</script>
</body>
指令_内置指令
常用内置指令
v:text : 更新元素的 textContent
v-html : 更新元素的 innerHTML
v-if : 如果为true, 当前标签才会输出到页面
v-else: 如果为false, 当前标签才会输出到页面
v-show : 通过控制display样式来控制显示/隐藏
v-for : 遍历数组/对象
v-on : 绑定事件监听, 一般简写为@
v-bind : 强制绑定解析表达式, 可以省略v-bind
v-model : 双向数据绑定
ref : 为某个元素注册一个唯一标识, vue对象通过$refs属性访问这个元素对象
v-cloak : 使用它防止闪现表达式, 与css配合: [v-cloak] { display: none }
<div id="app">
<p ref="content">aaaaaaaa</p>
<p> {{msg}} </p>
<button @click="hint">提示</button>
</div>
<script>
let vm = new Vue({
el: '#app',
data: {
},
methods: {
hint() {
//alert(this.$refs.content.innerHTML)
alert(this.$refs.content.textContent)
}
},
})
</script>
自定义全局指令与局部指令
- 注册全局指令
Vue.directive('my-directive', function(el, binding){
el.innerHTML = binding.value.toupperCase()
})
- 注册局部指令
directives : {
'my-directive' : {
bind (el, binding) {
el.innerHTML = binding.value.toupperCase()
}
}
}
- 使用指令
v-my-directive='xxx'
自定义2个指令
- 功能类型于v-text, 但转换为全大写
- 功能类型于v-text, 但转换为全小写
<div id="app">
<p v-upper-text="msg1"> {{ msg1 }}</p>
<p v-lower-text="msg1"> {{ msg1 }}</p>
</div>
<script>
// 注册一个全局指令
// el: 指令所在的标签对象
// binding: 包含指令相关数据的容器对象
Vue.directive('upper-text', (el, binding) => el.textContent = binding.value.toUpperCase())
let vm = new Vue({
el: '#app',
data: {
msg1: 'kasdaAasWaa',
},
methods: {
},
// 注册局部指令
directives: {
'lower-text'(el, binding) {
el.textContent = binding.value.toLowerCase()
}
}
})
</script>
插件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>17_插件</title>
</head>
<body>
<div id="test">
<p v-my-directive="msg"></p>
</div>
<script type="text/javascript" src="../js/vue.js"></script>
<script type="text/javascript" src="vue-myPlugin.js"></script>
<script type="text/javascript">
// 声明使用插件(安装插件: 调用插件的install())
Vue.use(MyPlugin) // 内部会调用插件对象的install()
const vm = new Vue({
el: '#test',
data: {
msg: 'HaHa'
}
})
Vue.myGlobalMethod()
vm.$myMethod()
new Object()
</script>
</body>
</html>
自定义的插件(vue-myPlugin.js):
(function (window) {
const MyPlugin = {}
MyPlugin.install = function (Vue, options) {
// 1. 添加全局方法或属性
Vue.myGlobalMethod = function () {
console.log('Vue函数对象的myGlobalMethod()')
}
// 2. 添加全局资源
Vue.directive('my-directive',function (el, binding) {
el.textContent = 'my-directive----'+binding.value
})
// 4. 添加实例方法
Vue.prototype.$myMethod = function () {
console.log('vm $myMethod()')
}
}
window.MyPlugin = MyPlugin
})(window)