Vue 练气大陆

开始练气

使用CDN载入

还是建议把js文件下载到本地使用

全局构建版本

我的理解是:在全局中有一个Vue对象,使用赋值语句,会自动把Vue对象里相同的属性值赋给用户,这样就可以不用在每个Vue语法前加Vue关键字

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>

<div id="app">{{ message }}</div>

<script>
const { createApp, ref } = Vue

// 可以使用 Vue.createApp({}).mount()
createApp({
setup() {
const message = ref('Hello vue!')
return {
message
}
}
}).mount('#app')
</script>

ES 模块构建版本

因为是模块化,所以需要使用import关键字导入功能

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<div id="app">{{ message }}</div>

<script type="module">
import { createApp, ref } from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js'

createApp({
setup() {
const message = ref('Hello Vue!')
return {
message
}
}
}).mount('#app')
</script>

两者的区别在于一个是引用全局模块的Vue对象,另一个是从外部js文件引入Vue功能模块

响应式数据的实现方式

ref() 函数

这是组合式Api推荐使用的声明响应式状态

1
2
3
import { ref } from 'vue'

const count = ref(0)

ref() 接收参数,并将其包裹在一个带有 .value 属性的 ref 对象中返回:

1
2
3
4
5
6
7
const count = ref(0)

console.log(count) // { value: 0 }
console.log(count.value) // 0

count.value++
console.log(count.value) // 1

可以在监听事件中改变一个ref:

1
2
3
<button @click="count++">
{{ count }}
</button>

reactive() 函数

reactive 则是将一个对象转换成响应式对象

1
2
3
4
5
6
7
8
9
import { reactive } from 'vue'

// 必须是一个对象
const count = reactive({
num : 0
})

console.log(count.num) // 0
count.num++ // 1

总的来说,ref 适用于简单数据类型的响应式处理,而 reactive 则适用于复杂数据类型的响应式处理。
此外,ref 可以通过 .value 访问值,而 reactive 则可以直接访问对象的属性。

setup() 函数

setup()是在组合式Api中使用的

1
2
3
4
5
6
7
8
9
10
const app = createApp({
setup() {
const message = ref('nodaoli')
const count = ref(0)
return {
message,
count
}
}
}).mount('#app')

我的理解是:
用来定义变量并返回一个对象的引用,各种变量和方法在对象里面

绑定 武功秘籍

v-on

我们可以使用 v-on 来监听一下点击的事件:

1
2
3
4
<!-- 绑定一个表达式 -->
<button v-on:click="counter++"></button>
<!-- 绑定到一个methods方法中 -->
<button v-on:click="btnClick">按钮1</button>

v-on:click 可以写成@click,是它的语法糖写法:

1
2
<!-- v-on的语法糖 -->
<button @click="btnClick">按钮2</button>

当然,我们也可以绑定其他的事件:

1
2
<!-- 绑定鼠标移动事件 -->
<button @mousemove="mouseMove">div的区域</button>

如果我们希望一个元素绑定多个事件,这个时候可以传入一个对象:

1
2
<!-- 绑定对象 -->
<button v-on="{click: btnClick, mousemove: mouseMove}">特殊按钮3</button>

v-on 参数传递

当通过 methods 中定义方法,以供 @click 调用时,需要注意参数问题

  • 情况一:如果该方法不需要额外参数,那么方法后的()可以不添加。
    但是注意:如果方法本身中有一个参数,那么会默认将原生事件 event 参数传递进去
  • 情况二:如果需要同时传入某个参数,同时需要 event 时,可以通过 $event 传入事件。

例子:

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
45
46
47
48
49
<div id="app">
<h1>{{message}}</h1>
<h1>{{count}}次</h1>
<button @click="count++">增加</button>
<button v-on:click="edit">修改</button> <br>
<a v-bind:href="web.url">{{web.url}}</a>
<span>共计访问次数:{{web.user}}</span>
<button @click="add">访问</button>
</div>

<script>
// 从全局构建版本中引用 createApp ref
const { createApp, ref } = Vue;

const app = createApp({
setup() {
// 定义变量
const message = ref('Hello Vue!');
const count = ref(0);
// 定义一个对象
const web = ref({
// 这是对象的属性
url:'https://icewolf-li.top',
user: 0
})

// 定义一个方法,引用赋值给 edit
const edit = function() {
message.value = 'I`m nodaoli';
}

// 使用lambda表达式的函数定义
const add = () => {
// Vue本体里面就可以直接引用
// 在JavaScript需要使用value
web.value.user++;
}

return {
// 需要返回变量和函数方法,外部才能调用
web,
message,
count,
edit,
add
}
}
}).mount('#app') // 挂载在id为app的html标签上,只能挂载一次
</script>

v-show

条件显示一个元素的指令是 v-show,其用法基本一样:

1
2
3
4
5
6
7
<h1 v-show="web.show">Hello!</h1>

<script>
const web = reactive({
show: true
});
</script>

v-if

v-if 指令用于条件性地渲染一块内容。这块内容只会在指令的表达式返回真值时才被渲染。

1
<h1 v-if="awesome">Vue is awesome!</h1>

v-else​

