1.基本语法
view 视图 = html(模版) + data(数据)
动态页面是通过 js 来绑定,
传统方式 先抓页面元素 , 再 绑定数据
vue方式 先绑定 再赋值
先绑定数据, 之后 只关心数据的变化 不再关心 页面的数据显示过程
1.0.在线引包
<!-- 在线引包 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script>
1.1. 基本结构
页面中 用于渲染的 元素, 这里称为页面模板
<div id="app">
msg: {{ message }}
<br/>
{{getMsg()}}
<br/>
<button type="button" v-on:click="fn" >{{num}}</button>
</div>
脚本中 定义 vue 实例对象, 并传入 配置对象,
在配置对象中可以设置 属性 , 方法(函数)
var vm = new Vue({
el: '#app',
data: {
message: 'Hello Vue!',
getMsg: function(){
return "getMsg()自定义函数返回信息";
},
num:1
},
methods:{
fn:function(){
// this 指 vm 对象
this.num++;
}
}
})
1.1.1. el 属性 与 .$mount()
在 配置对象中 通过 el属性 与 页面元素 实现一对一 对应
也可以 通过 .$mount() 进行绑定
var vm = new Vue({
// el: '#app',
data: {
message: 'Hello Vue!',
getMsg: function(){
return "getMsg()自定义函数返回信息";
},
num:1
},
methods:{
fn:function(){
// this 指 vm 对象
this.num++;
}
}
})
// 与页面元素进行 绑定
vm.$mount("#app")
两种 方式 对应的元素, 都可以通过 CSS 选择器指定
1.1.2.data的两种定义方式
在 配置对象中 配置对象中定义 data 数据时, 可以使用 对象式, 也可以使用函数式
var vm = new Vue({
el: '#app',
data() {
return {
message: 'Hello Vue!',
getMsg: function () {
return "getMsg()自定义函数返回信息";
},
num: 1
}
},
methods:{
fn:function(){
// this 指 vm 对象
this.num++;
}
}
})
1.1.3.this
由vue管理的函数,一定不要写箭头函数,
使用普通函数时, this 指 vue 实例对象自己
使用箭头函数,this就不再是Vue实例了, 通常会是所属的window。
页面模板 增加 两个测试按钮
<button type="button" v-on:click="fn1" >按钮1</button>
<button type="button" v-on:click="fn2" >按钮2</button>
对应 methods 对象中, 增加两个函数 , 点击后在控制台可以观察
fn1:()=>{
// 使用 => 箭头函数
// this 指向 window 对象
console.log( this )
},
fn2:function(){
// this 指 vm 对象
console.log( this )
}
1.2. {{ }} 插(入)值表达式
在页面 元素的inner 位置 显示 信息
{{xxx}}中的xxx要写js表达式,且xxx可以自动读取到data中的所有属性
1.{{num + 1}} 运算
2.{{ok?'YES':'NO'}} 三元表达式
3.{{getMsg()}} 返回信息
4.{{ message.split('').reverse().join('') }} 函数调用
5.{{value.replace(/,/g,'')}} 可以写正则表达式
1.3. v-text v-html 元素信息
v-text 与 {{}} 产生的效果相似, v-text会替换掉节点中的内容,{{}}则会与之结合。
v-html 会对 html标签进行解析
<div id="app">
<!-- inner text -->
<span>{{msg}}</span> <br>
<span v-text="txtMsg" ></span> <br>
<!-- inner html -->
<textarea v-html="hmsg"></textarea> <br>
<span v-html="hcode" ></span> <br>
</div>
但 v-html 在文本域中 , 为文本原样输出, 与 v-text 相同
var vm = new Vue({
el: '#app',
data: {
// inner text
msg:"<font color='red' size='7'>插入信息</font>",
txtMsg:"<font color='red' size='7'>行内信息</font>",
// inner html
hmsg: '<font color='red' size='7'>文本域内容</font>',
hcode:"<font color='red' size='7'>这是HTML代码</font>",
}
})
1.4. v-bind 绑定属性
html属性不能使用 {{}} 形式绑定,只能使用v-bind指令
v-bind:属性=“xxx” 或 简写为 :属性=“xxx”,xxx同样要写js表达式,
当 html 属性 使用
属性 = "值 " 此时值 就是字符串
:属性 = “js表达式” 加了 绑定 , “” 双引号中按 js 表达式进行解析
<style>
.class1{
background: #444;
color: #eee;
}
</style>
<div id="app">
<p v-bind:title="getTitle()">html属性不能使用双大括号形式绑定,只能使用v-bind指令</p>
<div v-bind:id="'div-' + id">v-bind: 拼接 字符串 用 单引号</div>
<div v-bind:class="css1"> v-bind:class 指令 绑定 css 样式 </div>
<div :class="{class1:cssflag}"> {样式名:true 绑定样式/ false 不绑定} </div>
<div :style="{fontSize: size}">:style 是 v-bind:style 简写</div>
</div>
var app = new Vue({
el: '#app',
data: {
css1:"class1",
cssflag:false,
getTitle: function(){
return "getTitle()自定义函数返回信息";
},
id: 1,
size:"40px"
}
})
1.4.1.class绑定样式
1.4.1.1.静态样式 与 动态样式 相结合
div 的静态样式 basic , 与 动态样式 backColor 相结合
通过定时 修改 backColor
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<style>
.basic{
width: 100px;
height: 100px;
border: 1px solid black;
}
.back-red{
background-color: red;
}
.back-blue{
background-color: blue;
}
.back-green{
background-color: green;
}
</style>
</head>
<body>
<div id="app">
<div class="basic" :class="backColor" >{{name}}</div>
</div>
</body>
<script>
Vue.config.productionTip = false
const vm = new Vue({
el:'#app',
data:{
name:'vue',
backColor:'back-red',
},
mounted() {
this.changeBack();
},
methods: {
changeBack(){
const arr = ['back-red','back-blue','back-green']
let index = 0 ;
setInterval( () => {
this.name = index
this.backColor = arr[index]
if(index === arr.length-1 ){
index = 0
}else{
index++
}
},500)
}
},
})
</script>
</html>
1.4.1.2.动态管理多种样式
可以通过 数组的形式 一次指定多种样式
也可以通过 对象中为每一种样式设置 true / false 来控制
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<style>
.basic{
width: 100px;
height: 100px;
border: 1px solid black;
}
.select-back{
background-color: yellowgreen;
}
.select-font{
font-size: 30px;
color: #2b50e0;
}
.select-border{
border:#777777 solid 20px;
}
</style>
</head>
<body>
<div id="app">
<div class="basic" :class="classArr">{{name}}</div>
<div class="basic" :class="classObj">{{name}}</div>
</div>
</body>
<script>
const vm = new Vue({
el:'#app',
data:{
name:'vue',
classArr:['select-back','select-font','select-border'],
classObj:{
'select-back':true,
'select-font':true,
'select-border':true
}
}
})
</script>
</html>
1.4.2.style绑定样式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<div class="basic" :style="{ background : bcolor }">{{name}}</div>
<div class="basic" :style="styleObj">{{name}}</div>
<div class="basic" :style="styleArr">{{name}}</div>
</div>
</body>
<script>
Vue.config.productionTip = false
const vm = new Vue({
el:'#app',
data:{
name:'vue',
bcolor:'red',
styleObj:{
background:'orange'
},
styleArr:[{
color:'#ffffff',
},{
background:'gray'
}
]
},
})
</script>
</html>
1.5. v-model 双向绑定
单向绑定(v-bind) : 数据只能从data流向页面。
双向绑定(v-model) :数据不仅能从data流向页面,还可以从页面流向data。
v-model 是 v-model:value的 简写形式
<div id="app">
文本: <input :value="v1" />{{v1}} <br>
文本: <input v-model="v2" />{{v2}} <br>
<hr>
<input type="checkbox" name="" id="" v-model="language" value="java" />java <br>
<input type="checkbox" name="" id="" v-model="language" value="php" />PHP <br />
<input type="checkbox" name="" id="" v-model="language" value="vue" />Vue <br>
选中的是 <span v-text="language"></span>
</div>
var app = new Vue({
el: '#app',
data: {
v1:"使用v-bind:value, 显示信息",
v2:"使用v-model, 双向绑定",
language:['java', 'vue']
}
})
1.5.1. 绑定修饰符
lazy
:失去焦点再收集数据
number
:输入字符串转为有效的数字
trim
:输入首尾空格过滤
<div id="app">
<input v-model.lazy="msg" ><span>输入值为: {{ msg }}</span> <br>
<input v-model.number="age" type="number"> <span>输入值为: {{ age*10 }}</span> <br>
<input v-model.trim="tmsg"> <span>输入值为: {{ tmsg }}</span> <br>
</div>
new Vue({
el: '#app',
data: {
msg:'I am lazy;',
age:'18',
tmsg:' 两边有空格 '
}
})
1.6. v-on 绑定事件
使用 v-on:xxx=“fn” 或者 简写成 @xxx=“fn” 绑定事件,其中xxx是事件名
fn 可以是 在 methods 中 定义的函数 , 也可以是 js 表达式
<div id="app">
有{{num}}个赞
<button type="button" v-on:click="num++" >点赞</button>
<button type="button" v-on:click="cancle" >取消</button>
<button type="button" @click="num++" >点赞</button>
<button type="button" @click="cancle" >取消</button>
</div>
var app = new Vue({
el:"#app",
data:{
num:1
},
methods:{
cancle(){
this.num--
}
}
})
1.6.1.事件对象
在methods中定义的函数 , 使用普通函数格式时, 函数内 this 指向 vue实例对象
如何得到事件对象?
1.6.1.1.调用不传参时
页面模板, 不传参
<button type="button" v-on:click="fn1" >按钮1</button>
methods 中函数是的默认参数 为 事件对象
fn1($event){
// this 指 vm 对象
console.log( this )
// 默认参数为事件对象, target为事件源
console.log( $event.target )
},
1.6.1.2.调用传参时
页面模板, 传参时, 要同步传入事件对象, 注意这里 必须是 $event
<button type="button" v-on:click="fn2('hello', $event)" >按钮2</button>
methods 中函数根据实参顺序得到 事件对象
fn2(param, $event){
console.log( param )
// 事件对象, target为事件源
console.log( $event.target )
}
调用时 ,不传入 $event 事件对象 , 函数中将得不到事件对象
1.6.2. 事件修饰符
1.6.2.1.prevent
prevent 阻止默认事件发生
如 : a 超链接 默认事件是根据 href 为目标, 进行跳转, 事件中加入 prevent 会执行 click事件, 而不再跳转
页面模板 ,
<a href="http://www.baidu.com" @click.prevent="hello('a')" >baidu: 现在不去百度了</a>
methods 中函数
hello(val){
alert(val)
}
1.6.2.2.shop
stop 阻止事件冒泡到父元素
如果没有stop
点击按钮 hello 函数会分别 根据 button 及 div 执行, 先button 后 div
加入 stop 点击按钮 就只执行 按钮的 hello 函数
<div id="app">
<div style="border:1px solid red;width: 80%;height:100px;" @click="hello('div')">
<button @click.stop="hello('button')" >按钮</button>
</div>
</div>
1.6.2.3.其它修饰符
once : 只执行一次
capture:使用事件的捕获模式, 这时先执行 大的对象事件函数, 后执行小的对象的事件函数, 如上例, 先执行 div的, 再执行 button 的
self:只有event.target是当前操作的元素时才触发事件, 这种方式 也能阻止事件冒泡
<div id="app">
<div style="border:1px solid red;width: 80%;height:100px;" @click.self="hello('div')">
<button @click="hello('button')" >按钮</button>
</div>
</div>
passive: 事件的默认行为立即执行,无需等待事件回调执行完毕; 针对事件本身有明确的效果, 但处理函数执行时间长的时候使用
1.6.3. 按键修饰符
Vue中常用的按键别名:
回车 ( enter ) , 删除 ( delete (捕获“删除”和“退格”键) ) , 退出 ( esc ) , 空格 ( space ) , 制表 ( tab (特殊,必须配合keydown去使用) )
上 ( up ) , 下 ( down ) , 左 ( left ) , 右 ( right )
系统修饰键(用法特殊):ctrl、alt、shift、window ,
配合keyup使用:按下修饰键的同时,再按下其他键,随后释放其他键,事件才被触发。
配合keydown使用:正常触发事件。
<div id="app">
按键修饰符: <br>
enter tab delete esc space up down left right <br>
up键 +2 , alt + up 赋值为10 <br>
<input v-model="num" @keyup.up="num += 2" @keyup.alt.up="num = 10" />
</div>
var app = new Vue({
el:"#app",
data:{
num:1
}
})
1.7. v-if 判断
:v-if 可以和 :v-else-if、v-else 一起使用,但不能在整体结构中加入其它信息。
根据条件 控制 页面模板结构
<div id="app">
<div v-if="type === 'A'">A</div>
<div v-else-if="type === 'B'">B</div>
<div v-else-if="type === 'C'">C</div>
<div v-else>Not A/B/C</div>
</div>
var app = new Vue({
el: '#app',
data: {
type: 'C'
}
})
1.7.1.v-if v-show
v-if : 不展示的DOM元素直接被移除, 无法被获取
v-show : 不展示的DOM元素未被移除,是通过CSS样式隐藏掉, 还可以获取到
<div id="app" >
<button type="button" @click="show = !show">点击{{show}}</button>
<h1 v-if="show" > if 显示 是生不生成文档元素 </h1>
<h1 v-show="show" > show 显示 是 显不显示文档元素</h1>
</div>
var vm = new Vue({
el:"#app",
data:{
show:true
}
})
1.8. v-for 循环
1.8.1.数组
建立 在循环元素加 :key 绑定 唯一 值, 不写默认为 循环序号
<div id="app">
<h3>简单数组</h3>
<ul>
<li v-for=" (num,index) in nums" :key="index" >序号:{{index}} 值:{{num}}</li>
</ul>
<h3>对象数组</h3>
<ul>
<li v-for="stu in students" >{{ stu.name }}</li>
</ul>
<h3>直接循环</h3>
<ul>
<li v-for="n in 10">{{ n }}</li>
</ul>
</div>
var vm = new Vue({
el:"#app",
data:{
nums:[10,20,30,40,50],
students: [
{ name: '王小二' },
{ name: '李小三' },
{ name: '赵小四' }
],
}
})
1.8.1. 对象循环
<div id="app">
<ul>
<li v-for="value in stu">{{ value }}</li>
</ul>
<hr/>
<ul>
<li v-for="(value, key, index) in stu">
{{ index }}. {{ key }} : {{ value }}
</li>
</ul>
</div>
var app = new Vue({
el: '#app',
data: {
stu: {
name: '王小二',
age: 13,
sex: '男'
}
}
})
1.9.其它指令
1.9.1.v-cloak
v-cloak
指令,用于在 Vue 渲染 DOM 后再移除元素内的 CSS 类或样式,主要用于隐藏未渲染完成时的 Vue 模板{{ xxx }}语法产生的闪烁问题。
在 HTML 中使用 v-cloak
指令的方式如下:
<div v-cloak>
{{ message }}
</div>
然后在 CSS 中定义一个针对 .v-cloak
的样式,比如隐藏带有该类的所有元素:
[v-cloak] {
display: none;
}
当 Vue 实例完成渲染并且将数据绑定到 DOM 上之后,v-cloak
指令会自动被移除,因此之前被隐藏的元素将会显示出来,从而避免了由于 Vue 渲染过程导致的内容闪烁现象。
1.9.2.v-once
v-once
指令,用于指定元素及其子元素只进行一次渲染,之后即使数据发生变化,该元素也不会再重新渲染。
这在某些场景下可以提高性能,尤其对于大型列表中的一些静态内容部分。
例如:
<body>
<div id="app">
<h2 v-once>初始化的n值是:{{n}}</h2>
<h2>当前的n值是:{{n}}</h2>
<button @click="n++">点我n+1</button>
</div>
</body>
<script type="text/javascript">
new Vue({
el:'#app',
data:{
n:1
}
})
</script>
1.9.3.v-pre
v-pre
用于跳过当前元素和其子元素的编译过程。这意味着 Vue 将不会解析该元素及其内部的任何 Vue 语法,比如插值表达式 {{ }}
或指令等。
使用 v-pre
的典型场景是在模板中存在大量不需要 Vue 编译处理的原始文本时,它可以提高渲染效率,因为 Vue 不会花时间去解析这部分内容。
例如:
<div v-pre>
{{ 这是一段说明文字不需要解析 }}
<span v-bind:title="这个也不需要">也是</span>
</div>