一、Vue的安装
1.首先下载node
2.然后引用vue的框架,vue下载地址https://cdn.jsdelivr.net/npm/vue/dist/vue.js
二、vue简述
1.MVVM模式
- Model:负责数据存储
- View:负责页面展示
- View Model:负责业务逻辑,类比MVC模式的Controller
三、开发
3.1 初识Vue–声明渲染
-
在
HBuilderX
里新建项目,选择Vue项目
,系统会自动引入Vue.js
文件 -
Vue框架的使用就是在
html
文件里 -
首先定义要显示的文件的
id=‘app’
,该id可任意命名<div id="app"> {{title}} <h1>{{msg}}</h1> </div>
-
然后进行数据绑定
<script type="text/javascript"> // console.log(Vue) // 告诉系统该元素使用Vue框架 let app = new Vue({ // #后跟数据id el:"#app", // 模型 Model data:{ title:"Hello Vue!!", msg:"sh" } }) console.log(app) </script>
-
记住Vue框架是双向绑定,因此在html的源码里输入
app.title = 'liting'
,然后再回车,页面显示的值会改变。
修改前
修改语句
修改后
3.2 条件渲染
3.2.1 v-if
- 判断用户是否为VIP用户时,需要进行条件判断
- 语法为
<h3 v-if="isVip">用户类型: VIP</h3>
,v-if
为判断标识,isVip
为变量(变量名可任意定义),当变量值为true
时,显示用户类型: VIP
内容。 v-else
:当用户类型不是Vip时,显示该内容。语句为
<h3 v-else>用户类型:普通用户</h3>
- 注意: v-if和v-else中间不能有其他的元素
v-else-if
:多条件,比如判断用户年龄,后面可直接跟条件:"age>18"
,也可跟变量:"isVip"
<h3 v-if="age>18">允许24小时登陆</h3> <h3 v-else-if="age>14">允许8小时登陆</h3> <h3 v-else>允许4小时登陆</h3>
3.2.2 v-show
-
点击按钮,切换显示。当
isShow为true
时,显示定义的内容。<div id="app"> <div v-show="isShow" id="pane"> HelloVue </div> //点击事件的绑定 <button @click="showBtn">切换显示内容</button> </div>
<script type="text/javascript"> let app = new Vue({ el:"#app", data:{ isShow:true }, methods:{ showBtn:function(){ app.isShow = !app.isShow; } } }) </script>
isShow为true时
isShow为false时
3.2.3 v-if
和v-show
的区别
v-if:
不显示时,第一次就直接不渲染,如果是内容已经显示将其改为不显示,将内容直接从Dom去除
,只是渲染1次的内容用v-if
v-show:
不显示时,就会改为display:none
,但是会渲染在DOM上。反复需要切换的内容,使用v-show
3.3 列表渲染
-
我们可以用
v-for
指令基于一个数组来渲染一个列表。v-for 指令需要使用item in items
形式的特殊语法,其中items
是源数据数组,而item
则是被迭代的数组元素的别名。 -
data里的数据
data:{ stars:['蔡徐坤',"苏有朋","范冰冰","李晨"], students:[ { studentName:"小明", age:16, school:"清华" }, { studentName:"小黑", age:17, school:"北大" } ] }
1.items里元素是单个字符时,按顺序将items里的数据展示
<div id="app">
<h3>明星列表</h3>
<ul>
<li v-for="item in stars">
{{item}}
</li>
</ul>
</div>
结果图
2.items里元素是数组时,可以用.
表示输出数组的某一属性,比如item.studentname
表示学生的姓名
<div id="app">
<h3>学生列表</h3>
<ul>
<li v-for="item in students">
<h4>{{item.studentName}}</h4>
<p>年龄:{{item.age}}---学校:{{item.school}}</p>
</li>
</ul>
</div>
结果图
3.items里元素是数组且带索引值显示
<div id="app">
<h3>学生列表</h3>
<ul>
<li v-for="item,key in students">
<h4>索引值:{{key}}---{{item.studentName}}</h4>
<p>年龄:{{item.age}}---学校:{{item.school}}</p>
</li>
</ul>
</div>
结果图
4.循环学生列表的某个对象的所有属性
<h3>循环对象</h3>
<ul>
<li v-for="item,key in students[0]">key:{{key}}---value:{{item}}</li>
</ul>
5.按条件循环渲染,将学生年龄为偶数的输出
- 先循环在判断
- ul是无序列表,全称是unordered list
- ol是有序列表 ,全称是ordered list
<ol>
<li v-if="item.age%2==0" v-for="item,index in students" :key="index">
<h4>索引值:{{index}} -------- {{item.studentName}}</h4>
<p>年龄:{{item.age}}---学校:{{item.school}}</p>
</li>
</ol>
结果图
6.当只修改了某个对象的单个属性,vue只会将变动的值显示,其他的不会改变,因此设置key
值,它会认为每个都是独一无二的,会将整个对象都修改,重新显示。
key设置实例
<div v-if="loginType === 'username'" key = 'username'>
3.4模板语法
1.一次性插入,值不能修改
<h1>{{msg}}</h1>
<!--v-once 一次性插入,不在修改 -->
<h1 v-once>{{msg}}</h1>
el:"#app",
data:{
msg:"hello Vue"
}
当修改msg的值时,页面显示不变
修改语句
结果图,没有v-once
标识的msg
值改变了,有v-once
没变。
2.原始HTML
双大括号会将语义解释为普通文本,而不是html,需要使用v-html
指令,才能识别为html。
<h1>{{htmlTxt}}</h1>
<!-- v-html插入HTML内容 -->
<h1 v-html="htmlTxt"></h1>
htmlTxt:'<span>hello</span>',
结果图:可以看见使用v-html
指令和没使用的区别
3.绑定动态属性,修改属性的内容
绑定修改属性的id,当id为register
时,背景为粉色;当id为login
时,背景为蓝色。
绑定代码
<!-- 修改属性内容 -->
<!-- 绑定动态属性,全写 -->
<div v-bind:id="idname">
<h1>登陆</h1>
</div>
<!-- 绑定动态属性,省略 -->
<div :id="idname">
<h1>登陆</h1>
</div>
data:{
idname = 'register'
}
样式代码,实现背景色的改变
<style type="text/css">
#login{
background: skyblue;
}
#register{
background: pink;
}
</style>
4.字符拼接,目前为止,都只是显示单一的属性值,如果想要实现拼接,只需要用+
连接。
<div>
{{firstname+lastname}}
</div>
data:{
firstname:"张",
lastname:"三",
},
结果图
5.三元运算法,{{A?B:C}}
,A为true则B,否则为C。
示例
{{isVip?"欢迎VIP用户回来":"普通用户请充值"}}
isVip默认为真:isVip:true
结果显示
isVip为true时:
把isVip修改为false时,结果显示为:
6.事件绑定
<!-- 事件的绑定 全写-->
<button v-on:click="changeBg">改变背景</button>
<!-- 事件的绑定 省略-->
<button @click="changeBg">改变背景</button>
3.5 计算属性和侦听器
- 计算属性的优势:会缓存计算结果,只要结果不改变,函数就不会再次被调用
1.计算拼接
示例:当实现字符拼接时,需要拼接的字符内容可能会改变,因此我们利用计算属性,直接计算拼接后的内容。
一次修改,两个性能差不多。只有反复修改时,计算属性的性能会高。
<!-- 一般情况下写法 -->
<h1>{{firstname+lastname}}</h1>
<!-- 计算属性 -->
<h1>{{fullname}}</h1>
data:{
firstname:"张",
lastname:"三",
}
//计算属性的指令computed
computed:{
fullname:function(){
console.log(this)
//会将计算的结果进行缓存,只要this.firstname和lastname变量的内容不改变,就不会重新计算
return this.firstname+this.lastname
},
2.逆序显示
<!-- 逆序显示一个单词 -->
//一般写法,先分割,在逆序,最后连接
<h1>{{word.split("").reverse().join("") }}</h1>
//计算属性
<h1>{{reverseWord}}</h1>
reverseWord:function(){
return this.word.split("").reverse().join("")
},
3.显示一个列表中符合条件的对象
一般写法,需要双重操作,先循环后判断,因此性能不是很好,因此使用计算属性,先将符合条件的提取出来,在循环显示。
实例:显示学生列表中年龄为偶数的对象,与 3.3节的 5.按条件循环渲染,对照看,一个为普通写法,一个为计算属性。
<ul>
<li v-for="item,index in oddStudents">
<h3>{{item.studentName}}</h3>
<h4>{{item.age}}----{{item.school}}</h4>
</li>
</ul>
oddStudents:function(){
let results = this.students.filter((item,i)=>{
return item.age%2==0
})
return results
}
4.侦听器
监听数据改变的事件:当msg的值发生改变时,触发监听事件。
watch:{
// msg:被监听的对象
msg:function(val){
console.log("监听事件------msg")
console.log(val)
}
}
5.计算属性的setter
计算属性默认只有 getter,不过在需要时你也可以提供一个 setter:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<!-- 当存在数组时,使用侦听器可以监听数组中的数据,当数据发生变化时可触发事件 -->
<div id="app">
<h1>{{msg}}</h1>
<h1>{{reverseMsg}}</h1>
<ul>
<li v-for="item in arr">{{item}}</li>
</ul>
</div>
<script type="text/javascript">
var app = new Vue({
el:"#app",
data:{
msg:"hello vue",
arr:['小明','小红',"小黑"]
},
computed:{
reverseMsg:{
//设置set与get属性可以同步修改msg的值
get:function(){
return this.msg.split("").reverse().join("")
},
set:function(value){
//console.log(value)
this.msg = value.split("").reverse().join("")
}
}
},
/*
watch事件监听尽量不要使用的太多,会影响性能,可以使用compute
*/
watch:{
msg:function(val){
console.log("监听事件------msg")
console.log(val)
},
arr:function(val){
console.log("监听事件-------arr")
this.msg = "监听事件-------arr"
console.log(val)
}
}
})
</script>
</body>
</html>
其中设置set属性的是:
computed:{
reverseMsg:{
//设置set与get属性可以同步修改msg的值
get:function(){
return this.msg.split("").reverse().join("")
},
set:function(value){
//console.log(value)
this.msg = value.split("").reverse().join("")
}
}
},
当调用app.reverseMsg = ' '
时,msg
的值也会修改。
3.6 class和style
1.绑定HTML Class
-
对象语法:我们可以传给 v-bind:class 一个对象,以动态地切换 class:
<div v-bind:class="{ active: isActive }"></div>
上面的语法表示
active
这个 对象存在与否将取决于属性isActive
的 truthiness。
通过v-bind,可以动态修改类的样式。
也可以直接放置对象,没有属性<!-- 直接放置对象 --> <div class="page" :class="styleObj"></div>
-
数组语法
我们可以把一个数组传给v-bind:class
,以应用一个 class 列表:<div v-bind:class="[activeClass, errorClass]"></div>
data: { activeClass: 'active', errorClass: 'text-danger' }
渲染为:
<div class="active text-danger"></div>
如果你也想根据条件切换列表中的 class,可以用三元表达式:<div v-bind:class="[isActive ? activeClass : '', errorClass]"></div>
这样写将始终添加
errorClass
,但是只有在isActive
是truthy
时才添加activeClass
。
2.绑定内联样式
-
CSS内联样式变量拼接 ,长,高和边框
<div style="width: 100px;height: 100px;background: salmon;" :style="{border:borderWidth+'px solid plum',padding:paddingWidth+'px'}"></div>
data:{ borderWidth:50, paddingWidth:30, }
-
CSS内联样式放置对象
<div :style="styleObj"></div>
data: { styleObj: { color: 'red', fontSize: '13px' } }
-
CSS 数组的方式进行拼接
<div :style="styleArr"></div>
styleArr:[ { width:"200px", height:"300px", padding:"50px", 'background-color':'skyblue' },{ border:"30px solid yellow" } ]
3.7 事件处理
1.监听事件
- 方式一:可以使用表达式完成事件操作
<button type="button" @click="count+=1">点击</button>
- 方式二:获取事件对象 ,
clickEvent
是方法名<button type="button" @click="clickEvent">点击2</button>
methods:{ clickEvent:function(event){ console.log(event) console.log(this) this.count++; } }
2.事件传参
-
需点击对象才会在后台进行传参操作。点击列表对象,点击事件监听到,输出该对象索引值和内容。
<ul> <li v-for="item,index in stars" @click="clickEvent(index,item,$event)">索引值:{{index}}----内容:{{item}}</li> </ul>
3.事件修饰符
-
使用修饰符时,顺序很重要;相应的代码会以同样的顺序产生。因此,用
v-on:click.prevent.self
会阻止所有的点击,而v-on:click.self.prevent
只会阻止对元素自身的点击。<!-- 阻止单击事件继续传播 --> <a v-on:click.stop="doThis"></a> <!-- 提交事件不再重载页面 --> <form v-on:submit.prevent="onSubmit"></form> <!-- 修饰符可以串联 --> <a v-on:click.stop.prevent="doThat"></a> <!-- 只有修饰符 --> <form v-on:submit.prevent></form> <!-- 添加事件监听器时使用事件捕获模式 --> <!-- 即内部元素触发的事件先在此处理,然后才交由内部元素进行处理 --> <div v-on:click.capture="doThis">...</div> <!-- 只当在 event.target 是当前元素自身时触发处理函数 --> <!-- 即事件不是从内部元素触发的 --> <div v-on:click.self="doThat">...</div> <!-- 点击事件将只会触发一次 --> <a v-on:click.once="doThis"></a>
-
Vue 还对应
addEventListener
中的 passive 选项提供了.passive
修饰符。<!-- 滚动事件的默认行为 (即滚动行为) 将会立即触发 --> <!-- 而不会等待 `onScroll` 完成 --> <!-- 这其中包含 `event.preventDefault()` 的情况 --> <div v-on:scroll.passive="onScroll">...</div>
警告:不要把
.passive
和.prevent
一起使用,因为 .prevent 将会被忽略,同时浏览器可能会向你展示一个警告。请记住,.passive 会告诉浏览器你不想阻止事件的默认行为。 -
阻止单击事件继续传播
<!-- stop修饰符,阻止冒泡事件向上传递 --> <div class="btnParent" @click="clickParent"> <!-- @click.stop 阻止单击事件继续传播 --> <button type="button" @click.stop="clickEvent">按钮</button> </div>
在上述例子中,点击了
button
就相当于点击了div
,单击事件会继续向上冒泡传播。因此,想要阻止事件向上传递,需要使用stop
指令。 -
阻止默认事件
<input @click.prevent="searchWeather" type="submit" name="" id="" value="提交" />
提交有默认的触发事件,因此需要
.prevent
指令阻止,并让它执行我们定义的函数searchWeather
。
4.按键修饰符
-
绑定输入框回车事件 ,
@keydown.enter
则指明回车事件。<input type="text" @keydown.enter="searchWeather" name="username" v-model="city"/>
列举按键修饰符:
.enter
.tab
.delete (捕获“删除”和“退格”键)
.esc
.space
.up
.down
.left
.right -
绑定多个按键修饰符,
@keydown.enter.f2
,可以继续.+按键
。
5.系统修饰键
-
.exact
修饰符,允许你控制由精确的系统修饰符组合触发的事件。@click.ctrl.exact
有且只有Ctrl
被按下的时候才触发<button type="button" @click.ctrl.exact="ctrlEvent">按住ctrl事件</button>
3.8 表单输入绑定
可以用 v-model
指令在表单 <input>、<textarea> 及 <select>
元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素。尽管有些神奇,但 v-model 本质上不过是语法糖。它负责监听用户的输入事件以更新数据,并对一些极端场景进行一些特殊处理。
1.单行文本输入
-
数据的双向绑定,在输入框修改messgae时,文本的message也会改变。
<input v-model="message" placeholder="edit me"> <p>Message is: {{ message }}</p>
data:{ message:'edit me', }
2.多行文本输入
只要绑定同一个属性,一个地方修改了,则其他的都会修改。
<h2>多行文本输入框</h2>
<textarea rows="" cols="" v-model="username"></textarea>
3.复选框
将选中的数据fruit
,写入定义好的数组checkFruits
。
<span v-for="item in fruits">
{{item}}
<input type="checkbox" name="fruit" v-model="checkFruits" :value="item" />
</span>
<h2>{{checkFruits}}</h2>
4.单选框
<h1>单选框: 选择喜欢的水果</h1>
<!--单选框 type="radio" -->
<span v-for="item in fruits">
{{item}}
<input type="radio" name="fruit" v-model="radioFruits" :value="item" />
</span>
<h2>{{radioFruits}}</h2>
5.下拉选项框
- 单选城市选项
<select v-model="chooseCity">
//在选项前加入一个禁用的空选项
<option disabled value="">请选择</option>
<option v-for="item in citys" :value="item">{{item}}</option>
</select>
<h3>{{chooseCity}}</h3>
- 复选城市选项 注意在进行多选时需要按住ctrl键
<select v-model="moreCity" multiple="multiple">
<option v-for="item in citys" :value="item">{{item}}</option>
</select>
<h3>{{moreCity}}</h3>
6.修饰符
- 想自动将用户的输入值转为数值类型,可以给
v-model
添加number
修饰符。<input type="text" name="age" v-model.number="age" value="" />
- 在默认情况下,v-model 在每次
input
事件触发后将输入框的值与数据进行同步 (除了上述输入法组合文字时)。你可以添加lazy
修饰符,从而转为在change
事件之后进行同步。<!-- 在“change”时而非“input”时更新 --> <input v-model.lazy="msg">
- 如果要自动过滤用户输入的首尾空白字符,可以给 v-model 添加 trim 修饰符:
<input v-model.trim="msg">
3.9 过渡动画
1.进入离开的效果
-
组件过渡:Vue 提供了
transition
的封装组件,在下列情形中,可以给任何元素和组件添加进入/离开过渡。条件渲染 (使用 v-if)
条件展示 (使用 v-show)
动态组件
组件根节点淡入淡出的进入效果
<transition name="fade" > <div v-if="isShow" class="content"></div> </transition>
必须在style里添加效果方法
.fade{ }
<style type="text/css"> /* opacity 用于设置元素的不透明度级别 value :规定不透明度。从 0.0 (完全透明)到 1.0(完全不透明)。 */ /* 透明度过度,即由浅变深 */ .fade-enter-active, .fade-leave-active { transition: opacity 5s; } .fade-enter, .fade-leave-to { opacity: 0; }
-
自定义过渡的类名
我们可以通过以下 attribute 来自定义过渡类名:enter-class
enter-active-class
enter-to-class (2.1.8+)
leave-class
leave-active-class
leave-to-class (2.1.8+)他们的优先级高于普通的类名,这对于 Vue 的过渡系统和其他第三方 CSS 动画库,如 Animate.css 结合使用十分有用。
示例:
// animate.css地址 <link href="https://cdn.jsdelivr.net/npm/animate.css@3.5.1" rel="stylesheet" type="text/css"> <div id="app"> // 自定义过渡的类名 <transition name="slide" enter-active-class="animated bounceInLeft" leave-active-class="animated bounceOutRight"> <div v-if="isShow" class="content"></div> </transition> <button @click="toggleEvent">切换内容</button> </div>