vue的安装
CDN引入
开发环境版本,包含了有帮助的命令行警告
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
生产环境版本,优化了尺寸和速度
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
方式二:下载和引入
开发版本:https://cn.vuejs.org/js/vue.js
生产版本:https://cn.vuejs.org/js/vue.min.js方式三:NPM安装
$ npm install vue
-
vue实例传入的options
el:
类型:string | HTMLElement
作用:决定之后Vue实例会管理哪一个DOM
data:
类型:Object | Function(组件中data必须是一个函数)
作用:Vue实例对应的数据对象
methods:
类型:{[key:string]:Function}
作用:定义属于Vue的一些方法,可以在其他地方调用,也可以在指令中使用
数据传递
-
数据的单向传递
把数据交给vue实例对象,实例对象将数据交给界面
<div id="box1">
{{ message }}
<p></p>
</div>
<script>
// 创建一个vue实例
let box = new Vue({
// vue作用域
el: "#box1",
// 作用域的数据
data: {
message: "Hello Vue"
}
})
</script>
常用指令
-
v-once
只渲染元素和组件一次。随后的重新渲染,元素/组件及其所有的子节点将被视为静态内容并跳过。这可以用于优化更新性能。
<div id="box1">
<p v-once>原始数据:{{ message1 }}</p>
<p>当前数据:{{ message1 }}</p>
</div>
<script>
let vue1 = new Vue({
el: "#box1",
data: {
message1: "test111"
}
})
// 原始数据不会变化
vue1.message1 = '6666666'
</script>
-
v-html
更新元素的 innerHTML。注意:内容按普通 HTML 插入 - 不会作为 Vue 模板进行编译。
会按照html格式进行解析。
<div id="app">
<h2 v-html="url"></h2>
</div>
<script>
let app = new Vue({
el: "#app",
data: {
url: "<a href='https://www.baidu.com'>百度一下</a>"
}
})
-
v-text
更新元素的 textContent。如果要更新部分的 textContent,需要使用 {{ Mustache }} 插值。很少用
<div id="app">
<h2>{{message}}</h2>
<h2 v-text="message"></h2>
</div>
<script>
// 更新元素的 textContent。如果要更新部分的 textContent,需要使用 {{ Mustache }} 插值。
let app = new Vue({
el: "#app",
data: {
message: "hello"
}
})
</script>
-
v-pre
跳过这个元素和它的子元素的编译过程。可以用来显示原始 Mustache 标签。跳过大量没有指令的节点会加快编译。
<div id="app">
<h2>{{message}}</h2>
<h2 v-pre>{{message}}</h2>
</div>
<script>
// 第一个h2标签,显示hello
// 第二个h2标签,显示{{message}}
let app = new Vue({
el: "#app",
data: {
message: "hello"
}
})
</script>
-
v-cloak
某些情况,浏览器可能会直接显示未编译Mustache标签,可以使用 v-cloak 指令来解决这一问题。需要配合css使用。
这个指令保持在元素上直到关联实例结束编译。和 CSS 规则如 [v-cloak] { display: none } 一起用时,这个指令可以隐藏未编译的 Mustache 标签直到实例准备完毕。
<style type="text/css">
<!-- 属性选择器-->
[v-cloak] {
display: none;
}
</style>
<div id="box2">
<p v-cloak>{{ message2 }}</p>
</div>
<script>
let vue2 = new Vue({
el: "#box2",
data: {
message2: "test clock"
}
})
-
v-bind
想要给元素绑定数据,可以使用{{}} v-text v-html,
如果想给元素的属性绑定数据,只能使用v-bind。
v-bind:属性名称="绑定的数据"
:属性名称="绑定的数据"
赋值的数据可以是任意合法的js表达式。
- 绑定属性
<div id="box2">
<input type="text" v-bind:value="name">
<input type="text" :value="age">
<input type="text" :value="age + 1">
</div>
<script>
let vue2 = new Vue({
el: '#box2',
data: {
name: '我是v-bind',
age: 18
}
})
</script>
- 绑定类名
v-bind绑定class注意事项:
(1) 类名要放到{}或[]中;
(2) 类名要加引号;
(3) 绑定类名时,可以使用三目运算符实现按需绑定;
(4) 绑定类名时,可以通过对象来决定是否需要绑定;
<style>
.active {
color: red;
}
.bgColor {
background-color: darkorange;
}
.largeSize {
font-size: 30px;
}
</style>
<body>
<div id="app">
<!--
<div :class="{classA: isTrue }"></div>
<div :class="[classA, classB]"></div>
<div :class="[classA, { classB: isB, classC: isC }]">
-->
<!-- 对象语法 用的较多-->
<p v-bind:class="{'active': isActive, 'bgColor': isBg}">{{message}}</p>
<p v-bind:class="getClasses()">{{message}}</p>
<!-- 数组语法-->
<p v-bind:class="['largeSize', 'active']">{{message}}</p>
<p v-bind:class="['largeSize', {'active': isActive}]">{{message}}</p>
</div>
<script>
let app = new Vue({
el: "#app",
data: {
message: "hello",
isActive: true,
isBg: true
},
methods: {
getClasses: function () {
return {'active': this.isActive, 'bgColor': this.isBg}
}
}
})
</script>
- 绑定样式
v-bind绑定style注意事项:
(1) 将样式代码赋值到对象中,给style属性赋值,取值必须用引号;
(2) 样式如果带'-',也必须用引号,如'font-size',没有'-'的style属性也可以加引号;
<div id="app">
<!-- 对象语法-->
<p :style="{color: 'green'}">{{message}}</p>
<p :style="{color: 'yellow', 'fond-size': '30px'}">{{message}}</p>
<p :style="{'color': 'aqua', 'fond-size': '20px'}">{{message}}</p>
<p :style="obj">v-bind绑定style,通过model中的对象</p>
<p :style="addStyle()">v-bind绑定style,通过model中的对象</p>
<!-- 数组语法-->
<p :style="[{'color': 'red'}, {'fond-size': '20px'}]">{{message}}</p>
</div>
<script>
let vue2 = new Vue({
el: '#app',
data: {
message: "hello",
obj: {
color: 'chocolate',
size: '40px'
}
},
methods: {
addStyle: function () {
return this.obj
}
}
})
</script>
- 计算属性
- 基本使用
只要返回的结果没有变化,计算属性只会被执行一次。
<div id="app">
<!-- 显示名字全称 中间空格隔开-->
<h2>{{firstName + ' ' + lastName}}</h2>
<h2>{{firstName}} {{lastName}}</h2>
<h2>{{getFullName()}}</h2>
<!-- 计算属性方式-->
<h2>{{fullName}}</h2>
</div>
<script>
let app = new Vue({
el: "#app",
data: {
firstName: "Li",
lastName: "xiaolong"
},
computed: {
fullName: function () {
return this.firstName + " " + this.lastName
}
},
methods: {
getFullName: function () {
return this.firstName + " " + this.lastName
}
}
})
</script>
- 计算属性的复杂操作
<div id="app">总价格:{{totalPrice}}</div>
<script>
let app = new Vue({
el: "#app",
data: {
books: [
{id: 110, name: '代码大全',price: 105},
{id: 111, name: '深入理解计算机原理', price: 98},
{id: 112, name: '现代操作系统', price: 87}
]
},
computed: {
totalPrice: function () {
totalPrice = 0;
// for (let i = 0; i < this.books.length; i++){
// totalPrice += this.books[i]['price']
// }
// ES6语法
// for (let i in this.books) {
// totalPrice += this.books[i]['price']
// }
for (let book of this.books){
totalPrice += book['price']
}
return totalPrice
}
}
})
movies = ['海贼王', '名侦探柯南', '火影忍者']
for (let i = 0; i < movies.length; i++){
console.log(movies[i])
}
// ES6语法一
for (let i in movies){
console.log(movies[i])
}
// ES6语法二
for (let item of movies){
console.log(item)
}
</script>
- 计算属性setter和getter
<script>
/* 每个计算属性都包含一个getter和一个setter方法(setter不常用)*/
let app = new Vue({
el: "#app",
data: {
firstName: "wang",
lastName: "xiaolan"
},
computed: {
fullName: {
set: function (name) {
const names = name.split(' ');
this.firstName = names.length > 0 ? names[0] : '';
this.lastName = names.length > 1 ? names[1] : '';
},
get: function () {
return this.firstName + ' ' + this.lastName;
}
}
}
})
</script>
- v-on
- v-on的使用
作用:绑定事件监听器
缩写:@
预期:Function | Inline Statement | Object
参数:event
<div id="app">
<h2>{{counter}}</h2>
<button v-on:click="increment">+</button>
<button @click="decrement">-</button>
</div>
<script>
let app = new Vue({
el: '#app',
data: {
counter: 0
},
methods: {
increment() {
this.counter ++;
},
decrement() {
this.counter --;
}
}
})
</script>
- v-on参数
如果调用的方法不需要额外参数,那么方法后的()可以不添加,如果方法本身有一个参数,那么会默认将原生事件event参数传递进去
如果需要同时传入某个参数,同时需要event时,可以通过$event传入事件
<!-- 事件调用的方法没有参数-->
<button @click="btn1Click()">按钮1</button>
<button @click="btn1Click">按钮1</button>
<!-- 写函数时省略了(),但是方法本身需要一个参数-->
<button @click="btn2Click('test')">按钮2</button> <!-- btn2Click: test-->
<button @click="btn2Click()">按钮2</button> <!-- btn2Click: undefined-->
<button @click="btn2Click">按钮2</button> <!-- btn2Click: MouseEvent…-->
<button @click="btn3Click()">按钮3</button> <!-- btn3Click: undefined MouseEvent...-->
<button @click="btn3Click">按钮3</button> <!-- btn3Click: MouseEvent... MouseEvent...-->
<button @click="btn3Click('test')">按钮3</button> <!-- btn3Click: test MouseEvent...-->
<button @click="btn3Click('test', $event)">按钮3</button> <!-- btn3Click: test MouseEvent...-->
</div>
<script>
let app = new Vue({
el: '#app',
data: {
counter: 0
},
methods: {
increment() {
this.counter ++;
},
decrement() {
this.counter --;
},
btn1Click() {
console.log('btn1Click');
},
btn2Click(a) {
console.log('btn2Click: ', a);
},
btn3Click(a, event) {
console.log('btn3Click: ', a, event);
}
}
})
</script>
- v-on的修饰符
.once - 只触发一次回调
.prevent - 调用 event.preventDefault() ,阻止默认行为
.self - 只有当前元素本身触发事件时,才执行回调函数
.stop - 调用 event.stopPropagation(),阻止事件冒泡
.capture - 添加事件侦听器时使用 capture 模式
.native - 监听组件根元素的原生事件
.{keyCode | keyAlias} - 只当事件是从特定键触发时才触发回调
<div id="app">
<!-- .stop - 阻止事件冒泡-->
<div @click="divClick">aaaaaaaaa
<button @click.stop="btnClick">按钮</button>
</div>
<!-- .prevent - 阻止默认事件-->
<form action="...">
<input type="submit" value="提交" @click.prevent="submitClick">
</form>
<!-- .{keyCode | keyAlias} 监听键盘某个键帽 -->
<input type="text" @keyup.enter="keyup">
<!-- .once - 只触发一次回调-->
<button @click.once="btn2Click">按钮2</button>
</div>
<script>
let app = new Vue({
el: '#app',
data: {
},
methods: {
divClick() {
console.log('divClick');
},
btnClick() {
console.log('btnClick');
},
submitClick() {
console.log('submitClick');
},
keyup() {
console.log('keyup');
},
btn2Click() {
console.log('btn2Click');
}
}
})
</script>
-
v-if
如果取值是true就渲染元素,否则就不渲染元素。(如果条件不满足,不会创建这个元素)
v-if 可以从模型中获取元素,也可以直接赋值一个表达式。
v-else 前面必须有 v-if 或者 v-else-if ;
v-if 和 v-else 中间不能插入其它内容;
<div v-if='isShow'>
<h2>abc</h2>
<p>abc</p>
<div>abc</div>
</div>
<h2 v-else>isShow为false时,显示</h2>
<p v-if="score>=90">优秀</p>
<p v-else-if="score>=80">良好</p>
<p v-else-if="score>=60">及格</p>
<p v-else>不及格</p>
</div>
<script>
let app = new Vue({
el: '#app',
data: {
isShow: true,
score: 88
}
})
</script>
-
v-show
如果取值是true就渲染元素,否则就不渲染元素。
v-if 和 v-show 区别:
v-if: 只要取值是false,就不会创建元素;
v-show: 取值为false也会创建元素,会设置元素的display为none;
一般来说,v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。
- v-for
格式:
v-for="item in movies"
v-for="(item, index) in movies"
v-for="(value, key) in obj"
官方推荐在使用v-for时,给对应的元素或组件添加上一个:key属性
key的作用主要是为了高效的更新虚拟DOM
<div id="app">
<ul>
<li v-for="item in movies">{{item}}</li>
</ul>
<br><br>
<ul>
<li v-for="(item, index) in movies">{{index}}----------{{item}}</li>
</ul>
<br><br>
<ul>
<li v-for="(value, key) in obj">{{key}}----------{{value}}</li>
</ul>
<ul>
<li v-for="item in letters" :key="item">{{item}}</li>
</ul>
</div>
<script>
let app = new Vue({
el: '#app',
data: {
message: 'hello vue!',
movies: ['姜子牙', '急先锋', '流浪地球', '极速车神'],
obj: {
name: 'xiaolan',
age: 13
},
letters: ['A', 'B', 'C', 'D', 'E']
}
})
// 在最后插入
app.movies.push('盗梦空间')
// 在第二个元素急先锋后插入
app.movies.splice(2, 0, '少年的你')
// B后面插入F
app.letters.splice(2, 0, 'F')
</script>
-
v-model
可以用 v-model 指令在表单 <input>、<textarea> 及 <select> 元素上创建双向数据绑定。
v-model其实是一个语法糖,它的背后本质上是包含两个操作:
1.v-bind绑定一个value属性
2.v-on指令给当前元素绑定input事件
<div id="box2">
<input type="text" v-model="text_message" placeholder="填写内容">
<p>Message is: {{ text_message }}</p>
</div>
<script>
let box2 = new Vue({
el: "#box2",
data: {
text_message: ''
}
})
</script>
- v-model结合radio使用
<div id="app">
<label for="male">
<input type="radio" id="male" name="sex" value="男" v-model="sex">男
</label>
<label for="female">
<input type="radio" id="female" name="sex" value="女" v-model="sex">女
</label>
<h2>您选择的性别是:{{sex}}</h2>
</div>
<script>
const app = new Vue({
el: '#app',
data: {
sex: '男'
}
})
</script>
- v-model结合checkbox使用
<div id="app">
<!-- 1.checkbox单选框-->
<h1>checkbox单选框</h1>
<label for="agree">
<input type="checkbox" id="agree" v-model="isAgree">同意协议
</label>
<h2>您选择的是:{{isAgree}}</h2>
<button :disabled="!isAgree">下一步</button>
<!-- 2.checkbox多选框-->
<h1>checkbox多选框</h1>
<input type="checkbox" value="篮球" v-model="hobbies">篮球
<input type="checkbox" value="打游戏" v-model="hobbies">打游戏
<input type="checkbox" value="羽毛球" v-model="hobbies">羽毛球
<input type="checkbox" value="足球" v-model="hobbies">足球
<h2>选择的爱好是:{{hobbies}}</h2>
</div>
<script>
const app = new Vue({
el: '#app',
data: {
isAgree: false,
hobbies: []
}
})
</script>
-
v-model修饰符
1.修饰符:lazy
默认情况下,v-model默认是在input事件中同步输入框的数据的,一旦数据发生改变,对应的data中的数据就会自动发生改变;
lazy修饰符可以让数据在失去焦点或回车时才会更新;2.修饰符:number
默认情况下,在输入框中无论我们输入的是字母还是数字们都会被当做字符串类型进行处理;
number修饰符可以将输入框中输入的内容自动转成数字类型;3.修饰符:trim
trim修饰符可以去除内容左右两边的空格 过滤器
过滤器一般用来格式化插入的文本数据。
使用过滤器格式:
{{ message | filterA }}
{{ message | filterA | filterB }}
{{ message | filterA('arg1', arg2) }}
<div id="app">
<h2>保留两位小数:{{price | showPrice}}</h2>
</div>
<script>
const app = new Vue({
el: '#app',
data: {
price: 35
},
filters: {
showPrice(price) {
return '¥' + price.toFixed(2);
}
}
})
</script>
利用过滤器对时间进行格式化
<div id="time">
<p>{{time_date | dataFormart}}</p>
</div>
<script>
Vue.filter('dataFormart', function (value) {
let date = new Date(value);
let year = date.getFullYear() + '';
let month = date.getMonth() + 1 + '';
let day = date.getDate() + '';
let hour = date.getHours() + '';
let minute = date.getMinutes() + '';
let second = date.getSeconds() + '';
return `${year}-${month.padStart(2, '0')}-${day.padStart(2, '')} ${hour.padStart(2, '0')}:${minute.padStart(2, '0')}:${second.padStart(2,'0')}`;
});
let vue2 = new Vue({
el: '#time',
data: {
time_date: 1601673785000
}
})
</script>
-
自定义全局指令
除了核心功能默认内置的指令 (v-model 和 v-show),Vue 也允许注册自定义指令。
- 语法
1.1 全局自定义指令:
在任何一个Vue实例控制的区域中都可以使用。
Vue.directives('自定义指令名称', {
生命周期名称: function (el) {
指令逻辑代码
}
})
1.2. 局部指令:
只能在自定义的那个Vue实例中使用
directives: {
自定义指令名称: {
生命周期名称: function (el) {
指令逻辑代码
}
}
}
- 指令生命周期方法
自定义指令时一定要明确指令的业务逻辑代码更合适在哪个阶段执行
例如:指令逻辑代码中没有用到元素事件,那么可以在bind阶段执行
例如:指令逻辑代码中用到了元素事件,那么就需要在inserted阶段执行 - 自定义指令注意点
使用时需要加上v-,而在自定义时不需要加v-;
<div id="box1">
<p v-red>测试red全局自定义指令</p>
<p v-blue>测试blue局部自定义指令</p>
<!-- input被渲染出来后,就被选中-->
<input type="text" v-focus>
</div>
<script>
/*
第一个参数:指令名称
第二个参数:对象
bind:指令被绑定到元素上的时候执行
inserted:绑定指令的元素被添加到父元素上的时候调用
*/
Vue.directive('red', {
bind: function (el) {
el.style.color = 'red';
}
});
let vue1 = new Vue({
el: '#box1',
directives: {
blue: {
bind: function (el) {
el.style.color = 'blue';
}
},
focus: {
inserted: function (el) {
el.focus();
}
}
}
})
</script>
- 自定义指令传参
<div id="box2">
<p v-color="'green'">自定义指令传参</p>
<p v-color="pinkColor">自定义指令传参取data数据</p>
</div>
<script>
let vue2 = new Vue({
el: '#box2',
data: {
pinkColor: 'pink'
},
directives: {
color: {
bind: function (el, color) {
el.style.color = color.value;
}
}
}
})
</script>
- 过渡动画
- 给vue添加过渡动画
1.1 将要执行动画的元素放到transaction组件中;
1.2 当transaction中的元素显示时,会自动查找 .v-enter/ .v-enter-active/ .v-enter-to类名
当transaction中的元素隐藏时,会自动查找 .v-leave/ .v-leave-active/ .v-leave-to类名
1.3 只需在.v-enter/ ..v-leave-to中指定动画开始的状态
在.v-enter-active / .v-leave-active中指定动画执行的状态
即可完成过渡动画。