Vue.js 使用了基于 HTML 的模板语法,允许开发者声明式地将 DOM 绑定至底层 Vue 实例的数据。所有 Vue.js 的模板都是合法的 HTML,所以能被遵循规范的浏览器和 HTML 解析器解析。
在底层的实现上,Vue 将模板编译成虚拟 DOM 渲染函数。结合响应系统,Vue 能够智能地计算出最少需要重新渲染多少组件,并把 DOM 操作次数减到最少。
使用Vue,为了简化理解,可以将Vue语法部分和模板引擎的语法作比较一同学习,可以增强理解
在使用vue之前,通过一个小实例看vue的实例的创建
DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="https://cdn.jsdelivr.net/npm/[email protected]">script>
head>
<body>
<div id="app">
<h3>{{ hello }}h3> //显示hello的数据
div>
<script type="text/javascript">
var app = new Vue({
el: '#app',
data: {
hello: 'hello,Vue!'
}
})
script>
body>
html>
新建一个Vue对象,赋值给变量app,将标签元素用Vue对象中的el属性绑定在一起,然后在div标签内就可以使用Vue对象中的内容了。
v-text
除了使用{{ }}
的方式来绑定文本,我们还可以使用v-text的方式来绑定文本属性,两者各有优势。但在组件中,使用v-text将会给我们字符串拼接造成巨大麻烦
<div id="app">
<h3 v-text="hello">你好h3> //覆盖原来的内容,显示hello,Vue!
div>
<script type="text/javascript">
var app = new Vue({
el: '#app',
data: {
hello: 'hello,Vue!'
}
})
script>
通过这样的一个方式,实现了之前直接使用{{}}
来对数据进行渲染的方式。
补充:如果有只需要渲染一次的属性,可以使用v-once
。
它将不会随着的变化而变化,但是需要注意它可能对其他数据绑定的影响。
v-html
如果有html属性的值,比如一段百度富文本编辑器的内容项,我们希望直接解析后在绑定后不被解析成文本而是html。
使用v-html
将可以实现这一效果
<div id="app">
<h3 v-text="hello">h3> //html标签也被展示
<h3 v-html="hello">h3>
div>
<script type="text/javascript">
var app = new Vue({
el: '#app',
data: {
hello: '你好鸭>'
}
})
script>
v-bind
:
标签的文本值也是标签属性值的一种,但是使用除了文本值得其他属性时,如class,type,id,disabled等等,可以使用v-bind
来实现值的绑定。
DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="https://cdn.jsdelivr.net/npm/[email protected]">script>
<style>
.myHello{
background-color: #008000; //背景色为绿色
}
style>
head>
<body>
<div id="app">
<h3 v-bind:class="myClass">helloh3> //绑定属性值
div>
<script type="text/javascript">
var app = new Vue({
el: '#app',
data: {
myClass: 'myHello'
}
})
script>
body>
html>
当标签的属性值有多个时,class属性需要使用[]
包裹。而style用{}
包裹
DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="https://cdn.jsdelivr.net/npm/[email protected]">script>
<style>
.myHello{
background-color: #008000; //背景色为绿色
}
.myHello2{
font-size: 50px;
}
style>
head>
<body>
<div id="app">
<h3 v-bind:class="[myHello, myHello2]">helloh3>
<h3 v-bind:style="{fontSize: fonts,color: colors}">helloh3>
<h3 v-bind:style="style1">helloh3>
div>
<script type="text/javascript">
var app = new Vue({
el: '#app',
data: {
myHello: 'myHello',
myHello2: 'myHello2',
fonts: '12px',
colors: 'red',
style1: {
fontSize: '20px',
color: 'yellow'
}
}
})
script>
body>
html>
v-on
@
和原生js中绑定事件一样,v-on
提供也是为标签绑定事件。
Vue对象中有一个methods属性,里面可以定义函数,调用这个函数中就可以修改Vue对象中的data值。
<div id="app">
<button v-on:click="add()">+button> //绑定事件
<h3 v-text="number">h3>
<button v-on:click="sub()">-button>
div>
<script type="text/javascript">
var app = new Vue({
el: '#app',
data: {
number: 12
},
methods: {
add(){
this.number++; //加一,通过this指针才可以调用data的属性值。
},
sub(){
this.number--; //减一
}
}
})
script>
当然,在标签中也可以直接使用
<div id="app">
<button v-on:click="number++">+button>
<h3 v-text="number">h3>
<button v-on:click="number--">-button>
div>
<script type="text/javascript">
var app = new Vue({
el: '#app',
data: {
number: 12
}
})
script>
v-if
分支结构不止有v-if
,还有其他几种
v-if
:if是否成立v-else
:else不成立时v-else-if
:elseif如果不成立时如果v-show
:if如果<div id="app">
<div v-if="score==100">
<a>恭喜你,满分了a>
div>
<div v-else-if="score>=80">
<a>恭喜你,本次结果优秀a>
div>
<div v-else-if="score>=60">
<a>及格啦a>
div>
<div v-else>
<a>很遗憾,下次再试a>
div>
<div v-show="flag">gogogodiv>
div>
<script type="text/javascript">
var app = new Vue({
el: '#app',
data: {
score: 100,
flag: true
}
})
script>
使用方式和java语言的分支结构使用相同
v-show和v-if的异同
v-for
<div id="app">
<ul>
<li v-for="item in habbit" v-text="item">li>
ul>
<ul>
<li v-for="(item,index) in habbit">
<span v-text="index">span>
<span v-text="item">span>
li>
ul>
<div v-for="(value,key,index) in user">
<span v-text="key">span>
<span v-text="value">span>
<span v-text="index">span>
div>
<ul>
<li v-for="item in petlist">
<span v-text="item.name">span>
<span v-text="item.type">span>
li>
ul>
div>
<script type="text/javascript">
var app = new Vue({
el: '#app',
data: {
habbit: ['唱歌', '跳舞', '打豆豆'],
user: {
name: '张三',
age: '19',
addr: '江西赣州'
},
petlist: [{
type: 'cat',
name: 'citty'
},
{
type: 'dog',
name: 'dd'
},
]
}
})
script>
v-model
<div id="app">
<input type="number" v-model="number"/> //下面的值随着上面的值改变
<a v-text="number">a>
div>
<script type="text/javascript">
var app = new Vue({
el: '#app',
data: {
number: 0
}
})
script>
当需要操作数组时,Vue提供了一些方法,让我们不用基于字符层次上进行操作
Vue 将被侦听的数组的变更方法进行了包裹,所以它们也将会触发视图更新。这些被包裹过的方法包括:
push()
在最后一个元素追加pop()
删除最后一个元素shift()
删除第一个元素unshift()
在开头追加一个元素splice()
在指定位置替换元素sort()
排序reverse()
反转替换数组: filter()
、concat()
和 slice()
。它们不会变更原始数组,而总是返回一个新数组。当使用非变更方法时,可以用新数组替换旧数组:
example1.items = example1.items.filter(function (item) {
return item.message.match(/Foo/)
})
绑定事件的几种方式
直接在标签中操作属性的改变
<div id="app">
<a v-text="number">a><br>
<button v-on:click="number++">加一button>
div>
<script type="text/javascript">
var app = new Vue({
el: '#app',
data: {
number: 0
},
methods: {
add(){
this.number++
}
}
})
script>
绑定事件方法
<div id="app">
<a v-text="number">a><br>
<button v-on:click="add()">加一button>
<button v-on:click="add1">加一button>
<button v-on:click="add2('hello')">加一button>
div>
<script type="text/javascript">
var app = new Vue({
el: '#app',
data: {
number: 0
},
methods: {
add(){ //简化写法
this.number++
},
add1: function(event){ //event可以不定义,是原生的decument
this.number++;
window.alert("增加一");
if(event){
alert(event.target.tagName)
}
},
add2: function(message){ //传递参数
window.alert(message);
}
}
})
script>
在事件处理程序中调用 event.preventDefault()
或 event.stopPropagation()
是非常常见的需求。
为了简化操作document的事件细节,vue将其提取为单纯的数据逻辑,使用事件修饰符可以实现这一功能。
.stop
阻止冒泡.prevent
阻止默认行为.capture
.self
.once
.passive
<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>
<div v-on:click.self="doThat">...div>
<a v-on:click.once="doThis">a>
使用修饰符时,顺序很重要;相应的代码会以同样的顺序产生。因此,用 v-on:click.prevent.self
会阻止所有的点击,而 v-on:click.self.prevent
只会阻止对元素自身的点击。
当摁下键盘时,如何判断摁下的时哪个键呢?在原生js中,使用keyCode值来判断不同的键,而在vue中,可以用按键修饰符来判断。有两种形式,一种用名字修饰
,一种用键值修饰
。
<div id="app">
<div>
<input name="username" type="text" @keyup.enter="handler()" value="回车触发" />
<input name="username" type="text" @keyup.space="handler()" value="空格触发" />
<input name="username" type="text" @keyup.left="handler()" value="<-触发" />
<input name="username" type="text" @keyup.right="handler()" value="->键触发" />
<input name="username" type="text" @keyup.13="handler()" value="回车触发" />
<input name="username" type="text" @keyup.38="handler()" value="向上键触发" />
<input name="username" type="text" @keyup.40="handler()" value="向下触发" />
div>
div>
<script type="text/javascript">
var app = new Vue({
el: '#app',
methods: {
handler(){
window.alert("我很被动")
}
}
})
script>
文本
<div id="app">
<input type="text" v-model="message"/>
message: <a v-text="message">a>
div>
<script type="text/javascript">
var app = new Vue({
el: '#app',
data: {
message: null
}
})
script>
多行文本
<div id="app">
<textarea type="text" v-model="message">textarea>
message: <a v-text="message">a>
div>
<script type="text/javascript">
var app = new Vue({
el: '#app',
data: {
message: null
}
})
script>
单选按钮
<div id="app">
<input type="radio" value="男" id="one" v-model="picked">男
<input type="radio" value="女" id="zero" v-model="picked">女<br />
sex: <a v-text="picked">a>
div>
<script type="text/javascript">
var app = new Vue({
el: '#app',
data: {
picked: ''
}
})
script>
复选框
单个复选框
<div id="app">
<input type="checkbox" v-model="picked">开启
sex: <a v-text="picked">a>
div>
<script type="text/javascript">
var app = new Vue({
el: '#app',
data: {
picked: false
}
})
script>
复选框
<div id="app">
<input type="checkbox" value="唱歌" v-model="array">唱歌
<input type="checkbox" value="跳舞" v-model="array">跳舞
<input type="checkbox" value="打豆豆" v-model="array">打豆豆<br/>
sex: <a v-text="array">a>
div>
<script type="text/javascript">
var app = new Vue({
el: '#app',
data: {
array: []
}
})
script>
下拉框
<div id="app">
<select v-model="selected">
<option disabled value="">请选择option>
<option value="S">Aoption>
<option>Boption>
<option>Coption>
select><br/>
<a v-text="selected">a>
div>
<script type="text/javascript">
var app = new Vue({
el: '#app',
data: {
selected: ''
}
})
script>
.lazy
在默认情况下,v-model
在每次 input
事件触发后将输入框的值与数据进行同步,可以添加 lazy
修饰符,从而转为在 change
事件_之后_进行同步:
<input v-model.lazy="msg">
.number
如果想自动将用户的输入值转为数值类型,可以给 v-model
添加 number
修饰符:
<input v-model.number="age" type="number">
.trim
如果要自动过滤用户输入的首尾空白字符,可以给 v-model
添加 trim
修饰符:
<input v-model.trim="msg">
为了简化理解程度,对于数据的处理一般都是封装在方法中处理后再回显,比如
<div id="app">
<input v-model="message">input><br/>
<p v-text="reversed()">p>
div>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
message: 'hello',
res: ''
},
methods: {
reversed: function(){
return this.message.split('').reverse().join('')
}
}
})
script>
但是,计算属性和方法的一个重要的区别是计算属性有缓存,计算属性是基于它们的响应式依赖进行缓存的。
当我们需要每次调用方法时,不管属性是否发生变化,都会重新计算执行一次。
当时每次调用计算属性,只要属性没有发生改变,它就不会去重新执行,而是使用缓存。
所以出现大数量的计算
时,我们应该使用计算属性进行,这样可以极大提高效率。
<div id="app">
<input v-model="message">input><br/>
<p v-text="reversedMessage()">p>
div>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
message: 'hello'
},
computed: {
// 计算属性的 getter
reversedMessage: function () {
// `this` 指向 vm 实例
return this.message.split('').reverse().join('')
}
}
})
script>
侦听器可以实时的监听数据的变化,当数据变化时,立刻执行侦听器,并且它是异步执行的。
<div id="app">
<input v-model="message">input><br/>
<p v-text="'传入的值为'+tip">p>
div>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
message: 'hello',
tip: ''
},
watch: {
//一个参数时为改变后的值,两个参数时前面那个为改变前的值,后面那个为改变后的值。
'message': function(val){
this.tip=val
}
}
})
script>
乍一看,和计算属性没什么区别,但是侦听器它是发生更改立马响应的,我们可以利用这个特性做许多功能,比如:输入值后自动执行调用某些方法,执行某些复杂的操作。特色在于侦听和异步。
类似于一些工具函数,我们可以在方法中将数据处理好再放上,但是Vue提供了一种更加整洁高效的形式,它可以避免方法的一些额外开销。
<div id="app">
<input v-model="message">input><br/>
<p>{{message | add}}p>
div>
<script type="text/javascript">
Vue.filter('add',(val)=>{ //添加过滤规则
return val+'123'
})
var vm = new Vue({
el: '#app',
data: {
message: 'hello'
}
})
script>