01 Vue 基础

Vue

初始化

vue

1
2
<script src="https://unpkg.com/vue@next"></script>
<div id="root"></div>

js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
const app = Vue.createApp({
data() {
return {
inputValue: '',
list: []
}
},
methods: {
handleAddItem() {
this.list.push(this.inputValue);
this.inputValue = '';
}
},
template: `
<div>
<input v-model="inputValue" />
<button
v-on:click="handleAddItem"
v-bind:title="inputValue"
>
增加
</button>
<ul>
<todo-item
v-for="(item, index) of list"
v-bind:content="item"
v-bind:index="index"
/>
</ul>
</div>
`
});
app.component('todo-item', {
props: ['content', 'index'],
template: '<li>{{index}} -- {{content}}</li>'
});
app.mount('#root');

MVVM设计模式,M -> Model 数据, V -> View 视图, VM -> ViewModel 视图数据连接层

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// createApp 表示创建一个 Vue 应用, 存储到 app 变量中
// 传入的参数表示,这个应用最外层的组件,应该如何展示
// MVVM 设计模式,M -> Model 数据, V -> View 视图, VM -> ViewModel 视图数据连接层
const app = Vue.createApp({
//M -> Model 数据
data() {
return {
message: 'hello world'
}
},
//V -> View 视图
template: "<div>{{message}}</div>"
});
// vm 代表的就是 Vue 应用的根组件
const vm = app.mount('#root');

vm.$data.message
vm.$option

生命周期函数

生命周期函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
 //生命周期函数:在某一时刻会自动执行的函数
const app = Vue.createApp({
data() {
return {
message: 'hello world'
}
},
//在实例生成之前
beforeCreate(){
},
//在实例生成之后
created(){
},
//在组件内容被渲染到页面之前
beforeMount(){
},
//在组件内容被渲染到页面之后
mounted(){
},
//当数据发生变化时
beforeUpdate(){
},
//当数据发生变化,页面重新渲染之后
updated(){
},
//当vue应用失效时
beforeUnmount(){
},
//当vue应用失效,DOM完全销毁之后
unmounted(){
},
template: "<div>{{message}}</div>"
});
// vm 代表的就是 Vue 应用的根组件
const vm = app.mount('#root');

常用模板语法

  • 差值表达式
  • v-once 只绑定第一次
  • v-html
  • v-bind (:) 绑定到标签的属性,使用动态数据
  • v-on (@) 绑定到标签的事件 (方法放在methods)
  • v-if v-show
  • v-model 数据绑定
  • 动态参数
  • 修饰符
    动态参数,动态属性
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const app = Vue.createApp({
data() {
return {
name: "title",
msg:"111",
event:"cilck"
}
},
methods: {
handleClick() {
alert('click')
}
},
template: `<div :[name]="msg" @[event]="handleClick"></div>`
});

修饰符.prevent阻止默认行为 等价于e.prevnetDedault()

1
2
3
4
5
template: `
<form action="https://www.baidu.com" @click.prevent="handleClick">
<button type="submit">提交</button>
</form>
`

数据,方法,计算属性和侦听器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
// data & methods & computed & watcher
// computed 和 method 都能实现的一个功能,建议使用 computed,因为有缓存
// computed 和 watcher 都能实现的功能,建议使用 computed 因为更加简洁
const app = Vue.createApp({
data() {
return {
message: "hello world",
count: 2,
price: 5,
newTotal: 10,
}
},
//侦听器 侦听data值的变化,可以添加定时器
watch: {
// price 发生变化时,函数会执行
price(current, prev) {
this.newTotal = current * this.count;
}
},
//计算属性
computed: {
// 当计算属性依赖的内容发生变更时,才会重新执行计算
total() {
return Date.now() + this.count;
// return this.count * this.price
}
},
//差值表达式和@绑定事件时可以直接使用
methods: {
formatString(string) {
return string.toUpperCase();
},
// 只要页面重新渲染,才会重新计算
getTotal() {
return Date.now();
// return this.count * this.price;
},
},
template: `
<div>{{total}} {{message}} {{newTotal}} </div>
`
});
const vm = app.mount('#root');

样式

1
2
3
4
5
6
7
8
<style>
.red {
color: red;
}
.green {
color: green;
}
</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
const app = Vue.createApp({
data() {
return {
classString: 'red',
classObject: { red: false, green: true },
classArray: ['red', 'green', {brown: false}],
styleString: 'color: yellow;background: orange',
styleObject: {
color: 'orange',
background: 'yellow'
}
}
},
template: `
<div :style="classString"> Hello World </div>
<div :style="classArray"> Hello World </div>
<div :style="classArray"> Hello World </div>
<div :style="styleString"> Hello World </div>
<div :style="styleObject"> Hello World </div>
<demo />
`
});
app.component('demo', {
template: `
<div :class="$attrs.class">one</div>
<div :class="$attrs.class">two</div>
`
})

