Vue
预热:
执行:npm install vue@2.6.10
命令安装 vue模块
<script src="./node_modules/vue/dist/vue.js"></script>
一、入门基础操作
1.模板数据绑定渲染
可生成动态的HTML页面,页面中使用嵌入 Vue.js 语法可动态生成
- {{xxxx}} 双大括号文本绑定
- v-xxxx 以 v- 开头用于标签属性绑定,称为指令
1.1 双大括号语法 {{ }}
格式:{{表达式}}
作用:
- 使用在标签体中,用于获取数据
- 可以使用 JavaScript 表达式
1.2 输出HTML指令 v-html
格式: v-html=‘xxxx’
作用:输出真正的 HTML
<body>
<div id="app">
<h3>1、双大括号输出文本内容</h3>
<!--文本内容-->
<p>普通文本:{{ message }}</p>
<!--使用JS表达式-->
<p>JS表达式:{{ number + 1 }}</p>
<h3>3、v-html 指令输出真正的 HTML 内容</h3>
<p>双大括号:{{ contentHtml }}</p>
<!-- 指令的值不需要使用双大括号获取,直接写获取的属性名 -->
<!-- <p>v-html指令:<span v-html="{{contentHtml}}"></span></p>-->
<p>v-html指令:<span v-html="contentHtml"></span></p>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
message: 'haha',
number: 1,
contentHtml: '<span style="color:red">红色字体内容> <script>alert("hello vue")<\/script></span>'
}
})
</script>
</body>
1.3 元素绑定指令 v-bind
完整格式: v-bind:元素的属性名=‘xxxx’
缩写格式: :元素的属性名=‘xxxx’
作用:将数据动态绑定到指定的元素上
1.4 事件绑定指令 v-on
完整格式: v-on:事件名称=“事件处理函数名”
缩写格式: @事件名称=“事件处理函数名” 注意: @ 后面没有冒号
作用:用于监听 DOM 事件
<body>
<div id="app">
<h3>4、v-bind 属性绑定指令</h3> <!-- 红色字体是正常的 -->
<img v-bind:src="imgUrl" alt="VueLogo">
<!-- 缩写 -->
<img :src="imgUrl" alt="VueLogo">
<h3>5、v-on 事件绑定指令</h3>
<input type="text" v-model="num">
<button v-on:click="add">点击+1</button>
<button @click="add">点击+1</button>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
message: 'haha',
number: 1,
contentHtml: '<span style="color:red">红色字体内容> <script>alert("hello vue")<\/script></span>',
imgUrl: 'https://cn.vuejs.org/images/logo.png',
num:0
},
methods: { //指定事件处理方法, 在模板页面中通过 v-on:事件名 来调用
add: function () { //key为方法名
console.log('add被调用')
// this 表示当前 vm 实例
this.num++ //每点击1次num加1
}
}
})
</script>
</body>
1.5 计算属性 computed
computed 选项定义计算属性
计算属性 类似于 methods 选项中定义的函数
- 计算属性 会进行缓存,只在相关响应式依赖发生改变时它们才会重新求值。
- 函数 每次都会执行函数体进行计算。
- 计算属性默认只有 getter ,不过在需要时你也可以提供一个 setter
1.6 监听器 watch
当属性数据发生变化时,对应属性的回调函数会自动调用, 在函数内部进行计算
通过 watch 选项 或者 vm 实例的 $watch() 来监听指定的属性
<body>
<div id="app">
数学:<input type="text" v-model="mathScore"><br>
英语:<input type="text" v-model="englishScore"><br>
总分(方法-单向):<input type="text" v-model="sumScore()"><br>
总分(计算属性-单向):<input type="text" v-model="sumScore1"><br>
总分(计算属性-双向):<input type="text" v-model="sumScore2"><br>
总分(监听器):<input type="text" v-model="sumScore3"><br>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
mathScore: 80,
englishScore: 90,
sumScore3: 170
},
methods: {
//不要少了s
sumScore: function () {
//在控制台输入 vm.sumScore() 每次都会被调用
console.info('sumScore被调用')
// `this` 指向当前 vm 实例, 减 0 是为了字符串转为数字运算
return (this.mathScore - 0) + (this.englishScore - 0)
}
},
computed: {
//计算属性
sumScore1: function () {
//在控制台输入vm.sumScore1 不会被重新调用,说明计算属性有缓存
console.info('sumScore1被调用')
return (this.mathScore - 0) + (this.englishScore - 0)
},
//指定 getter/setter 双向绑定
sumScore2: {
get: function () {
console.info('sumScore2被调用')
return (this.mathScore - 0) + (this.englishScore - 0)
},
set: function (newValue) {
//value为更新后的值
// 被调用则更新了sumScore2,然后将数学和英语更新为平均分
var avgScore = newValue / 2
this.mathScore = avgScore
this.englishScore = avgScore
}
},
},
//监听器方式1:watch选项
watch : {
//当数学修改后,更新总分sumScore3
mathScore : function (newValue, oldValue) {
//newValue 就是新输入的数学得分
this.sumScore3 = (newValue-0) + (this.englishScore-0)
}
}
})
//监听器方式2:通过vm对象调用
//第1个参数为监听的属性名,第2个回调函数
vm.$watch('englishScore', function (newValue) { //newValue 就是新输入的英语得分
this.sumScore3 = (newValue-0) + (this.mathScore-0)
})
</script>
</body>
1.7 Class 与 Style 绑定 v-bind
v-bind:class=‘表达式’ 或 :class=‘表达式’
class 的表达式可以为:
- 字符串 :class=“activeClass”
- 对象 :class="{active: isActive, error: hasError}"
- 数组 :class="[‘active’, ‘error’]" 注意要加上单引号,不然是获取data中的值
v-bind:style=‘表达式’ 或 :style=‘表达式’
style 的表达式一般为对象
- :style="{color: activeColor, fontSize: fontSize + ‘px’}"
- 注意:对象中的value值 activeColor 和 fontSize 是data中的属性
<body>
<!-- 第2步:定义样式 -->
<style>
.active {
color: green;
}
.delete {
background: red;
}
.error {
font-size: 30px;
}
</style>
<div id="app">
<h2>Class绑定,v-bind:class 或 :class</h2>
<!--activeClass会从data中获取值为active,则对应样式为绿色-->
<p v-bind:class="activeClass">字符串达式</p>
<!-- isDelete为 true,渲染delete样式;当 hasError为false,不取 error 样式;-->
<p :class="{delete: isDelete, error: hasError}">对象表达式</p>
<!--- 渲染 'active', 'error' 样式,注意要加上单引号,不然是获取data中的值 -->
<p :class="['active', 'error']">数组表达式</p>
<h2>Style绑定, v-bind:style 或 :style</h2>
<p :style="{color: activeColor, fontSize: fontSize + 'px'}">Style绑定</p>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script type="text/javascript">
new Vue({
el: '#app',
data: {
activeClass: 'active',
isDelete: true,
hasError: false, //演示 Style 绑定
activeColor: 'red',
fontSize: 20
}
})
</script>
</body>
1.8 条件渲染 v-if
- v-if 是否渲染当前元素
- v-else
- v-else-if
- v-show 与 v-if 类似,只是元素始终会被渲染并保留在 DOM 中,只是简单切换元素的 CSS 属性 display 来显示或隐藏
<body>
<style>
.box {
width: 200px;
height: 200px;
background: red;
}
</style>
<div id="app">
<h2>v-if 条件渲染</h2>
<input v-model="seen" type="checkbox">勾选后显示红色小块
<!-- v-if 为 true则显示渲染当前元素, -->
<div v-if="seen" class="box"></div>
<p v-else="seen">红块已隐藏</p>
<h2>v-show 条件渲染</h2>
<!-- v-show 的元素始终会被渲染并保留在 DOM 中,只是简单切换元素的 CSS 属性 display 显示隐藏,而不是重新加载div-->
<div v-show="seen" class="box"></div>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: { seen: false }
})
</script>
</body>
1.9 列表渲染 v-for
1.v-for 迭代数组
语法: v-for="(alias, index) in array"
说明: alias : 数组元素迭代的别名; index : 数组索引值从0开始(可选) 。
2. v-for 迭代对象的属性
语法: v-for="(value, key, index) in Object"
说明: value : 每个对象的属性值; key : 属性名(可选); index : 索引值(可选) 。
<body>
<div id="app">
<h2>1. 迭代数组</h2>
<ul>
<!-- e 为当前对象别名,index 数组下标0开始-->
<!-- 使用 `key` 特殊属性, 它会基于 key 的变化重新排列元素顺序,并且会移除 key 不存在的元素 -->
<li v-for="(e, index) in emps" :key="index">
编号:{{index+1}},姓名:{{e.name}},工资:{{e.salary}} </li>
</ul> <br>
<h2>2. 迭代对象</h2>
<ul>
<!-- value是属性值,key是属性名,index索引值-->
<li v-for="(value, key, index) in emps[0]">
第{{index+1}}个属性为:{{key}} = {{value}}
</li>
</ul>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
emps: [ //数组
{name: '马云', salary: '20000'},
{name: '马化腾', salary: '18000'},
{name: '刘强东', salary: '13000'}
] }
})
</script>
</body>
1.10 事件处理
1.事件处理方法
完整格式: v-on:事件名=“函数名” 或 v-on:事件名=“函数名(参数……)”
缩写格式: @事件名=“函数名” 或 @事件名=“函数名(参数……)” 注意: @ 后面没有冒号 @blur(失焦)
- event :函数中的默认形参,代表原生 DOM 事件
- 当调用的函数,有多个参数传入时,需要使用原生DOM事件,则通过 $event 作为实参传入
作用:用于监听 DOM 事件
2.事件修饰符
事件修饰符
- .stop 阻止单击事件继续传播 event.stopPropagation()
- .prevent 阻止事件默认行为 event.preventDefault()
- .once 点击事件将只会触发一次
3.按键修饰符
格式: v-on:keyup.按键名 或 @keyup.按键名
常用按键名:
.enter .tab .delete (捕获“删除”和“退格”键) .esc .space .up .down .left .right
<body>
<div id="app">
<h2>1. 事件处理方法</h2>
<button v-on:click="say">Say {{msg}}</button>
<button @click="warn('hello', $event)">Warn</button> <br>
<h2>2. 事件修饰符</h2>
单击事件继续传播
<div @click="todo">
<!--点击后会调用doThis再调用todo-->
<button @click="doThis">单击事件会继续传播</button>
</div> <br/>
<!-- 阻止单击事件继续传播,-->
<div @click="todo">
<!--点击后只调用doThis-->
<button @click.stop="doThis">阻止单击事件会继续传播</button>
</div> <br>
<!-- 阻止事件默认行为 -->
<a href="http://www.mengxuegu.com" @click.prevent="doStop">梦学谷官网</a>
<br><br>
<!-- 点击事件将只会触发一次 -->
<button @click.once="doOnly">点击事件将只会触发一次: {{num}}</button>
<h2>3. 按键修饰符</h2>
<input @keyup.enter="keyEnter">
<!--进入输入框按回车时调用keyEnter-->
<input @keyup.space="keySpace">
<!--进入输入框按空格时调用keySpace-->
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: { msg: 'Hello, Vue.js', num: 1 },
methods: {
say: function (event) {
// `this` 在方法里指向当前 Vue 实例
alert(this.msg)
// `event` 是原生 DOM 事件
alert(event.target.innerHTML)
},//多个参数如果需要使用原生事件,将 $event 作为实参传入
warn: function (msg, event) {
alert(msg + "," + event.target.tagName)
},
todo: function () {
alert("todo....");
},
doThis: function () {
alert("doThis....");
},
doStop: function () {
alert("href默认跳转被阻止....")
},
doOnly: function () {
this.num++
},
keyEnter: function () {
alert("已按:回车键")
},
keySpace: function () {
alert("已按:空格键")
}
}
})
</script>
</body>
1.11 表单数据双向绑定v-model
- 单向绑定:数据变,视图变;视图变(浏览器控制台上更新html),数据不变;上面的都是单向绑定
- 双向绑定:数据变,视图变;视图变(在输入框更新),数据变;
<body>
<div id="demo">
<!-- @submit.prevent 阻止事件的默认行为,当前阻止的是action行为 -->
<form action="#" @submit.prevent="submitForm">
姓名(文本):<input type="text" v-model="name">
<br><br>
性别(单选按钮):
<input name="sex" type="radio" value="1" v-model="sex" />男
<input name="sex" type="radio" value="0" v-model="sex" />女
<br><br>
技能(多选框):
<input type="checkbox" name="skills" value="java" v-model="skills">Java开发
<input type="checkbox" name="skills" value="vue" v-model="skills">Vue.js开发
<input type="checkbox" name="skills" value="python" v-model="skills">Python开发
<br><br>
城市(下拉框):
<select name="citys" v-model="city">
<option v-for="c in citys" :value="c.code">
{{c.name}}
</option>
</select>
<br><br>
说明(多行文本):<textarea cols="30" rows="5" v-model="desc"></textarea>
<br><br>
<button type="submit">提交</button>
</form>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
new Vue({
el: '#demo',
data: {
name: '',
sex: '1', //默认选中的是 男
skills: ['vue', 'python'], //默认选中 Vue.js开发 、Python开发
citys: [
{ code: 'bj', name: '北京' },
{ code: 'sh', name: '上海' },
{ code: 'gz', name: '广州' }
],
city: 'sh', // 默认选中的城市:上海
desc: ''
},
methods: {
submitForm: function () { //处理提交表单
//发送ajax异步处理
alert(this.name + ', ' + this.sex + ', ' + this.skills + ', ' + this.city + ', ' + this.desc)
}
}
})
</script>
</body>