你也可以使用 v-elsev-if 添加一个“else 区块”。

1
2
3
4
<button @click="awesome = !awesome">Toggle</button>

<h1 v-if="awesome">Vue is awesome!</h1>
<h1 v-else>Oh no 😢</h1>

v-else-if​

顾名思义,v-else-if 提供的是相应于 v-if 的“else if 区块”。它可以连续多次重复使用:

1
2
3
4
5
6
7
8
9
10
11
12
<div v-if="type === 'A'">
A
</div>
<div v-else-if="type === 'B'">
B
</div>
<div v-else-if="type === 'C'">
C
</div>
<div v-else>
Not A/B/C
</div>

v-else 类似,一个使用 v-else-if 的元素必须紧跟在一个 v-if 或一个 v-else-if 元素后面。

v-show VS v-if

v-if 是“真实的”按条件渲染,因为它确保了在切换时,条件区块内的事件监听器和子组件都会被销毁与重建。
v-if 也是惰性的:如果在初次渲染时条件值为 false,则不会做任何事。条件区块只有当条件首次变为 true 时才被渲染
相比之下,v-show 简单许多,元素无论初始条件如何,始终会被渲染,只有 CSS display 属性会被切换。
总的来说,v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要频繁切换,则使用 v-show 较好;如果在运行时绑定条件很少改变,则 v-if 会更合适。

不同之处在于 v-show 会在 DOM 渲染中保留该元素;v-show 仅切换了该元素上名为 display 的 CSS 属性

v-show 不支持在 <template> 元素上使用,也不能和 v-else 搭配使用。

v-bind 五系杂灵根

v-bind也成为动态绑定

绑定到属性

1
2
3
4
5
6
7
8
9
<div id="app">
<h3>默认用法</h3>
<input type="text" value="icewolf-li.top">

<h3>绑定value属性</h3>
<input type="text" v-bind:value="web.url"> <br>
<!-- 语法糖,使用冒号 -->
<input type="text" :value="web.name">
</div>

一般是用来绑定html标签属性,例如src,class,value等等

作用是更改标签的属性,不使用v-bind绑定的话,值是默认的字符串

绑定到值

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
<div id="app">
<input type="text" v-model="num">
<br>

<img :src="`img/${num}.jpg`" style="width: 200px;">
<button @click="next">下一张</button>
</div>

<script>
const { createApp,ref,reactive } = Vue;

createApp({
setup() {
const num = ref(1)

function next() {
num.value++
if(num.value > 4) {
num.value = 1
}
}

return {
num,
next
}
}
}).mount('#app')
</script>

使用反引号和${}来引用变量

v-on 运气

v-on 是绑定监听事件,语法糖@

1
2
3
4
5
<!-- 方法处理函数 -->
<button v-on:click="functionName"></button>

<!-- 语法糖 -->
<button @click="functionName"></button>

v-model 双修功法

v-model 可以在表单输入元素或组件上创建双向绑定

仅限:

  • input
  • select
  • textarea
  • components

修饰符:

  • .lazy - 监听 change 事件而不是 input,也就是说失去焦点或回车才更改值
  • .number - 将输入的合法字符串转为数字
  • .trim - 移除输入内容两端空格

实时渲染 <input type="text" v-model='data.text'>
非实时渲染 <input type="text" v-model.lazy='data.text'>

单向绑定无法从input传给Vue对象,双向绑定可以

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
45
46
47
48
49
50
51
52
53
54
55
56
<div id="app">
<h3>文本框 {{ data.text }}</h3>
<h3>单选框 {{ data.radio }}</h3>
<h3>多选框 {{ data.checkbox }}</h3>
<h3>复选框 {{ data.remember }}</h3>
<h3>下拉框 {{ data.select }}</h3>

<!-- 单向数据绑定 -->
<input type="text" :value='data.text'> <br>

<!-- 双向数据绑定 实时渲染-->
<input type="text" v-model='data.text'> <br>

<!-- 双向数据绑定lazy,失去焦点或回车才渲染 -->
<input type="text" v-model.lazy='data.text'> <br>

<!-- 单选框 -->
<input type="radio" v-model="data.radio" value="1">one
<input type="radio" v-model="data.radio" value="2">tow
<br>

<!-- 多选框 -->
<input type="checkbox" v-model="data.checkbox" value="1">one
<input type="checkbox" v-model="data.checkbox" value="2">tow
<br>

<!-- 复选框 -->
<input type="checkbox" v-model="data.remember">记住我
<br>

<!-- 下拉框 -->
<select v-model="data.select">
<option value="">请选择</option>
<option value="1">one</option>
<option value="2">tow</option>
</select>
</div>

<script>
const { createApp,reactive } = Vue

const app = createApp({
setup() {
const data = reactive({
text: 'icewolf-li.top',
radio: '',//单选框
checkbox: [],//多选框
remember: false,//复选框
select: '',//下拉框
})
return {
data
}
}
}).mount('#app')
</script>

v-for 一气化三清

v-for 指令基于一个数组来渲染一个列表。v-for 指令的值需要使用 item in items 形式的特殊语法,其中 items 是源数据的数组,而 item 是迭代项的别名: