一、Vue的基本使用
1、编码
<div id="app">
<input type="text" v-model="username">
<p>Hello, {{username}}</p>
</div>
<script type="text/javascript" src="../js/vue.js"></script>
<script type="text/javascript">
new Vue({
el: '#app',
data: {
username: 'world'
}
})
</script>
2、理解 Vue 的 MVVM
3、模板语法
(1)、模板语法的理解
Ⅰ、动态的 html 页面;
Ⅱ、 包含了一些 JS 语法代码
① 双大括号表达式 {{}} ;
② 指令(以v-开头的自定义标签属性)
(2)、双大括号表达式
Ⅰ、语法:{{exp}}
Ⅱ、功能:向页面输出数据
Ⅲ、可以调用对象的方法
(3)、指令一:强制数据绑定
Ⅰ、功能:指定变化的属性值
Ⅱ、完整写法:v-bind:xxx = 'yyy' //yyy会作为表达式解析执行
Ⅲ、简洁写法: :xxx = 'yyy'
(4)、指令二:绑定事件监听
Ⅰ、功能:绑定指定事件名的回调函数
Ⅱ、完整写法:v-on:keyup='xxx'
v-on:keyup='xxx(参数)'
v-on:keyup.enter='xxx'
Ⅲ、简洁写法:@keyup='xxx'
@keyup.enter='xxx'
(5)、编码
<div id="app">
<h2>1. 双大括号表达式</h2>
<p>{{msg}}</p>
<p>{{msg.toUpperCase()}}</p>
<h2>2. 指令一: 强制数据绑定</h2> <a href="url">访问指定站点</a>
<br>
<!-不 能 使 用 --> <a v-bind:href="url">访问指定站点 2</a>
<br> <a :href="url">访问指定站点 3</a>
<br>
<h2>3. 指令二: 绑定事件监听</h2>
<button v-on:click="handleClick">点我</button>
<button @click="handleClick">点我 2</button>
</div>
<script type="text/javascript" src="../js/vue.js"></script>
<script type="text/javascript">
new Vue({
el: '#app',
data: { //data的所有属性都会成功vm对象的属性,而模板页面中可以直接访问
msg: 'NBA I Love This Game!',
url: 'http://www.baidu.com'
},
methods: {
handleClick () {
alert('处理点击')
}
}
})
</script>
4、计算属性和监视
(1)、计算属性
Ⅰ、在 computed 属性对象中定义计算属性的方法;
Ⅱ、在页面中使用 {{方法名}} 来显示计算的结果
(2)、监视属性
Ⅰ、通过 vm 对象的 $watch() 或 watch 配置来监视指定的属性;
Ⅱ、当属性变化时,回调函数自动调用,在函数内部进行计算;
(3)、计算属性高级
Ⅰ、通过 getter/setter 实现对属性的显示和监视;
Ⅱ、计算属性存在缓存,多次读取只执行一次 getter 计算;
(4)、编码
<div id="app">
性:<input type="text" placeholder="First LastName" v-model="firstName"/></br>
名:<input type="text" placeholder=" Name" 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 type="text/javascript">
const vm = new Vue({
el: "#app",
data: {
firstName: "A",
lastName: "B",
// fullName1: "A B",
fullName2: "A B",
// fullName3: "A B",
},
computed: { //计算属性,(计算属性存在缓存)
//什么时候执行:初始化显示/相关的data属性数据发生了改变
//计算并返回当前属性得值
fullName1(){ //计算属性里的方法
console.log("fullName1()")
return this.firstName+ " "+this.lastName;
},
fullName3: {
//什么是回调函数:1、你定义的;2、你没有调;3、但最终它执行了
//1、什么时候调用? 2、用来做什么
//回调函数,当需要读取当前属性值时回调,根据相关的数据计算并返回当前属性的值
get(){
return this.firstName+ " "+this.lastName;
},
//回调函数,监视当前属性值的变化,当属性值发生改变时回调,更新相关的属性数据
set(value){ //value 就是fullName3的最新属性值
const names = value.split(" ");
this.firstName = names[0]
this.lastName = names[1]
}
}
},
watch: { //配置监视
firstName (value){ //firstName发生改变
console.log(this); //vm 对象
this.fullName2 = value + " " + this.lastName;
}
}
})
vm.$watch("lastName", function (value) {
//更新fullName2
this.fullName2 = this.firstName+ " "+value;
})
</script>
5、class 与 style 绑定
(1)、理解
Ⅰ、在应用界面中,某个(些)元素的样式是变化的;
Ⅱ、class/style 绑定就是专门用来实现动态样式效果的技术;
(2)、class 绑定
Ⅰ、class='xxx';
Ⅱ、表达式是字符串:'classA';
Ⅲ、表达式是对象:[classA: isA, classB: isB];
Ⅳ、表达式是数组:['classA', 'classB'];
(3)、style 绑定
Ⅰ、:style="{color: activeColor, fontSize: fontSize+ 'px'}";
Ⅱ、其中 activeColor/fontSize 是 data 属性;
(4)、编码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>强制绑定class和style</title>
</head>
<style>
.aClass{
color: red;
}
.bClass{
color: blue;
}
.cClass{
font-size: 22px;
}
</style>
<body>
<div id="app">
<h2>1、class绑定::class='xxx'</h2>
<p class="cClass" :class="a">xxx是字符串</p>
<p :class="{aClass: isA, bClass: isB}">xxx是对象</p>
<p :class="['aClass', 'cClass']">xxx是数组</p>
<h2>2、style绑定::class</h2>
<p :style="{color: activeColor,fontSize: fontSize+'px'}">
:style="{color: activeColor,fontSize: fontSize+'px'}"
</p>
<button @click="update">更换</button>
</div>
<script src="../js/vue.2.6.10.js"></script>
<script type="text/javascript">
new Vue({
el: '#app',
data: {
a: 'aClass',
isA: true,
isB: false,
activeColor: 'red',
fontSize: 22,
},
methods: {
update(){
this.a = 'bClass';
this.isA = false;
this.isB = true;
this.activeColor = 'green';
this.fontSize = 14;
}
}
})
</script>
</body>
</html>
6、条件渲染
(1)、 条件渲染指令
Ⅰ、v-if 与 v-else;
Ⅱ、v-show;
(2)、 比较 v-if 与 v-show
Ⅰ、如果需要频繁切换 v-show 较好;
Ⅱ、当条件不成立,v-if 的所有子节点不会解析(项目中使用)
(3)、 编码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>条件渲染</title>
</head>
<body>
<div id="app">
<p v-if="ok">成功了</p>
<p v-else>失败</p>
<p v-show="ok">完成</p>
<p v-show="!ok">未完成</p>
<button @click="ok=!ok">切换</button>
<!--
v-if与v-show对比:如果需要频繁切换v-show比较好
-->
</div>
<script src="../js/vue.2.6.10.js"></script>
<script type="text/javascript">
new Vue({
el: '#app',
data: {
ok: true
}
})
</script>
</body>
</html>
7、列表渲染
(1)、列表显示指令
Ⅰ、数组:v-for / index;
Ⅱ、对象:v-for / key;
(2)、列表的更新显示
Ⅰ、删除 item;
Ⅱ、替换 item;
(3)、列表的高级处理
Ⅰ、列表过滤;
Ⅱ、列表排序;
(4)、编码1
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>列表渲染</title>
</head>
<body>
<div id="app">
<h2>测试:v-for遍历数组</h2>
<ul>
<li v-for="(item, index) in persons" :key="index">
编号:{{index+1}},
姓名:{{item.name}},
年龄:{{item.age}},
-----<button @click="deleteItem(index)">删除</button>
---<button @click="updateItem(index)">更新</button>
</li>
</ul>
<h2>测试:v-for遍历对象</h2>
<ul>
<li v-for="(value, key) in persons[1]" :key="key">
{{key}}--------{{value}}
</li>
</ul>
</div>
<script src="../js/vue.2.6.10.js"></script>
<script type="text/javascript">
new Vue({
el: '#app',
data: {
persons:[//vue本身只是监视了persons的改变,没有监视数组内部数据的改变
{name:'关羽',age: 38},
{name:'张飞',age: 35},
{name:'赵云',age: 33},
{name:'马超',age: 30},
{name:'黄忠',age: 60}
]
},
methods: {
deleteItem(index){
this.persons.splice(index, 1);
},
updateItem(index){
// this.persons[index] = {name: '刘备', age: '40'}; //并没有改变peersons本身
this.persons.splice(index,1,{name: '刘备', age: '40'});
}
}
})
</script>
</body>
</html>
(5)、编码2
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>列表搜索过滤</title>
</head>
<body>
<div id="app">
<h2>测试:列表过滤、排序</h2>
<input type="text" v-model="searchName" style="margin-left: 25px"/>
<ul>
<li v-for="(item, index) in filterPersons" :key="index">
编号:{{index+1}},
姓名:{{item.name}},
年龄:{{item.age}}
</li>
</ul>
<button @click="setOrderType(1)" style="margin-left: 25px">年龄升序</button>
<button @click="setOrderType(2)" >年龄降序</button>
<button @click="setOrderType(0)" >原本顺序</button>
</div>
<script src="../js/vue.2.6.10.js"></script>
<script type="text/javascript">
new Vue({
el: '#app',
data: {
searchName: '',
orderType: 0, //0代表不排序,1代表升序,2代表降序
persons:[//vue本身只是监视了persons的改变,没有监视数组内部数据的改变
{name:'Tom',age: 21},
{name:'Jack',age: 19},
{name:'Rose',age: 22},
{name:'Bob',age: 20},
{name:'Lose',age: 18}
]
},
computed: { //计算属性
filterPersons(){
//取出相关的数据
const {searchName, persons, orderType} = this;
//最终需要显示的数组
let resPesons;
//对 persons 进行过滤
resPesons = persons.filter( item => item.name.indexOf(searchName)!=-1);
//排序
if (orderType != 0){
resPesons.sort(function (p1, p2) {//如果返回负数p1在前,返回正数p2在前,
//1代表升序,2代表降序
if (orderType == 2){
return p2.age-p1.age;
} else {
return p1.age-p2.age;
}
})
}
return resPesons;
}
},
methods: {
setOrderType(orderType){
this.orderType = orderType;
}
},
})
</script>
</body>
</html>
8、事件处理
(1)、绑定监听
Ⅰ、v-on:xxx="fun";
Ⅱ、@xxx="fun";
Ⅲ、@xxx="fun(参数)";
Ⅳ、默认事件参数: event;
Ⅴ、隐含属性对象:$event
(2)、事件修饰符
Ⅰ、.prevent:阻止事件的默认行为 event.preventDefault();
Ⅱ、.stop:停止事件冒泡 event.stopPropagation();
(3)、按键饰符
Ⅰ、.keycode:操作的是某个 keycode 值的键;
Ⅱ、.keyName:操作的是某个按键名的键(少部分);
(4)、编码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>事件处理</title>
</head>
<body>
<div id="app">
<h2>1.绑定监听</h2>
<button @click="test1">test1</button>
<button @click="test2('你好')">test2</button>
<button @click="test3">test3</button>
<button @click="test4('你好', $event)">test4</button>
<h2>2.事件修饰符</h2>
<div style="width: 150px;height: 100px;background-color: antiquewhite" @click="test5">
<div style="width: 100px;height: 50px;background-color: burlywood" @click.stop="test6">阻止事件冒泡</div>
</div>
<a href="http://www.baidu.com" @click.prevent="test7">去百度</a>
<h2>3.按键修饰符</h2>
<input type="text" @keyup.enter="test8"/>
</div>
<script src="../js/vue.2.6.10.js"></script>
<script type="text/javascript">
new Vue({
el: '#app',
data: {
},
methods: {
test1(){
alert("test1");
},
test2(param){
alert(param);
},
test3(event){
// console.log(event.target.innerHTML);
alert(event.target.innerHTML);
},
test4(param, event){
// console.log(event.target.innerHTML);
alert(param+"----------"+event.target.innerHTML);
},
test5(){
alert("out");
},
test6(){
alert("inner");
},
test7(){
// event.preventDefault();
alert("阻止事件默认行为");
},
test8(event){
alert(event.target.value);
// console.log(event);
}
}
})
</script>
</body>
</html>
9、表单输入绑定
(1)、使用 v-model 对表单数据自动收集
Ⅰ、text/textarea;
Ⅱ、checkbox;
Ⅲ、radio;
Ⅳ、select;
(2)、编码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>表单数据自动收集</title>
</head>
<body>
<div id="app">
<form action="/xxx" @submit.prevent="handleSubmit">
<span>用户名:</span>
<input type="text" v-model="username"/><br/>
<span>密 码:</span>
<input type="password" v-model="pwd"/><br/>
<span>性别:</span>
<input type="radio" id="female" value="female" v-model="sex"/>
<label for="female">女</label>
<input type="radio" id="male" value="male" v-model="sex"/>
<label for="male">男</label><br/>
<span>爱好</span>
<input type="checkbox" id="basket" value="basket" v-model="likes"/>
<label for="basket">篮球</label>
<input type="checkbox" id="foot" value="foot" v-model="likes"/>
<label for="foot">足球</label>
<input type="checkbox" id="pingpang" value="pingpang" v-model="likes"/>
<label for="pingpang">乒乓球</label><br/>
<span>城市</span>
<select v-model="allCity">
<option value="">未选择</option>
<option value="1">北京</option>
<option value="2">上海</option>
<option value="3">深圳</option>
<option value="4">杭州</option>
</select><br/>
<span>介绍</span>
<textarea rows="5" v-model="description"></textarea> <br/><br/>
<input type="submit" value="注册"/>
</form>
</div>
<script src="../js/vue.2.6.10.js"></script>
<script type="text/javascript">
new Vue({
el: '#app',
data: {
username: '',
pwd: '',
sex: 'male',
likes: [],
allCity: '',
description: '',
},
methods: {
handleSubmit(){
console.log(this.username, this.pwd, this.sex, this.likes, this.allCity, this.description);
}
}
})
</script>
</body>
</html>
10、过渡&动画
(1)、vue 动画的理解
Ⅰ、操作 css 的 trastion 或 animation;
Ⅱ、vue 会给目标元素添加/移除特定的 class;
Ⅲ、过渡的相关类名:
|--- xxx-enter-active:指定显示的 transtion;
|--- xxx-leave-active:指定隐藏的 transtion;
|--- xxx-enter/xxx-leave:指定隐藏时的样式;
(2)、基本过渡动画的编码
Ⅰ、在目标元素外包裹<transtion name="xxx">;
Ⅱ、定义 class 样式;
|--- 指定过渡样式:transtion;
|--- 指定隐藏时的样式:opacity/其它;
(3)、编码1
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>过渡&动画</title>
</head>
<style>
/*显示/隐藏的过渡效果*/
.aaa-enter-active, .aaa-leave-active {
transition: opacity 1s;
}
/*隐藏时的样式*/
.aaa-enter, .aaa-leave-to {
opacity: 0;
}
/*显示/隐藏的过渡效果*/
.bbb-enter-active {
transition: all 1s;
}
.bbb-leave-active{
transition: all 3s;
}
/*隐藏时的样式*/
.bbb-enter, .bbb-leave-to {
transform: translateX(30px);
opacity: 0;
}
</style>
<body>
<div id="app1">
<button @click="isShow=!isShow">toggle</button>
<transition name="aaa">
<p v-show="isShow">Hello</p>
</transition>
</div>
<div id="app2">
<button @click="isShow=!isShow">toggle2</button>
<transition name="bbb">
<p v-show="isShow">Hello</p>
</transition>
</div>
<script src="../js/vue.2.6.10.js"></script>
<script type="text/javascript">
new Vue({
el: '#app1',
data(){
return {
isShow: true,
}
}
})
new Vue({
el: '#app2',
data: {
isShow: true,
}
})
</script>
</body>
</html>
(4)、编码2
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>过渡&动画2</title>
</head>
<style>
.aaa-enter-active {
animation: aaa-in .5s;
}
.aaa-leave-active {
animation: aaa-in .5s reverse;
}
@keyframes aaa-in {
0% {
transform: scale(0);
}
50% {
transform: scale(1.5);
}
100% {
transform: scale(1);
}
}
.text{
display: inline-block;
}
</style>
<body>
<div id="app">
<button @click="isShow=!isShow">Toggle show</button><br/>
<transition name="aaa">
<p v-if="isShow" class="text">Lorem ipsum dolor sit amet</p>
</transition>
</div>
<script src="../js/vue.2.6.10.js"></script>
<script type="text/javascript">
new Vue({
el: '#app',
data(){
return {
isShow: true,
}
}
})
</script>
</body>
</html>
11、过滤器
(1)、理解过滤器
Ⅰ、功能:对要显示的数据进行特定格式化后再显示;
Ⅱ、注意:并没有改变原来的数据,可是产生新的对应的数据;
(2)、定义和使用过滤器
Ⅰ、定义过滤器:
Vue.filter(filterName,function(value[,arg1,arg2,...]){
// 进行一定的数据处理 returnnewValue
})
Ⅱ、使用过滤器:
<div>{{myData|filterName}}</div>
<div>{{myData|filterName(arg)}}</div>
(3)、编码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>vue过滤器</title>
</head>
<body>
<div id="app">
<h2>显示格式化的日期时间</h2>
<p>原始的:{{date}}</p>
<p>完整的:{{date | dateString}}</p>
<p>年月日:{{date | dateString("YYYY-MM-DD")}}</p>
<p>时分秒:{{date | dateString("HH:mm:ss")}}</p>
<P>new Date():{{date}}</P>
<P>moment():{{moment}}</P>
</div>
<script src="../js/vue.2.6.10.js"></script>
<script src="https://cdn.bootcss.com/moment.js/2.24.0/moment.min.js"></script>
<script type="text/javascript">
//自定义过滤器
// Vue.filter('dateString',function (value, format) {
// return moment(value).format(format || "YYYY-MM-DD HH:mm:ss");
// })
//"format="YYYY-MM-DD HH:mm:ss"形参默认值
Vue.filter('dateString',function (value, format="YYYY-MM-DD HH:mm:ss") {
return moment(value).format(format);
})
new Vue({
el: '#app',
data: {
date: new Date(),
moment: moment(),
}
})
</script>
</body>
</html>
12、内置指令和自定义指令
(1)、常用内置指令
- 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 对象通过$els 属性访问这个元素对象 ;
- v-cloak: 防止闪现, 与 css 配合:[v-cloak]{display:none};
(2)、自定义指令
1) 注册全局指令
Vue.directive('my-directive',function(el,binding){
el.innerHTML=binding.value.toupperCase()
})
2) 注册局部指令
directives:{
'my-directive':{
bind(el,binding){
el.innerHTML=binding.value.toupperCase()
}
}
}
3) 使用指令
v-my-directive='xxx'
(3)、编码1(内置指令)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>vue常用内置指令</title>
</head>
<style>
[v-cloak]{
display: none;
}
</style>
<body>
<!--
ref:指定唯一标识,vue对象通过$els属性访问这个元素对象
v-cloak:防止闪现,与css配合:[v-clock]{display: none}
-->
<div id="app">
<input type="text" ref="content"/>
<button @click="init">获得内容</button>
<p>有闪现:{{msg}}</p>
<p v-cloak>没闪现:{{msg}}</p>
</div>
<script src="../js/vue.2.6.10.js"></script>
<script>
alert("------")
new Vue({
el: '#app',
data:{
msg:'aaa'
},
methods: {
init(){
alert(this.$refs.content.value);
}
}
})
</script>
</body>
</html>
(4)、编码2(自定义指令)
需求: 自定义 2 个指令 :
- 功能类型于 v-text, 但转换为全大写
- 功能类型于 v-text, 但转换为全小写
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>自定义指令</title>
</head>
<body>
<div id="app1">
<p v-upper-text="msg1">a</p>
<p v-lower-text="msg1">b</p>
</div>
<div id="app2">
<p v-upper-text="msg2">1</p>
<p v-lower-text="msg1">2</p>
</div>
<script src="../js/vue.2.6.10.js"></script>
<script type="text/javascript">
//全局自定义指令
Vue.directive('upper-text', function (el, binding) {
console.log(el,binding)
el.textContent = binding.value.toUpperCase();
})
new Vue({
el: '#app1',
data: {
msg1: 'NBA I Love The Game!'
},
directives: {//局部自定义指令,当前vm管理的范围内有效
'lower-text': function (el, binding) {
el.textContent = binding.value.toLowerCase();
}
}
})
new Vue({
el: '#app2',
data: {
msg2: 'Just Do It!'
}
})
</script>
</body>
</html>
13、自定义插件
(1)、说明
- Vue 插件是一个包含 install 方法的对象 ;
- 通过 install 方法给 Vue 或 Vue 实例添加方法, 定义全局指令等;
(2)、 编码
1) 插件 JS
/**
* 自定义的 vue 插件库
*/
(function () {
//需要向外暴露的插件对象
const MyPlugin = {}
//插件对象必须有一个 install方法
MyPlugin.install = function (Vue, options) {
// 1. 添加全局方法或属性
Vue.myGlobalMethod = function () {
console.log("Vue函数对象的方法 myGlobalMethod()")
}
// 2. 添加全局资源
Vue.directive('my-directive', function (el, binding) {//自定义指令
el.textContent = binding.value.toUpperCase()
})
// 3. 注入组件选项
Vue.mixin({
created: function () {
}
})
// 4. 添加实例方法
Vue.prototype.$myMethod = function (methodOptions) {
console.log("Vue实例对象的方法 $myMethod()")
}
}
//向外暴露
window.MyPlugin = MyPlugin
})()
- 页面使用插件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>vue插件</title>
</head>
<body>
<div id="app">
<p v-my-directive="msg"></p>
</div>
<script src="../js/vue.2.6.10.js"></script>
<script src="./vue-myPlugin.js"></script>
<script type="text/javascript">
// 声明使用插件
Vue.use(MyPlugin) //内部会使用 MyPlugin.install(Vue)
Vue.myGlobalMethod()
const vm = new Vue({
el: '#app',
data: {
msg: 'I like you!'
}
})
vm.$myMethod()
</script>
</body>
</html>
网友评论