目录
Vue这种面向数据的编程模式是参考了MVVM的设计模式
MVVM:M->model数据,V->view视图,VM->ViewModel视图数据连接层
在编写Vue的代码前需要先引入
<script src="https://unpkg.com/vue@next"></script>
1. 应用和组件的概念
<div id="root"></div>
<script>
const app = Vue.createApp({
data() {
return {
message: 'hello world'
}
},
template: `
<div>{{message}}</div>
`
})
const vm = app.mount('#root');
</script>
createApp:使用Vue创建一个应用,存储到app中,传入的参数表示,这个组件的最外层该如何表示。
app.mount(’#root’) :将app挂载到id为root的dom中
可以在控制台里修改data中的值:vm.$data.message='bye',页面展示的message也会变成bye
$data:vue实例的属性,可以用来操作data中定义的数据
2. 生命周期函数
在某一时刻会自动执行的函数
beforeCreate:在实例生成之前自动执行的函数
created:在实例生成之后自动执行的函数
beforeMount:在模板已经被变成函数之后立即执行的函数,或在组件内容被渲染到页面前自动执行的函数
mounted:在组件内容被渲染到页面之后自动执行的函数
beforeUpdate:当data中的数据发生变化时会自动执行的函数
updated:当data中的数据发生变化时,同时页面完成更新后,自动执行的函数
beforeUnmount:当Vue应用失效时自动执行
Unmounted:当Vue应用失效时,且dom完全销毁之后,自动执行
3. 常用模板语法
3.1 插值表达式
1. v-html
<div v-html="message"></div>
// 相当于
<div>{{message}}</div>
如果message中有标签,会正常加上标签展示
data() {
return {
message: '<strong>hello</strong>'
}
},
template: `
<div>{{message}}</div> // 显示:<strong>hello</strong>
<div v-html="message"></div> // 显示:加粗的hello
`
2. v-bind
用于设置动态的属性值
data() {
return {
message: '<strong>hello</strong>',
name: '你好'
}
},
template: `
<div v-bind:title="name">{{message}}</div> //你好
<div title="name">{{message}}</div> //name
`
title:当鼠标碰到页面上展示的该标签会出现一个悬浮框展示内容
v-bind:可以简写为:
3.插值表达式{{ }}中可以写一些JS的表达式
注:不是语句,是表达式
{{ Math.max(1,2) }} // 2
{{ 'a'+'b' }} // 'ab'
3.2 v-once
<div v-once>{{message}}</div>
div中的变量只会使用一次,第一次渲染时会进行渲染,后面再对div的值改变就不会变了
3.3 v-if
data() {
return {
message: 'hello',
show: true
}
},
template: `
<div v-if="show">{{message}}</div>
`
show是true,页面中就可以展示内容,为false,就不能展示内容
3.4 v-on
methods: {
handleClick() {
alert('');
}
},
template: `
<div v-on:click="handleClick">{{message}}</div>
// 相当于
<div @click="handleClick">{{message}}</div>
`
v-on绑定事件,对应的方法写在methods:{ }里。
v-on:可以简化为@
3.5 动态属性
data() {
return {
message: 'hello',
key: 'k',
value: 'v'
}
},
template: `
<div :[key]="value">{{message}}</div>
`
给div设置一个属性,属性名为k,属性值为v,设置完,div就会变成
<div k='v'>hello</div>
3.6 修饰符
template: `
<form action="https://sass-lang.com/" @click.prevent="handleClick">
// prevent 阻止默认行为的修饰符
<button type="submit">提交</button>
</form>
`
4. 数据、方法、计算属性和侦听器
4.1 数据data
通过return返回数据,可以在控制台改变数据
vm.$data.message=123
如果要改变的数据是根数据,可以不加$data
4.2 方法methods
在Vue中,methods中定义的方法的this指向都为这个Vue的实例,但如果定义的方法是箭头函数,则指向外层this,所以别用箭头函数。
方法也可以用在插值表达式上,如:{{ formatString(message) }}
4.3 计算属性computed
data() {
return {
a: 3,
b: 5,
}
},
computed: {
// 计算属性里有一个叫cal的属性
cal() {
return this.a * this.b;
}
},
template: `
<div>{{cal}}</div>
`
某数据是由其他几个数据算出来的,当其他几个数据变化时,这个数据也跟着变化。在模板中使用不需要加()。
computed计算属性和methods方法的区别:
- methods方法:只要页面重新渲染,就会重新计算(无论改什么值都变)
- computed计算属性:当计算属性依赖的内容发生变更时,才会重新计算(改相关的才变)
建议:能采用computed和methods都可以时,尽量用computed,因为有缓存,性能好。
4.4 侦听器watch
data() {
return {
a: 1,
b: 2,
sum: 3
}
},
watch: {
b(current, prev) {
// current 更新后的值
// prev 老的值
this.sum = current + this.a;
//等价于
// this.sum = this.a * this.b;
}
},
template: `
<div>{{sum}}</div>
`
当b改变时,页面的内容会发生变化,但当a改变时,页面不变。
遇到异步的情况时,可以使用watch解决。通过watch监听data中定义的变量的改变。
computed和watch都能实现一个功能时,建议使用computed。
5. 样式绑定语法
5.1 可以直接绑定,或通过字符串、数组、对象绑定
data() {
return {
string: 'red',
object: { red: true, green: true },
array: ['red', 'green', { black: true }]
}
},
template: `
<div :class="string">aaa</div>
<div :class="object">bbb</div>
<div :class="array">ccc</div>
`
运行结果:
5.2 主动调用的叫父组件,被动调用的叫子组件
const app = Vue.createApp({
template: `
<div>我是父组件</div>
<test />
`
})
app.component('test',
template: `<div>我是子组件</div>`
})
1. 当子组件只有一个最外层节点时
(1)可在节点本身设置样式
app.component('test', {
template: `<div class="red">我是子组件</div>`
})
(2)可在父组件的模板中设置样式
const app = Vue.createApp({
template: `
<div>我是父组件</div>
<test class="green" />
`
})
2. 当子组件不只有一个最外层节点时,直接在父组件上设置样式是不可行的
(1)可以在子组件上,每一个都设置样式
app.component('test', {
template: `
<div class="red">我是子组件1</div>
<div class="green">我是子组件2</div>
`
})
(2)在父组件上设置样式,子组件上也设置样式
const app = Vue.createApp(
data() {
return {
classString: 'red'
}
},
template: `
<div :class="classString" >
<test class="green"/>
</div>
`
})
app.component('test', {
// $attrs.class子组件标签的样式是父组件属性上的值
// 设置了该属性的标签样式是子组件上设置的样式
// 没设置的是父组件上设置的样式
template: `
<div :class="$attrs.class">我是子组件1</div>
<div>我是子组件2</div>
`
})
5.3 写行内样式
方法一:直接书写,与HTML中一样
template: `
<div style="color:red">hello</div>
`
方法二:将样式放在对象中,将对象绑定给标签
const app = Vue.createApp({
data() {
return {
styleObject: {
color: 'red',
background: 'pink'
}
}
},
template: `
<div :style="styleObject">hello</div>
`
})
6. 条件渲染 v-if
1. v-if 和 v-show
data() {
return {
show: false
}
},
template: `
<div v-if="show">hello</div>
<div v-show="show">hello</div>
`
当show设置为true是,二者都显现。当show设置为false时,二者都不显现,区别在于v-if 直接销毁了这个div,而v-show是将div设置了display:none
2. v-if 的额外用法
template: `
<div v-if="conditionOne">if</div>
<div v-else-if="conditionTwo">else if</div>
<div v-else>else</div>
`
和JS中if相关语法一样,要注意他们要贴在一起写
7. 循环渲染 v-for
1. 对对象进行循环时,第一个参数代表value,第二个参数代表key,第三个参数代表下标
data() {
return {
zs: {
name: '张三',
sex: '男',
age: 33
}
}
},
template: `
<div v-for="(value,key,index) in zs">
{{value}} {{key}} {{index}}
</div>
`
直接添加对象的内容,也可以自动展示出来
2. 对数组进行循环时,为了提升性能,建议字啊v-for 指令的每一项添加一个key值,key值尽量唯一,这样才能对渲染的dom元素进行区分
data() {
return {
color: ['red', 'orange', 'yellow', 'green', 'blue', 'purple']
}
},
template:`
<div v-for="(item,index) in color" :key="item">
{{item}} {{index}}
</div>
`
(1)可以使用变更函数来改变数组,如push,pop,shift,unshiftmsplice,sort,reverse
(2)也可以直接改变数组
methods: {
handleClick() {
this.color.push('white');
}
},
template: `
<div v-for="(item,index) in color" :key="item">
{{item}} {{index}}
</div>
<button @click="handleClick">增加</button>
`
3. 可以直接循环数字
<div v-for="item in 10">{{item}}</div>
4. v-for 和v-if 一起写时,由于v-for 比v-if 优先级更好,所以v-if 不生效,此时需要分层写
5. <template></template>占位符,无实际意义,去掉冗余标签
8. 事件绑定
8.1 event
methods: {
fun(event) {
// console.log(event);
console.log(event.target);
}
},
template: `
<button @click="fun">点击</button>
`
可以通过event查看事件源对象
如果一个方法既要传参,又要获取事件源对象,就要在模板里用$event
data() {
return {
count: 1
}
},
methods: {
fun(num, event) {
// console.log(event);
console.log(event.target);
this.count += num;
}
},
template: `
{{count}}
<button @click="fun(2,$event)">点击</button>
`
当一次点击要执行多个函数时,要用逗号将函数名分开,还要加()
template: `
<button @click="fun(),fun2()">点击</button>
`
8.2 修饰符
1. stop:阻止冒泡
2. self:子标签触发的dom事件不执行,点击一个标签的子标签没有用,只有点击我本身的时候才回执行相应的绑定事件
3. capture:事件默认为冒泡,它会将事件变为捕获模式
4. prevent:阻止默认事件
5. once:事件绑定只执行一次
template: `
<div id="box1" @click.self="fun">
<div id="box2"></div>
</div>
`
9. 表单中双向绑定指令的使用 v-model
1. input:input进行双向绑定之后,不需要再写value了
data() {
return {
message: 'hello'
}
},
template: `
{{message}}
<input v-model="message" />
`
2. textarea:写单标签就行了
data() {
return {
message: 'hello'
}
},
template: `
{{message}}
<textarea v-model="message" />
`
3. checkbox
checkbox绑定的变量值只能是true或者false,但此时若多个checkbox绑定的是同一个变量,他们只能同时选中或取消。
可以将checkbox的绑定变量值设为数组,选中谁数组中就有谁
data() {
return {
show: []
}
},
template: `
{{show}}
jack<input type="checkbox" v-model="show" value="jack"/>
tom <input type="checkbox" v-model="show" value="tom"/>
`
checkbox的自定义特性,可以改变true和false的值
data() {
return {
str: '假的假的',
}
},
template: `
{{str}}
<input type="checkbox" v-model="str" true-value="真哒真哒" false-value="假的假的"/>
`
4. radio:与checkbox类似,type里换成radio就行了
5. select 与 option
在 select 中添加 multiple 属性代表可以多选
可以通过循环添加option
data() {
return {
str: '',
options: [{
text: '西瓜', value: { value: '西瓜' },
}, {
text: '草莓', value: { value: '草莓' },
}, {
text: '樱桃', value: { value: '樱桃' },
}],
}
},
template: `
{{str}}
<select v-model="str" multiple>
<option v-for="item in options" :value="item.value">
{{item.text}}
</option>
</select>
`
6. v-model 指令对应的修饰符 / form表单中标签的修饰符
(1)lazy:当input失去焦点后,数据才会同步
(2)number:可以做类型转化,输入数字会转为number类型,无法输入非数字
data() {
return {
num: 124
}
},
template: `
{{num}}
<input v-model.number="num" type="number" />
`
(3)trim:去除绑定内容前后的空格,但是字符串中间加空格不会去除