VueJS 总结

使用Vue有一段时间了,可能因为使用场景比较少,一直都感觉不得要领,最近终于有一种融会贯通的感觉了,理解了大部分使用场景 和技巧。这篇文章是我的总结。

简单示例

比起官网的写法,对于后端开发人员来说,我觉得新式的 Composition API + Single File Components 的写法会更容易让人理解, 这是一个例子:

<script setup>
import { ref } from 'vue'
const count = ref(0)
</script>

<template>
  <button @click="count++">Count is: {{ count }}</button>
</template>

<style scoped>
button {
  font-weight: bold;
}
</style>
  • <script setup></script> 部分,就是JS逻辑处理的内容
  • <template></template> 部分,就是模板内容,在里面写页面的模块,比如表单、按钮、弹窗等等
  • <style scoped></style> 部分,就是CSS样式

每一个页面,对应一个 Single File Components 文件,比如 main.vue / home.vue 等等。

构建工具

前端需要使用构建工具,可以提高开发效率,以前大部分都是使用 yarn,现在比较流行一个新型的工具,叫做 vite,使用方法如下:

$ npm create vite@latest

执行完成之后,照着提示一步步操作就可以,对于Vue项目,就选择Vue,然后选择JS或者TS。

项目结构

初始化完成之后,就可以看到如下的一个结构:

demovite $ tree
.
├── index.html
├── package.json
├── public
│   └── vite.svg
├── README.md
├── src
│   ├── App.vue
│   ├── assets
│   │   └── vue.svg
│   ├── components
│   │   └── HelloWorld.vue
│   ├── main.js
│   └── style.css
└── vite.config.js

5 directories, 10 files

其实渲染以后,浏览器首先加载的仍然是 index.html,我们来看看内容:

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="/vite.svg" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Vite + Vue</title>
  </head>
  <body>
    <div id="app"></div>
    <script type="module" src="/src/main.js"></script>
  </body>
</html>

可以看到 body 里,有一个div,id是 app,紧接着就是执行路径为 /src/main.js 的JS:

import { createApp } from 'vue'
import './style.css'
import App from './App.vue'

createApp(App).mount('#app')

这段JS的内容很好理解,import部分就和后端的语言里的导入是一样的,真正执行的地方,就是 createApp(App).mount('#app'), 这里就是找到id为 app 的DOM元素,然后开始执行代码操作DOM渲染页面。

而我们这里,App.vue 就是第一个页面:

<script setup>
import HelloWorld from './components/HelloWorld.vue'
</script>

<template>
  <div>
    <a href="https://vitejs.dev" target="_blank">
      <img src="/vite.svg" class="logo" alt="Vite logo" />
    </a>
    <a href="https://vuejs.org/" target="_blank">
      <img src="./assets/vue.svg" class="logo vue" alt="Vue logo" />
    </a>
  </div>
  <HelloWorld msg="Vite + Vue" />
</template>

<style scoped>
.logo {
  height: 6em;
  padding: 1.5em;
  will-change: filter;
  transition: filter 300ms;
}
.logo:hover {
  filter: drop-shadow(0 0 2em #646cffaa);
}
.logo.vue:hover {
  filter: drop-shadow(0 0 2em #42b883aa);
}
</style>

这里就可以看到我们最上面描述的三个段落:<script setup></script>, <template></template>, <style scoped></style>

Vue UI 框架

鉴于我们是后端,写UI自然是不太熟悉的,因此我们需要一个UI框架,这样我们可以直接使用里面提供的UI组件,不需要自己去改样式。 Vue常用的就是这么几个:

  • element-plus 饿了么出品的,饿了么风格的UI
  • Vuetify Material Design 风格的UI
  • BootstrapVue 使用Bootstrap的UI
  • Ant Design Vue Ant Design 风格的UI

这个就看个人喜好,选择一个就可以。

VueJS 语法简介

变量

VueJS是一个前端的MVVM框架,啥意思呢?就是以前我们需要执行JS去更改DOM,这样UI才会发生变化,但是现在,我们可以直接改变内存 中的一个变量,VueJS会自动将变量的值结合模版,然后自动更改DOM。这个只有使用了才能感受出来,开发效率真的高很多。

并不是任意变量VueJS都能监听到变化的,必须是它包装的或者支持的,下面这些就是了:

  • ref: 比如 const count = ref(0),只要 count.value 发生了变化,他就会监测到
  • reactive: 和ref一样,不过reactive是直接监听一个object,而且使用的时候,可以直接用,而不需要像ref那样使用 count.value。例如:const state = reactive({ count: 0 }),直接使用 state.count 即可

这两个的文档在 https://vuejs.org/guide/essentials/reactivity-fundamentals.html 请一定仔细阅读。

模板语法

对于后端开发来说,尤其是使用过后端的模版引擎的开发者来说,应该不难,参考文档 https://vuejs.org/guide/essentials/template-syntax.html 直接写HTML,在需要使用变量的地方,使用双括号即可:

<span>Message: {{ msg }}</span>

使用冒号来绑定属性,例如 <div v-bind:id="dynamicId"></div>,可以简写为 <div :id="dynamicId"></div>

使用 @ 来监听事件:

<a v-on:[eventName]="doSomething"> ... </a>

<!-- shorthand -->
<a @[eventName]="doSomething">

使用 v-if, v-else, v-else-if, v-show 来进行条件渲染。

computed 和 watch

有一些变量需要根据别的变量计算,才能得到值,或者一个变量变化的时候,我们希望另一个变量跟着变化,这个时候,就需要使用 computed

而有时候我们希望监听某个值,当然发生了变化,我们进行一些操作,这个时候就使用 watch,我们来看看GPT对他两的对比和总结:

Computed Properties (计算属性):

定义: 计算属性是基于它们的依赖进行计算的响应式属性。当依赖项发生变化时,计算属性会重新计算。 用途: 主要用于数据的转换和组合。例如,从原始数据派生出新的数据。 缓存: 计算属性是基于它们的响应式依赖进行缓存的。只有当依赖项发生变化时,计算属性才会重新计算。这意味着只要依赖项保持不变,多次访问计算属性会立即返回之前的计算结果,而不会重新执行函数。 示例场景: 如根据用户的名和姓计算出一个完整的姓名。 Watchers (侦听器):

定义: 侦听器用于观察和响应 Vue 实例上数据的变化。当侦听的数据变化时,会执行一个回调函数。 用途: 主要用于执行数据变化时的副作用(side effects),如异步操作或较长的运算。 方式: 侦听器不会返回一个值,而是在数据变化时执行代码。 示例场景: 如在用户更改数据后发送 AJAX 请求。 总结:

用途区别: computed 用于计算值的派生和转换,而 watch 用于响应数据的变化执行异步操作或昂贵的操作。 性能考虑: computed 属性由于其缓存特性,对于性能要求较高的场景更合适。 应用场景: 选择 computed 还是 watch 取决于具体的应用场景和需求。对于任何可以用计算属性实现的功能,优先考虑使用计算属性,只有在需要执行异步操作或复杂逻辑时才使用侦听器。

路由

页面之间如果需要跳转咋办呢?这个时候就需要一个路由框架,对于Vue的项目来说,一般都是使用 vue-router

// 1. Define route components.
// These can be imported from other files
const Home = { template: '<div>Home</div>' }
const About = { template: '<div>About</div>' }

// 2. Define some routes
// Each route should map to a component.
// We'll talk about nested routes later.
const routes = [
  { path: '/', component: Home },
  { path: '/about', component: About },
]

// 3. Create the router instance and pass the `routes` option
// You can pass in additional options here, but let's
// keep it simple for now.
const router = VueRouter.createRouter({
  // 4. Provide the history implementation to use. We are using the hash history for simplicity here.
  history: VueRouter.createWebHashHistory(),
  routes, // short for `routes: routes`
})

// 5. Create and mount the root instance.
const app = Vue.createApp({})
// Make sure to _use_ the router instance to make the
// whole app router-aware.
app.use(router)

app.mount('#app')

// Now the app has started!

状态管理

前端需要管理一些状态,比如登陆状态,对于这类需求,一般使用 vuex,现在最新版的,就是 pinia

总结

以上就是我对VueJS知识的理解和整理,只是一个大纲,具体的内容,其实是需要每个文档都读一遍,写一遍,理解一遍才能 真正掌握的。


Refs:


更多文章
  • 使用 gomock 测试 Go 代码
  • gevent不是黑魔法(二): gevent 实现
  • gevent不是黑魔法(一): greenlet 实现
  • 用 entgo 替代 gorm
  • 应用内使用crontab不是那么方便
  • 单测时要不要 mock 数据库?
  • Sentry 自建指南
  • 用selenium完成自动化任务
  • 用闲置的安卓手机做垃圾电话短信过滤
  • 推荐三个时间管理工具
  • 一次事故反思
  • 当JS遇到uint64:JS整数溢出问题
  • SQLite3 存储以及ACID原理
  • Redis源码阅读:pub/sub实现
  • Redis源码阅读:zset实现