条件渲染

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const app = Vue.createApp({
data() {
return {
show: false,
conditionOne: false,
conditionTwo: true
}
},
template: `
<div v-if="show">Hello World</div>
<div v-if="conditionOne">if</div>
<div v-else-if="conditionTwo">elseif</div>
<div v-else>else</div>
<div v-show="show">Bye World</div>
`
});

列表渲染

list (item,index) in listArray
对象 (value, key, index) in listObject
:key唯一key,提高性能,复用DOM

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
const app = Vue.createApp({
data() {
return {
listArray: ['dell', 'lee', 'teacher'],
listObject: {
firstName: 'dell',
lastName: 'lee',
job: 'teacher'
}
}
},
methods: {
handleAddBtnClick() {
// 1. 使用数组的变更函数 push, pop, shift, unshift, splice, sort, reverse
// this.listArray.push('hello');
// this.listArray.pop();
// this.listArray.shift();
// this.listArray.unshift('hello');
// this.listArray.reverse();
// 2. 直接替换数组
// this.listArray = ['bye', 'world']
// this.listArray = ['bye', 'wolrd'].filter(item => item === 'bye');
// 3. 直接更新数组的内容
// this.listArray[1] = 'hello'
// 直接添加对象的内容,也可以自动的展示出来
// this.listObject.age = 100;
// this.listObject.sex = 'male';
}
},
template: `
<div>
<template
v-for="(value, key, index) in listObject"
:key="index"
>
<div v-if="key !== 'lastName'">
{{value}} -- {{key}}
</div>
</template>
<div v-for="item in 10">{{item}}</div>
<button @click="handleAddBtnClick">新增</button>
</div>
`
});

事件绑定

1
<div @click="handleClick(), handleClick2()">123</div>

修饰符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// event, $event
// 事件修饰符:stop, prevent, capture, self, once, passive
// 按键修饰符:enter, tab, delete, esc, up, down, left, right
// 鼠标修饰符:left, right, middle
// 精确修饰符:exact
const app = Vue.createApp({
methods: {
handleClick() {
console.log('click')
},
},
template: `
<div>
<div @click.ctrl.exact="handleClick">123</div>
</div>
`
});

双向数据绑定

v-model

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// input, textarea, checkbox, radio, select
// 修饰符 lazy, number, trim
const app = Vue.createApp({
data() {
return {
message: 'hello',
checkbox1:true,
checkbox2:[]
}
},
template: `
<div>
{{message}}
<input v-model="message" />
<textarea v-model="message" />
<input type="checkbox" v-model="checkbox1" />
<input type="radio" v-model="checkbox1" />
<select v-model="message" >
<option>A</option>
<option>B</option>
<option>C</option>
</select>
<select v-model="message" multple>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
<input v-model.lazy="message" />
</div>
`
});

ref获取DOM

ref获取DOM节点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// ref 实际上是获取 Dom 节点引用 的一个语法
const app = Vue.createApp({
data() {
return { count: 1}
},
mounted:{
this.$refs.count
},
template: `
<div>
<button ref="count">Add</button>
</div>
`
});

ref获取DOM节点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 // ref 实际上是获取 Dom 组件引用 的一个语法
const app = Vue.createApp({
data() {
return {
count: 1
}
},
mounted() {
this.$refs.common.sayHello()
},
template: `
<div>
<common-item ref="common"/>
</div>
`
});
app.component('common-item', {
methods: {
sayHello(){
console.log("hello");
}
},
template: `<div>sayHello</div>`
});

provide / inject

传一个值给子组件的子组件,可以多次用动态传值props接受来完成,也可以用Provide / Inject

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
const app = Vue.createApp({
data() {
return { count: 1}
},
template: `
<div>
<child :count="count" />
</div>
`
});
app.component('child', {
props: ['count'],
template: `<child-child :count="count"/>`
});
app.component('child-child', {
props: ['count'],
template: `<div>{{count}}</div>`
});

Provide / Inject完成上述例子,同时provide传递的数据是一次性的,不是双向数据绑定的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// provide / inject
const app = Vue.createApp({
data() {
return { count: 1}
},
provide() {
return {
count: this.count,
}
},
template: `
<div>
<child :count="count" />
<button @click="count += 1">Add</button>
</div>
`
});
app.component('child', {
template: `<child-child />`
});
app.component('child-child', {
inject: ['count'],
template: `<div>{{count}}</div>`
});