使用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>
。
鉴于我们是后端,写UI自然是不太熟悉的,因此我们需要一个UI框架,这样我们可以直接使用里面提供的UI组件,不需要自己去改样式。 Vue常用的就是这么几个:
这个就看个人喜好,选择一个就可以。
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
,我们来看看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: