(1)解耦视图和数据
(2)可复用的组件
(3)前端路由技术
(4)状态管理
(5)虚拟DOM
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<!-- 生产环境版本,优化了尺寸和速度 -->
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
下载:https://vuejs.org/js/vue.js
生产环境: https://vuejs.org/js/vue.min.js
后续通过webpack和CLI的使用,我们使用该方式
在我们前端开发中,通常就是DOM层。
主要的作用是给用户展示各种信息。
数据可能是我们固定的死数据,更多的是来自我们服务器,从网络上请求下来的数据。
在我们计数器的案例中,就是后面抽取出来的obj,当然,里面的数据可能没有这么简单。
视图模型层是View和Model沟通的桥梁。
(1) 一方面它实现了Data Binding,也就是数据绑定,将Model的改变实时的反应到View中
(2)另一方面它实现了DOM Listener,也就是DOM监听,当DOM发生一些事件(点击、滚动、touch等)时,可以监听到,并在需要
该指令后面不需要跟任何表达式(比如之前的v-for后面是由跟表达式的)
该指令表示元素和组件(组件后面才会学习)只渲染一次,不会随着数据的改变而改变。
<div id="app">
<h2>{
{
message}}</h2>
<!--v-once 该指令只会渲染一次,不会随着数据的改变而改变 -->
<h2 v-once>{
{
message}}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: "#app",
data: {
message: "hello vue!",
firstName: "Kim",
lastName: "Lily",
counter: 100
}
})
</script>
该指令后面会跟上一个String类型,会将String的html解析出来并渲染
<div id="app">
<!-- v-html 会将string里的内容解析出来,并且进行渲染 -->
<h2 v-html="header"></h2>
<h2 v-html="url"></h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
url: 'aaa',
header: '头部'
},
})
</script>‘
作用和Mustache比较相似:都是用于将数据显示在界面中v-text通常情况下,接受一个string类型
<div id="app">
<h2>{
{
message}}</h2>
<!-- v-text就是将数据显示在界面中;一般接收一个String类型 -->
<!-- v-test后面的指令中并不是自己定义的字符串,而是data中已经存在的字符串 -->
<!--v-test指令会覆盖元素的内容 -->
<h2 v-text="message">你好呀!</h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: "你好呀,vue"
},
})
</script>
用于跳过这个元素和它子元素的编译过程,用于显示原本的Mustache语法。`
<div id="app">
<h2>{
{
message}}</h2>
<!-- v-pre 用于跳过这个元素和它的子元素的编译过程,用于原本的mustache语法 -->
<!-- v-pre 会直接显示显示{
{
message}}显示 -->
<h2 v-pre>{
{
message}}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: "你好 vue!"
},
})
</script>`
我们浏览器可能会直接显示出未编译的Mustache标签
<div id="app" v-cloak>
<h2>{
{
message}}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
setTimeout(() => {
const app = new Vue({
el: '#app',
data: {
message: "你好!"
},
})
}, 2000)
</script>
<div id="app">
<!-- 正确的做法;使用v-bind使用 -->
<!-- <img v-bind:src="imgURL" alt="">
<a v-bind:href="aHref">百度一下</a> -->
<!-- 语法糖 -->
<img :src="imgURL" alt="">
<a :href="aHref">百度一下</a>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: "你好,vue",
imgURL: "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1595995481748&di=0ec2eec968da1f7186fde2d5a446bd6f&imgtype=0&src=http%3A%2F%2Fa1.att.hudong.com%2F05%2F00%2F01300000194285122188000535877.jpg",
aHref: "https://www.baidu.com"
},
})
</script>
单个类的绑定、多个类的绑定(如果有多个类名不会有冲突;且过于复杂时,可以定义在一个方法中)
<div id="app">
<!-- 单个类绑定的写法 -->
<!-- <h2 v-bind:class="{key: value}"></h2> -->
<h2 v-bind:class="{active: isActive}">{
{
message}} </h2>
<!-- 多个类的绑定 -->
<!-- <h2 v-bind:class="{key1: value1,key2: value2}">
{
{
message}}
</h2> -->
<h2 v-bind:class="{active: isActive,line: isLine}">
{
{
message}}
</h2>
<!-- 如果有多个类名,他们是不冲突的 -->
<h2 class="title" v-bind:class="{active: isActive,line: isLine}">
{
{
message}}
</h2>
<!-- 如果过于复杂,可以放在一个methods中,这里的getClassse需要加括号 相当于执行这个方法 -->
<h2 :class="getClasses()">{
{
message}}</h2>
<!-- 点击切换 -->
<button @click="switchClick">切换</button>
</div>
<script src="../js/vue.js"></script>
<script>
// 监听dom和动态绑定
const app = new Vue({
el: '#app',
data: {
message: "你好 vue",
isActive: true,
isLine: true
},
//MVVM
methods: {
switchClick(){
this.isActive = !this.isActive;
this.isLine =!this.isLine
},
getClasses(){
return {
active: isActive,line: isLine}
}
}
})
</script>
<div id="app">
<!-- 数组语法 传入一个值 -->
<h2 :class="[active]">{
{
message}} </h2>
<!-- 数组语法 传入多个值 -->
<h2 :class="[active,line]">{
{
message}}</h2>
<!-- 和普通的类存在并不冲突 -->
<h2 class="title" :class="[active,line]">
{
{
message}}
</h2>
<!-- 过于复杂,可以放在一个method中 -->
<h2 :class="getClasses()">{
{
message}} </h2>
<!--数组语法和对象语法的结合 -->
<!-- <h2 :class="[{active: isActive}]">{
{
message}} </h2> -->
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: "你好 lily",
isActive: true,
active: "active",
line: "line123"
},
methods:{
getClasses(){
return [this.active,this.line];
}
}
})
</script>
(1)对象的key(css的属性名);对象的value是具体赋的值
<h2 :style="{key(属性名): value(属性值)}"> {
{
message}}
</h2>
(2)如果使用了像素单位,必须加单引号,否则会被当做一个变量解析(3)style的修饰也可以当作变量使用,在data中定义
数组语法:style将data中的修饰属性放在数组中,进行修饰
(1)调用的时候没有参数传递,后面的()可加可不加
(2)事件调用的时候需要传递参数,有多个参数需要传递,使用逗号分隔开
(3)在定义事件时,写方法的时候省略的小括号,但是方法本身需要一个参数的;这时 vue会默认将浏览器产生的event事件传入方法中
(4)定义方法时,既需要event参数,又需要其他参数,顺序不影响; 如果需要手动获取浏览器的参数event对象:$event
1、v-if
2、v-if与v-else
3、v-if与v-else-if与v-else
4、v-show
5、v-if 与v-show的区别:
(1)v-show当条件位false的时候,会增加一个行内样式:display:none
(2)v-if当为false时,包含v-if指令的元素,根本不会存在DOM中,所以每次切换的时候需要在DOM中重新创建元素。
如果绑定了input框中的message,所以输入的内容会实时传递给message,message则会发生改变(通过插值语法进行显示)
<!-- 1.没有使用v-model的radio -->
<label for="male">
<input type="radio" name="gender" value="男" id="male">男
</label>
<label for="female">
<input type="radio" name="gender" value="女" id="female">女
</label>
<!-- 2.使用v-model的radio值 -->
<!-- 使用v-model的绑定相同的属性,name属性就不用写了 -->
<label for="male">
<input type="radio" v-model="gender" value="男" id="male">男
</label>
<label for="female">
<input type="radio" v-model="gender" value="女" id="female">女
</label>
<h2>您选择的性别是:{
{
gender}}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
gender: "女"
},
})
</script>
(1)单选框:不需要加value属性
<!-- 1.checkbox单选框 -->
<!-- 需求:当用户选中同意时,下一步的按钮才会点击;不同意时,下一步按钮不可点击 -->
<label for="agree">
<input type="checkbox" id="agree" v-model="isAgree">同意 </label>
<h2>您选择的时是:{
{
isAgree}}</h2>
<!-- :idsabled 取反, -->
<button :disabled="!isAgree">下一步</button>
(2)多选框:必须加value属性
<!--2.checkbox多选框 -->
<!-- 与value有关;选中便增加;没选中就删除 -->
<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>
(3)设置value属性,如果不适用动态绑定,就会把item都当作一个变量,每一个选项的value就是item(value就是当前选项的值)
<!-- 从服务器上获取爱好数组并且对其进行展示和处理 (动态)-->
<!-- 给当前的input设置一个value,如果不使用动态绑定,就会把item都当作一个变量,也就是每一个选项的value都是item -->
<!-- 动态绑定之后,每一个value就是当前选项的值 -->
<label v-for="item in orHobbies" :for="item">
<input type="checkbox" :value="item" v-model="hobbies" :id="item">
{
{
item}}
</label>
<h2>您选择的爱好是:{
{
hobbies}}</h2>
(1)单选:
<select name="abc" v-model="fruit">
<option value="苹果">苹果</option>
<option value="榴莲">榴莲</option>
<option value="水蜜桃">水蜜桃</option>
<option value="梨">梨</option>
<option value="香蕉">香蕉</option>
</select>
<h3>您选择的水果是:{
{
fruit}}</h3>
(2)多选:
<select name="abc" v-model="fruits" multiple>
<option value="苹果">苹果</option>
<option value="榴莲">榴莲</option>
<option value="水蜜桃">水蜜桃</option>
<option value="梨">梨</option>
<option value="香蕉">香蕉</option>
</select>
<h3>您选择的水果是:{
{
fruits}}</h3>`
(1).lazy在失去焦点或者按回车时才会更新
`当前内容:{
{message}}
`
(2).number转换为number格式的数据
`<input type="text" v-model.number="age"><h2>年龄:{
{
age}} 类型:{
{
typeof age}}</h2
`>
(3).trim过滤内容两边的空格
<input type="text" v-model.trim="name"><h2>您输入的名字:---{
{
name}}---</h2>
<div id="app">
<!-- 以前拼接属性 -->
<h2>{
{
firstName}} {
{
lastName}}</h2>
<h2>{
{
firstName+ ' '+lastName}}</h2>
<!-- 通过method拼接 -->
<h2>{
{
getFullName()}}</h2>
<!-- 通过计算属性拼接 不用加括号,直接使用-->
<h2>{
{
fullName}}</h2>
</div>
methods: {
getFullName(){
return this.firstName+ ''+this.lastName;
}
},
//计算属性
computed: {
fullName(){
return this.firstName + '' + this.lastName;
}
}
用在数组中
(1)计算属性会进行缓存;如果多次使用一个计算属性,计算属性只调用一次
(2)methods每调用一次methods方法,就会重新执行一次
(1)作用:
用来监听data中的数据变化,如果数据发生变化,就会触发侦听器所绑定的方法,方法中可以做一些特定的业务需求;
(2)使用时和计算属性相似,只是使用watch属性,可以定义别的方法,用来实现属性的监听
(3)注意:
侦听数据变化时,函数名与data中定义的属性名一致;只要数据发生变化,val就会发生变化,得到最新的值
(1)当是使用定时函数的时候:
使用普通的函数定义setTimeout(function(){}, 2000)(非箭头函数);
如果在其内部使用this,需要外部定义let that = this(将this存为一个变量,此时的this指向checkName)
(2)定时器中使用that:
利用闭包访问that,that是一个指向obj的指针
(3)原因:
因为定时器函数内的this是指向window对象的;
setTimeout()调用的代码运行在与所在函数完全分离的环境上,才会导致这些代码中包含的this关键字会指向window对象
(4)解决:
使用箭头函数;因为ES6箭头函数完全修复了this指向此作用域问题(外层调用obj)
基本使用
* 第一种方式:只是用一个过滤器 {
{要过滤的值 | 过滤器的名称}}
* 第二种方式:多个过滤器级联使用 {
{message | upper |lower}}
* 第三种方式:绑定属性的时候也可以使用过滤器
<div :class="message | upper"> 测试数据</div>
第一个参数:过滤器名称;
第二个参数:处理函数函数的形参就是要处理的数据
(3)注意:过滤器是需要返回结果的
beforeCreate()、created()、brforeMount()、mounted()、
beforeUpdate()、updated()、beforeDestory()、destoryed()
此函数一旦被触发,代表着初始化已经完成了;初始化完成之后,页面中的模板已经存在了;就可以向里面填充数据了