Vue.js初体验:踏入前端开发的灵活世界
前言
在前端领域,众多框架和库的涌现使得开发变得更加高效和灵活。Vue.js(简称Vue)作为其中一员,在其简洁而强大的特性下,吸引了越来越多的开发者。本文将分享我的Vue初体验,探索这个流行的JavaScript框架的基本概念和使用感受。篇尾附上一个实战小demo。
Vue.js:轻巧而强大
Vue.js是一款渐进式JavaScript框架,专注于构建用户界面。相比于其他框架,Vue更加轻量,容易上手,同时在大型项目中也能展现出强大的表现。它由尤雨溪(Evan You)于2014年创建,并迅速在开发者社区中崭露头角。
我的第一个Vue实例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title></title>
</head>
<body>
<div id="app"></div>
<template id="tel">
<h3>{{message}}</h3>
</template>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script>
Vue.createApp({
template: '#tel',
data: function () {
// 数据存放的地方
return {
message: 'Hello BiangBiang!'
}
}
}).mount('#app')
</script>
</body>
</html>
解释:
<div id="app">
:定义一个带有ID为 "app" 的空<div>
元素,作为Vue应用的挂载点。<template id="tel">...</template>
:使用了Vue 3的模板语法,定义了一个模板,其中有一个<h3>
标签,通过{{message}}
插值语法展示一个动态的文本。这个模板被放在了<template>
标签中,并通过ID为 "tel" 的模板标签进行引用。<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
:引入Vue 3的全局构建,这是通过UNPKG提供的CDN链接引入Vue库。
可在Vue.js的官网找到:
Vue.createApp({...})
:通过Vue.createApp
方法创建了一个Vue应用实例。template: '#tel'
:在Vue应用实例中指定了模板,使用了之前定义的ID为 "tel" 的模板。data: function () {...}
:定义了一个数据属性message
,初始值为 'Hello BiangBiang!'。.mount('#app')
:将Vue应用实例(也就是上述创建的app)挂载到ID为 "app" 的HTML元素上,使Vue应用能够在该元素内进行渲染和交互。
效果:
初次学的时候还没一眼看出Vue的优势,心想原本一行可以解决的代码却写的这么麻烦,可又很简单能想到,实际项目开发代码量是巨大的,Vue的优势到那个时候想必就能体现出来了。由于本人还刚初次接触,只了解Vue的一些优势,有的优势看了也不是很能理解,下面引用网上给出的Vue开发的优势。
- 简洁易学: Vue.js的设计简单直观,易于学习和上手。Vue提供了清晰的文档和逐步增量的学习曲线,使新手能够快速入门。
- 响应式数据绑定: Vue采用了双向数据绑定,当数据发生变化时,视图会自动更新,反之亦然。这简化了DOM操作,提高了开发效率。
- 组件化开发: Vue推崇组件化开发思想,将一个应用划分为多个独立的组件,每个组件负责自己的状态和视图。这使得代码更易于维护、复用和测试。
- 灵活性: Vue并不强制使用特定的工具链,可以逐步采用,也可以与其他库和项目无缝集成。这种灵活性使得Vue可以适应各种项目规模和需求。
- 渐进式框架: Vue是一个渐进式框架,可以根据项目的需要逐步引入。你可以选择只使用Vue的一部分功能,如只使用Vue的数据绑定而不使用其它特性。
- 虚拟DOM: Vue使用虚拟DOM来提高性能。通过在内存中维护一个虚拟DOM树,Vue能够在数据变化时计算出最小化的DOM更新,从而减少真实DOM操作的次数,提高页面渲染效率。
- 社区和生态系统: Vue拥有庞大而活跃的社区,开发者可以从社区获取支持、学习经验,并分享自己的知识。此外,Vue的生态系统也在不断壮大,有许多插件和第三方库可供选择。
- 适用于单页应用(SPA): Vue对单页应用提供了良好的支持,通过Vue Router进行路由管理,通过Vuex进行状态管理,使得开发复杂的前端应用变得更加容易。
- 良好的性能: Vue的虚拟DOM和合理的更新策略使得应用具有良好的性能表现,同时Vue 3引入了一些新的优化策略,进一步提升了性能。
以上9点我目前并没有全部切身感受到,其中第1,2,5,6点目前都能感受到一点,我等下也会通过最近的学习来举例,但是相信不出一个月,我对Vue的认识也会更深一步。到时候也可以给大家分享更深层次的Vue的学习体验。下面简单介绍一下最近学习的Vue的部分指令,以及computed和watch的基本使用。
Vue指令
1.v-html
- 作用:插入HTML
- 例子:
<div v-html="info"></div>
,将info
中的HTML代码插入到元素中。
2.v-text
- 作用:插入文本
- 例子:
<div v-text="msg"></div>
,将msg
中的文本代码插入到元素中。
<body>
<div id="app"></div>
<template id="my-app">
<div>{{msg}}</div>
<div v-text="msg"></div>
<div v-html="info"></div>
</template>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script>
const App = {
template:'#my-app',
data(){
return {
msg:'hello World!',
info:`<h1>这是一个富文本</h1>`
}
}
}
Vue.createApp(App).mount('#app')
</script>
</body>
3.v-once
- 作用:只渲染一次渲染了一次就不再渲染了
- 例子:
<h1 v-once>{{count}}</h1>
,count变化一次之后就不会再变了,如下图。
不加该属性:
加上该属性:
代码案例:
<body>
<div id="app"></div>
<template id="my-app">
<h2>{{count}}</h2>
<button @click="add">+1</button>
<!-- v-once 只渲染一次 变了一次之后就不会再变了 -->
<h1 v-once>{{count}}</h1>
</template>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script>
const App = {
template: '#my-app',
data() {
return {
count: 100
}
},
methods:{
add(){
this.count++;
}
}
}
Vue.createApp(App).mount('#app')
</script>
</body>
可以看到加上了v-once之后,原本都需要增加的下面的点击确不会再增加了。
4.v-bind
- 作用:进行属性绑定,可以v-bind:class(动态类名) 也可以 v-bind:style(样式)
- 例子:
<a v-bind:href="url">Link</a>
,将href
属性绑定到url
变量。
5.v-on
- 作用:进行事件绑定,可简写成@事件名
- 例子:
<button v-on:click="change">按我</button>
,当按钮被点击时执行change
方法。
6.v-pre
- 语法:
v-pre
- 例子:
<span v-pre>{{ 这里不会被编译,而是连同括号一起输出 }}</span>
,使元素和它的所有子节点都跳过编译。
7.v-if
效果展示:
8.v-show
- 作用:条件显示 ,v-show = "条件"
- 例子:
<p v-show="isShown">Hello World</p>
,根据isShown
的值决定是否显示元素。
值得注意的是:相比于上面的v-if等等, v-show存在一个弊端,v-show是直接修改style属性 ,将display改为none ,而上面的是直接删除动物结构或者添加动物结构,所以它消失后不会允许用户右键检查直接修改display属性,而v-show可以。但是v-show也有好处,由于v-if是直接删除或添加动物结构,但在频繁切换时可能涉及到DOM的销毁和创建,带来一些性能开销。而v-show更适用于需要频繁切换的场景,它的性能开销较小。
9.v-for
- 作用:循环渲染 v-for="item in items" 或 v-for="(item,index) in items"
- 例子:
<li v-for="item in items">{{ item.text }}</li>
,根据数组items
的内容渲染列表项。
效果展示:
<body>
<div id="app"></div>
<template id="my-app">
<h2>歌曲列表</h2>
<ul>
<!-- 使用v-for时 常在v-for其后加上 :key="唯一且不同的标识" 否则性能就会降低 ,但下面这个index其实也没有用 这个以后再了解 -->
<li v-for="(item ,index) in songs" :key="index" v-if="">{{index+1}}--{{item}}
<a href="#" @click="del(index)">x</a>
</li>
</ul>
</template>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script>
const App = {
template: '#my-app',
data() {
return {
songs: [
'说好不哭',
'稻香',
'说好的幸福呢',
'等你下课',
'告白气球',
'半岛铁盒',
'夜曲'
]
}
},
methods:{
del(i){
this.songs.splice(i, 1);
}
}
}
Vue.createApp(App).mount('#app')
</script>
</body>
计算属性computed
- 动态更新
直接上案例:
<body>
<div id="app"></div>
<template id="my-app">
<h2>今天温度:{{temp}}°</h2>
<h3>温馨提示:建议出门穿:{{suggestion}}</h3>
<button @click="add">+</button>
<button @click="down">-</button>
</template>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script>
const App = {
template: '#my-app',
data() {
return {
temp: 10,
}
},
computed: {
// computed 里面的属性时响应式执行 执行条件是当它依赖的数据源发生变化时(如:下述案例为temp) 它才会执行
suggestion() {
let res = '夹克'
if (this.temp >= 20) {
res = '短袖'
} else if (this.temp <= 0) {
res = '棉袄'
} else {
res = '夹克'
}
return res
}
},
methods: {
add() {
this.temp += 5
},
down() {
this.temp -= 5
}
}
}
Vue.createApp(App).mount('#app')
</script>
</body>
效果如下:
上述代码,我们将suggestion函数放在methods里面也能执行,但是为什么还要增加一个computed计算属性呢。这是因为计算属性它是依赖缓存的,它只有依赖关系发生了变化,计算属性才会重新计算。这也意味着在多次访问相同的计算属性时,Vue会返回之前计算的结果,而不用重新计算,这显然提高了性能。而methods每次调用都会执行一次,这也是计算属性的优势之处。
侦听器watch
- 添加侦听,也可以进行动态更新
<body>
<div id="app"></div>
<template id="my-app">
<h2>今天温度:{{temp}}°</h2>
<h3>温馨提示:建议出门穿:{{suggestion}}</h3>
<button @click="add">+</button>
<button @click="down">-</button>
</template>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script>
const App = {
template: '#my-app',
data() {
return {
temp: 30,
suggestion: '夹克'
}
},
watch: { // 侦听器
// 侦听temp数据
temp: {
// newVal:新改变的值 oldVal:原先的值
handler: function (newVal, oldVal) {
if (newVal >= 20) {
this.suggestion = '短袖'
} else if (newVal <= 0) {
this.suggestion = '羽绒服'
} else {
this.suggestion = '夹克'
}
},
// 加载页面时立即执行一遍上面的handler函数,(因为我们拿到得温度初始值可能是30,但默认的是夹克,显然不合理)
immediate:true
}
},
methods: {
add() {
this.temp += 5
},
down() {
this.temp -= 5
}
}
}
Vue.createApp(App).mount('#app')
</script>
</body>
效果和上述computed计算属性是一样的,不过它可以加一个属性immediate,当值为true时表示加载页面的时候就会立即执行一遍。正好会覆盖掉我们设置的初始值。
了解了上面这些之后,下面是一个简单的实战小demo,刚接触Vue的可先自行完成,效果如下:
附上上述小demo的代码:
HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="./style.css">
</head>
<body>
<div id="app"></div>
<template id="my-app">
<table>
<thead>
<th>序号</th>
<th>书籍名称</th>
<th>出版日期</th>
<th>价格</th>
<th>购买数量</th>
<th>操作</th>
</thead>
<tbody>
<tr v-for="(book,index) in books" :key="index">
<td>{{book.id}}</td>
<td>{{book.name}}</td>
<td>{{book.date}}</td>
<td>{{book.price}}</td>
<td>
<button @click="down(index)">-</button>
<span class="counter">{{book.count}}</span>
<button @click="add(index)">+</button>
</td>
<td>
<button @click="remove(index)">移除</button>
</td>
</tr>
</tbody>
</table>
<h2>总价格: {{totalPrice}} </h2>
</template>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script src="./index.js"></script>
</body>
</html>
CSS:
table {
border: 1px solid #e9e9e9;
border-collapse: collapse;
border-spacing: 0;
}
th, td {
padding: 8px 16px;
border: 1px solid #e9e9e9;
text-align: left;
}
th {
background-color: #f7f7f7;
color: #5c6b77;
font-weight: 600;
}
.counter {
margin: 0 5px;
}
JS:
Vue.createApp({
template: "#my-app",
data() {
return {
books: [
{
id: 1,
name: '《算法导论》',
date: '2006-9',
price: 85.00,
count: 0
},
{
id: 2,
name: '《UNIX编程艺术》',
date: '2006-2',
price: 59.00,
count: 0
},
{
id: 3,
name: '《编程珠玑》',
date: '2008-10',
price: 39.00,
count: 0
},
{
id: 4,
name: '《代码大全》',
date: '2006-3',
price: 128.00,
count: 0
},
],
}
},
computed: {
totalPrice() {
// 两种计算价格的方式都可以
// return this.books.reduce((sum, book) => {
// return sum + book.price * book.count;
// }, 0);
let sum = 0;
for (let i = 0; i < this.books.length; i++) {
sum += this.books[i].price * this.books[i].count;
}
return sum;
},
},
methods: {
add(index) {
this.books[index].count++;
},
down(index) {
if (this.books[index].count != 0) {
this.books[index].count--;
}
},
remove(index) {
this.books.splice(index, 1);
}
}
}).mount("#app");
留言
博主刚接触Vue,可能上述内容比较简单,以后随着学习的深入,我还会持续更新质量更高的内容♥(ˆ◡ˆԅ)。
转载自:https://juejin.cn/post/7307185449440182306