前置知识
ES
ES modules 是原生 JavaScript 提供的模块功能,逐渐被更多的浏览器支持
形如:
1 2 3 4 5 6 7 8 9
| <script type="module"> <!-- something --> </script>
<script> import { x,y } from './module.js </script>
|
vue基础
应用
每个 Vue 应用都是通过createApp函数创建一个新的应用实例,例如:
1 2 3 4
| import { createApp } from 'vue' import App from './App.vue'
const app = createApp({App})
|
createApp 的对象实际上是一个组件,每个应用都需要一个“根组件”,其他组件将作为其子组件,最后得到一个树状结构
模板
当根组件没有设置 template 选项时,Vue 将自动使用容器的 innerHTML 作为模板
模板中可以使用指令,指令由 v- 作为前缀,表明它们是一些由 Vue 提供的特殊 attribute,指令最常用的功能是绑定html属性到某个元素
双大括号会将数据解释为纯文本,而不是 HTML。若想插入 HTML,需要使用 v-html 指令:
<span v-html="rawHtml"></span></p>
想要响应式地绑定一个 attribute,应该使用 v-bind 指令<div v-bind:id="dynamicId"></div>
简写语法为:<div :id="dynamicId"></div>
同名简写(3.4以上版本):<div :id></div>
js表达式支持:
1 2 3 4 5 6
| {{ number + 1 }} {{ ok ? 'YES' : 'NO' }} {{ message.split('').reverse().join('') }} <div :id="`list-${id}`"></div>
|
响应式
这里使用选项式api,使用data 选项来声明组件的响应式状态。此选项的值应为返回一个对象的函数
在 Vue 3 中,数据是基于JavaScript Proxy 实现响应式的,也就是通过一个代理来更新对象状态,vue3中原始对象不会变成响应式代理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| export default { data() { return { count: 0 } }, methods: { increment() { this.count++ } }, mounted() { this.increment() } }
|
Vue 自动为 methods 中的方法绑定了永远指向组件实例的 this,且嵌套的对象变化也能相应,也就是类似json的格式可以随意修改
当你修改了响应式状态时,DOM 会被自动更新。但是需要注意的是,DOM 更新不是同步的。Vue 会在“next tick”更新周期中缓冲所有状态的修改,以确保不管你进行了多少次状态修改,每个组件都只会被更新一次
创建有自己状态的方法:
如果需要多个有独立状态的方法,则要在created期间创建这样的函数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| export default { created() { this.debouncedClick = _.debounce(this.click, 500) }, unmounted() { this.debouncedClick.cancel() }, methods: { click() { } } }
|
常用api
vue内置指令 常用的用v-bind,v-model,v-if,v-for等,语法都很符合直觉 在组合式 API 中,通过setup脚本块来初始化需要的数据和函数(包括响应式状态),常用 ref()
函数来声明响应式状态:const count = ref(0)
脚本中访问count的值需要解包,即通过count.value
访问,但在模板块中可以自动解包(只有顶级的 ref 属性才会被解包,被包裹在一个列表中的ref不会解包)
要在组件模板中访问 ref,需要从组件的 setup()
函数中声明并返回它们:
1 2 3 4 5 6 7 8 9 10 11 12 13
| import { ref } from 'vue'
export default { setup() { const count = ref(0)
return { count } } }
|
计算属性 ref:形如以下的ref,computed()
方法期望接收一个 getter 函数,返回值为一个计算属性 ref,用法类似数据的ref,与function的区别是能追踪响应式状态,且响应式状态不改变就不会重新计算
1 2 3
| const publishedBooksMessage = computed(() => { return author.books.length > 0 ? 'Yes' : 'No' })
|
路由
创建: history
选项控制了路由和 URL 路径是如何双向映射的,详见不同的历史记录模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| import { createMemoryHistory, createRouter } from 'vue-router'
import HomeView from './HomeView.vue' import AboutView from './AboutView.vue'
const routes = [ { path: '/', component: HomeView }, { path: '/about', component: AboutView }, ]
const router = createRouter({ history: createMemoryHistory(), routes, })
|
路由作为一个插件被使用: 1 2 3
| const app = createApp(App) app.use(router) app.mount('#app')
|
组合式api中,用useRouter() ;useRoute()
两个函数获取路由器实例和当前路由;组件 RouterView
和 RouterLink
都是全局注册的,可以直接调用,最简单地做法是APP.vue直接整个渲染当前路径的RouterView
routes可以使用参数或者正则匹配,详见官网文档
Pinia 是 Vue 的专属状态管理库,可以帮助我们管理共享状态,也就是一些我们希望定义在组件外部,全局可用的状态
引入:
1 2 3 4 5 6 7 8 9
| import { createApp } from 'vue' import { createPinia } from 'pinia' import App from './App.vue'
const pinia = createPinia() const app = createApp(App)
app.use(pinia) app.mount('#app')
|