数据变化会自动更新到对应元素中,无需手动操作 DOM,这种行为称作单向数据绑定。
对于输入框等可输入元素,可设置双向数据绑定。双向数据绑定是在数据绑定基础上,可自动将元素输入内容更新给数据,实现数据与元素内容的双向绑定。
Vue.js 的数据驱动视图是基于 MVVM 模型实现的。
MVVM (Model – View – ViewModel )是一种软件开发思想。其中:
• Model 层,代表数据
• View 层, 代表视图模板
• ViewModel 层,代表业务逻辑处理代码
优点:基于MVVM 模型实现的数据驱动视图解放了DOM操作,View 与 Model 处理分离,降低代码耦合度。
缺点:但双向绑定时的 Bug 调试难度增大,大型项目的 View 与 Model 过多,维护成本高。
组件化开发,允许我们将网页功能封装为自定义 HTML 标签,复用时书写自定义标签名即可。
组件不仅可以封装结构,还可以封装样式与逻辑代码,大大提交了开发效率与可维护性。
分为三种方式,本地引入、 cdn 引入和 npm 安装。
本地引入:
• 开发版本:https://cn.vuejs.org/js/vue.js
• 生产版本:https://cn.vuejs.org/js/vue.min.js
cdn 引入:
• 最新稳定版: https://cdn.jsdelivr.net/npm/vue
• 指定版本:https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js
npm 安装:
• 最新稳定版: npm install vue
• 指定版本: npm install [email protected]
Vue 实例是通过 Vue 函数创建的对象,是使用 Vue 功能的基础。
var vm = new Vue ({
// 选项对象
});
用于选取一个 DOM 元素作为 Vue 实例的挂载目标。只有挂载元素内部才会被 Vue 进行处理,外部为普通 HTML 元素。el 选项代表 MVVM 中的 View 层(视图)。
可以为 CSS 选择器格式的字符串 或 HTMLElement 实例,但不能为 html 或 body。挂载完毕后,可以通过 vm.$el 进行访问。
写法:
var vm = new Vue({
el: '#app'
});
console.log(vm.$el);
var app = document.querySelector('#app');
var vm = new Vue({
el: app
});
console.log(vm.$el);
未设置 el 的 vue 实例,也可以通过 vm.$mount() 进行挂载,参数形式与 el 规则相同。
var vm = new Vue({});
vm.$mount('#app');
或
var app = document.getElementById('app');
var vm = new Vue({});
vm.$mount(app);
console.log(vm.$el);
挂载元素可以使用 Vue.js 的模板语法,模板中可以通过插值表达式为元素进行动态内容设置,写法为 {{ }}。
<div id="app">
<ul>
<li>第一段示例内容:{{ 10 + 20 + 30 }}li>
<li>第二段示例内容:{{ 22 > 3 ? '22比3大' : '3比22大' }}li>
ul>
div>
注意点:
• 插值表达式只能书写在标签内容区域。
• 内部只能书写 JavaScript 表达式,不能书写语句。
用于存储 Vue 实例需要使用的数据,值为对象类型。data 中的数据可以通过 vm.$data.数据 或 vm.数据 访问。
语法示例:
var vm = new Vue ({
el: '#app',
data: {
title: '标题文本'
}
});
console.log(vm.$data.title);
console.log(vm.title); // 更常用
data 中的数据可以直接在视图中通过插值表达式访问。
代码示例:
<div id="app">
<p>{{ title }}p>
div>
var vm = new Vue ({
el: '#app',
data: {
title: '标题文本'
}
});
data 中的数据为响应式数据,在发生改变时,视图会自动更新。
代码示例: 在控制台输入 vm.title = ‘新的标题文本’,结果如下图
data 中存在数组时,索引操作与 length 操作无法自动更新视图,这时可以借助 Vue.set() 方法替代操作。
代码示例: 更新数组中的第一个字符串内容
<div id="app">
<ul>
<li>{{ arr[0] }}li>
<li>{{ arr[1] }}li>
<li>{{ arr[2] }}li>
ul>
div>
<script src="lib/vue.js">script>
<script>
var vm = new Vue({
el: '#app',
data: {
arr: ['内容1', '内容2', '内容3']
}
});
script>
使用Vue.set() 方法进行更新操作:
Vue.set(vm.arr,0,‘生效的新内容’);
用于存储需要在 Vue 实例中使用的函数。
代码示例:
<div id="app">
<p>{{ fn(title1) }}p>
<p>{{ fn(title2) }}p>
div>
<script src="lib/vue.js">script>
<script>
var vm = new Vue({
el: '#app',
data: {
prefix: '处理的结果为:',
title1: 'a-b-c-d-e',
title2: 'x-y-z'
},
methods: {
fn (value) {
return value.split('-').join('');
}
}
});
script>
methods 中的方法可以通过 vm.方法名 访问。方法中的 this 为 vm 实例,可以便捷的访问 vm 数据等功能。
代码示例:
<div id="app">
<p>{{ fn(title1) }}p>
<p>{{ fn(title2) }}p>
div>
<script src="lib/vue.js">script>
<script>
var vm = new Vue({
el: '#app',
data: {
prefix: '处理的结果为:',
title1: 'a-b-c-d-e',
title2: 'x-y-z'
},
methods: {
fn (value) {
this.fn1(); //this指向vm实例,使用this替代vm
this.fn2();
return this.prefix + value.split('-').join('');
},
fn1 () {
console.log('执行了 fn1 的代码');
},
fn2 () {
console.log('执行了 fn2 的代码');
}
}
});
script>
指令的本质就是 HTML 自定义属性,Vue.js 的指令就是以 v- 开头的自定义属性。以下列举一些常用的指令。
使元素内部的插值表达式只生效一次。
代码示例:
<div id="app">
<p>此内容会随数据变化而自动变化:{{ content }}p>
<p v-once>此内容不会随数据变化而自动变化: {{ content }}p>
div>
<script src="lib/vue.js">script>
<script>
var vm = new Vue({
el: '#app',
data: {
content: '内容文本'
}
})
script>
在控制台输入 vm.content = ‘新的内容文本’;
只有第一段内容发生变化,而第二段内容未改变。
元素内容整体替换为指定纯文本数据。
代码示例:
<div id="app">
<p v-text="100">这是 p 标签的原始内容p>
<p v-text="content">这是 p 标签的原始内容p>
<p v-text="content2">p>
div>
<script src="lib/vue.js">script>
<script>
var vm = new Vue({
el: '#app',
data: {
content: '内容文本',
content2: 'span的内容'
}
});
script>
元素内容整体替换为指定的 HTML 文本。
代码示例:
<div id="app">
<p v-html="content">这是默认的文本内容p>
div>
<script src="lib/vue.js">script>
<script>
var vm = new Vue({
el: '#app',
data: {
content: 'span的内容'
}
});
script>
v-bind 指令用于动态绑定 HTML 属性。
代码示例:
<div id="app">
<p v-bind:title="myTitle">p标签的内容p>
div>
<script src="lib/vue.js">script>
<script>
var vm = new Vue({
el: '#app',
data: {
myTitle: '这是title的内容'
}
});
script>
简写方式:
<div id="app">
<p :title="myTitle">p标签的内容p>
div>
<body>
<div id="app">
<p v-bind="attrObj">这是 p 标签的内容p>
div>
<script src="lib/vue.js">script>
<script>
var vm = new Vue({
el: '#app',
data: {
attrObj: {
id: 'box',
title: '示例内容',
class: 'clearFix',
'data-title': '这是 data-title 的内容'
}
}
});
script>
控制台中查看元素属性:
2. 与插值表达式类似,v-bind 中也允许使用表达式。
代码示例:
<div id="app">
<p :title="myTitle">p标签的内容p>
<p :class="prefix + num">p>
div>
<script src="lib/vue.js">script>
<script>
var vm = new Vue({
el: '#app',
data: {
myTitle: '这是title的内容',
prefix: 'demo',
num: 10
}
});
script>
class 是 HTML 属性,可以通过 v-bind 进行绑定,并且可以与class 属性共存。
代码示例:
<div id = "app">
<p v-bind:class = "cls">标签内容p>
<p class="a" :class = "cls">标签内容p>
div>
<script src="lib/vue.js">script>
<script>
var vm = new Vue({
el: '#app',
data: {
cls: 'x'
}
});
script>
对于 class 绑定, Vue.js 中还提供了特殊处理方式。
代码示例: 多个类名,判断类名是否生效的设置,两种写法:对象写法和数组写法
对象写法:
<div id="app">
<p :class="{ x: isX, y: false, z: true }">p>
div>
<script src="lib/vue.js">script>
<script>
var vm = new Vue({
el: '#app',
data: {
classB: 'b',
isC: true,
isX: true
}
});
script>
<p :class="['a', classB, {c: isC}]">p>
<div id="app">
<p :class="bool ? cls1 : cls2">p>
div>
<script src="lib/vue.js">script>
<script>
var vm = new Vue({
el: '#app',
data: {
bool: true,
cls1: 'x',
cls2: 'y'
}
});
script>
style 是 HTML 属性,可以通过 v-bind 进行绑定,并且可以与style 属性共存。
代码示例:
<div id="app">
<p style="width: 100px" :style="styleObj">p>
div>
<script src="lib/vue.js">script>
<script>
var vm = new Vue({
el: '#app',
data: {
styleObj: {
height: '200px',
backgroundColor: 'red',
'font-size': '30px'
}
}
});
script>
style属性名使用驼峰写法,如上述示例中的backgroundColor;也可以使用通过引号包裹的横线结构书写,例如示例中的 ‘font-size’: ‘30px’;
当我们希望给元素绑定多个样式对象时,可以设置为数组。
代码示例:
<div id="app">
<p :style="[baseStyle, styleObj1]">第一个 p 标签p>
<p :style="[baseStyle, styleObj2]">第二个 p 标签p>
div>
<script src="lib/vue.js">script>
<script>
var vm = new Vue({
el: '#app',
data: {
// 公共样式
baseStyle: {
width: '100px',
height: '100px'
},
styleObj1: {
backgroundColor: 'red'
},
styleObj2: {
backgroundColor: 'blue'
}
}
});
script>
用于遍历数据渲染结构,常用的数组与对象均可遍历。
代码示例:
操作数组:
<div id="app">
<ul>
<li v-for="item in arr">元素内容为:{{ item }}li>
ul>
div>
<script src="lib/vue.js">script>
<script>
new Vue({
el: '#app',
data: {
arr: ['内容1', '内容2', '内容3']
}
});
script>
操作对象:
<div id="app">
<ul>
<li v-for="value in obj">元素内容为:{{ value }}li>
ul>
div>
<script src="lib/vue.js">script>
<script>
new Vue({
el: '#app',
data: {
obj: {
content1: '内容1',
content2: '内容2',
content3: '内容3'
}
}
});
script>
使用 v-for 的同时,应始终指定唯一的 key 属性,可以提高渲染性能并避免问题。
<div id="app">
<ul>
<li v-for="(item, index) in itemList" :key="item.id">
输入框{{ item.value }}: <input type="text">
li>
ul>
div>
<script src="lib/vue.js">script>
<script>
var vm = new Vue({
el: '#app',
data: {
arr: [1, 2, 3],
itemList: [
{
id: 1,
value: 2
},
{
id: 2,
value:3
},
{
id:3,
value:3
}
]
}
})
script>
通过 标签设置模板占位符,可以将部分元素或内容作为整体进行操作。无需进行key属性设置。
<div id="app">
<template v-for="item in obj">
<span>{{ item }}span>
<br>
template>
div>
<script src="lib/vue.js">script>
<script>
var vm = new Vue({
el: '#app',
data: {
obj: {
content1: '内容1',
content2: '内容2',
content3: '内容3'
}
}
})
script>
用于控制元素显示与隐藏,适用于显示隐藏频繁切换时使用。
<div id="app">
<p v-show="ture">这个元素会显示p>
<p v-show="false">这个元素会显示隐藏p>
<p v-show="bool">标签内容p>
div>
<script src="lib/vue.js">script>
<script>
var vm = new Vue({
el: "#app",
data: {
bool: true
}
});
script>
注意: 无法使用 v-show 指令。
用于根据条件控制元素的创建与移除。
<div id="app">
<p v-if="bool">这是标签内容p>
<p v-else-if="false">这是第二个p标签,不会被创建p>
<p v-else-if="false">这是第三个p标签,不会被创建p>
<p v-else>最后一个p标签,会被创建p>
div>
<script src="lib/vue.js">script>
<script>
var vm = new Vue({
el: '#app',
data: {
bool: false
}
});
script>
给使用 v-if 的同类型元素绑定不同的key。
代码示例:
<div id="app">
<div v-if="type==='username'" :key="'username'">
用户名输入框:<input type="text">
div>
<div v-else :key="'email'">
邮箱输入框:<input type="text">
div>
div>
<script src="lib/vue.js">script>
<script>
var vm = new Vue({
el: '#app',
data: {
bool: true,
type: 'username'
}
});
script>
出于性能考虑,应避免将 v-if 与 v-for 应用于同一标签。
<div id="app">
<ul v-if="false">
<li v-for="item in items">{{item}}li>
ul>
div>
<script src="lib/vue.js">script>
<script>
var vm = new Vue({
el: '#app',
data: {
items: {
content1: '内容1',
content2: '内容2',
content3: '内容3'
}
}
});
script>
用于进行元素的事件绑定。
***代码示例:***添加点击按钮事件,将默认的内容替换成新的内容
<div id="app">
<p>{{ content }}p>
<button v-on:click="content='这是新的内容'">按钮button>
div>
<script src="lib/vue.js">script>
<script>
new Vue({
el: '#app',
data: {
content: '这是默认内容'
}
})
script>
简写方式:
<button @click="content='这是新的内容'">按钮button>
1、事件程序代码较多时,可以在 methods 中设置函数,并设置为事件处理程序。设置事件处理程序后,可以从参数中接收事件对象。
<div id="app">
<p>{{ content }}p>
<button @click="fn">按钮3button>
div>
<script src="lib/vue.js">script>
<script>
new Vue({
el: '#app',
data: {
content: '这是默认内容'
},
methods: {
fn(event) {
this.content = '这是按钮3设置的内容';
}
}
})
script>
2、在视图中可以通过 $event 访问事件对象。
<div id="app">
<p>{{ content }}p>
<button @click="fn2(200, $event)">按钮4button>
div>
<script src="lib/vue.js">script>
<script>
new Vue({
el: '#app',
data: {
content: '这是默认内容'
},
methods: {
fn2(value, event) {
console.log(value, event);
}
}
})
script>
用于给 、
输入框分为单行输入框 input 与多行输入框 textarea。
代码示例:
<div id="app">
<p>input 输入框的内容为: {{ value1 }}p>
<input type="text" v-model="value1">
<p>textarea 输入框的内容为: {{ value2 }}p>
<textarea v-model="value2">textarea>
div>
<script src="lib/vue.js">script>
<script>
var vm = new Vue({
el: '#app',
data: {
value1: '',
value2: ''
}
});
script>
单选按钮的双向数据绑定方式如下:
<div id="app">
<p>radio 的内容为: {{ value3 }}p>
<input type="radio" id="one" value="1" v-model="value3">
<label for="one">选项1label>
<input type="radio" id="two" value="2" v-model="value3">
<label for="two">选项2label>
div>
<script src="lib/vue.js">script>
<script>
var vm = new Vue({
el: '#app',
data: {
value3: ''
}
});
script>
复选框绑定分为单个选项与多个选项两种情况,书写方式不同。
<div id="app">
<p>单个复选框的值: {{ value4 }}p>
<input type="checkbox" value="选项内容" id="one" v-model="value4">
<label for="one">选项内容label>
<p>多个复选框的值:{{ value5 }}p>
<input type="checkbox" id="cb1" value="选项1" v-model="value5" >
<label for="cb1">选项1label>
<input type="checkbox" id="cb2" value="选项2" v-model="value5" >
<label for="cb2">选项2label>
<input type="checkbox" id="cb3" value="选项3" v-model="value5" >
<label for="cb3">选项3label>
div>
<script src="lib/vue.js">script>
<script>
var vm = new Vue({
el: '#app',
data: {
value4: '',
value5: []
}
});
script>
选择框绑定分为单选绑定与多选绑定两种情况,书写方式不同。
<div id="app">
<p>单选选择框的内容: {{ value6 }}p>
<select v-model="value6">
<option value="">请选择option>
<option value="1">选项1option>
<option value="2">选项2option>
<option value="3">选项3option>
select>
<p>多选选择框的内容:{{ value7 }}p>
<select v-model="value7" multiple>
<option value="1">选项1option>
<option value="2">选项2option>
<option value="3">选项3option>
select>
div>
<script src="lib/vue.js">script>
<script>
var vm = new Vue({
el: '#app',
data: {
value6: '',
value7: []
}
});
script>
• input 输入框:绑定字符串值。
• textarea 输入框:绑定字符串值。
• radio:绑定字符串值。
• checkbox:单个绑定布尔值,多个绑定数组。
• select:单选绑定字符串,多选绑定数组。
修饰符是以点开头的指令后缀,用于给当前指令设置特殊操作。以下列出一些常见的修饰符语法。
用于阻止默认事件行为,相当于 event.preventDefault()。
代码示例: 阻止a标签跳转
<div id="app">
<a @click.prevent href="https://kaiwu.lagou.com/">链接a>
div>
<script src="lib/vue.js">script>
<script>
new Vue({
el: '#app',
data: {
},
methods: {
fn() {
console.log('这是 a 标签的点击事件')
}
}
});
script>
用于阻止事件传播,相当于 event.stopPropagation()。
Vue.js 中允许修饰符进行连写,例如:@click.prevent.stop
代码示例: 阻止a的跳转,并且阻止事件冒泡,链式写法
<div id="app">
<div @click="fn1">
<a @click.prevent.stop="fn2" href="https://kaiwu.lagou.com/">链接a>
div>
div>
<script src="lib/vue.js">script>
<script>
new Vue({
el: '#app',
data: {
},
methods: {
fn1 () {
console.log('div 的点击事件');
},
fn2 () {
console.log('a 的点击事件');
}
}
})
script>
用于设置事件只会触发一次。
代码示例: 按钮2只会被触发一次
<div id="app">
<button @click="fn">按钮1button>
<button @click.once="fn">按钮2button>
div>
<script src="lib/vue.js">script>
<script>
new Vue({
el: '#app',
data: {
},
methods: {
fn () {
console.log('按钮被点击了');
}
}
})
script>
按键码指的是将按键的按键码作为修饰符使用以标识按键的操作方式。
特殊按键指的是键盘中类似 esc、enter、delete 等功能按键,为了更好的兼容性,应首选内置别名。
系统按键指的是 ctrl 、alt 、shift 等按键。系统按键通常与其他按键组合使用,单独点击系统操作符无效。
1、 .ctrl 修饰符
2、 .alt 修饰符
3、 .shift 修饰符
代码示例: 以ctrl修饰符为例,按 ctrl+q,清空输入框内容
<div id="app">
<input type="text" @keyup.ctrl.q="fn" v-model="inputValue">
div>
<script src="lib/vue.js">script>
<script>
new Vue({
el: '#app',
data: {
inputValue: ''
},
methods: {
fn (event) {
this.inputValue = '';
}
}
});
script>
另外两个修饰符类似使用方法。
鼠标按键修饰符用于设置点击事件由鼠标哪个按键来完成。分为 .left 修饰符、 .right 修饰符和 .middle 修饰符,写法与前面的修饰符写法类似。
1、.trim 修饰符
.trim 修饰符 用于自动过滤用户输入内容首尾两端的空格。
2、.lazy 修饰符
用于将 v-model 的触发方式由 input 事件触发更改为 change 事件触发。
代码示例:
<div id="app">
<input type="text" v-model.lazy="inputValue">
<p>{{ inputValue }}p>
div>
<script src="lib/vue.js">script>
<script>
var vm = new Vue({
el: '#app',
data: {
inputValue: ''
}
});
script>
每次输入框中输入内容后,需要在输入框外点一下,下面的内容才会相应的改变
3、.number 修饰符
用于自动将用户输入的值转换为数值类型,如无法被 parseFloat() 转换,则返回原始内容。