vue3.0 学习笔记(重点 及 与vue2不同 的做下记录)
官网:https://vue3js.cn/docs/zh/guide/instance.html 或 https://v3.cn.vuejs.org/guide/migration/introduction.html(推荐,介绍差异的内容)
一、<script setup> 简化 setup() 的写法:
<script setup> import { reactive } from 'vue' const state = reactive({ count: 0 }) function increment() { state.count++ } </script> <template> <button @click="increment"> {{ state.count }} </button> </template>
<script setup>
中的顶层的导入和变量声明可在同一组件的模板中直接使用。你可以理解为模板中的表达式和 <script setup>
中的代码处在同一个作用域中。
二、响应式基础:
- reactive():可以使用 reactive() 函数创建一个响应式对象或数组,响应式对象其实是 JavaScript Proxy。
import { reactive } from 'vue' const state = reactive({ count: 0 })
因为 reactive() 的存在一定的局限性,所以 Vue 提供了一个 ref() 方法来允许我们创建可以使用任何值类型的响应式 ref 对象。
- ref():
import { ref } from 'vue' const count = ref(0) console.log(count) // { value: 0 } console.log(count.value) // 0
- ref 在模板中的解包:
当 ref 在模板中作为顶层属性被访问时,它们会被自动“解包”,所以不需要使用.value
。<script setup> import { ref } from 'vue' const count = ref(0) function increment() { count.value++ } </script> <template> <button @click="increment"> {{ count }} <!-- 无需 .value --> </button> </template>
请注意,仅当 ref 是模板渲染上下文的顶层属性时才适用自动“解包”
- ref 在响应式对象中的解包:
当一个ref
被嵌套在一个响应式对象中,作为属性被访问或更改时,它会自动解包,因此会表现得和一般的属性一样const count = ref(0) const state = reactive({ count }) console.log(state.count) // 0 state.count = 1 console.log(count.value) // 1
- 数组和集合类型的 ref 解包:
跟响应式对象不同,当 ref 作为响应式数组或像 Map 这种原生集合类型的元素被访问时,不会进行解包。const books = reactive([ref('Vue 3 Guide')]) // 这里需要 .value console.log(books[0].value) const map = reactive(new Map([['count', ref(0)]])) // 这里需要 .value console.log(map.get('count').value)
- ref 在模板中的解包:
三、计算属性:computed() 方法期望接收一个 getter 函数,返回值为一个计算属性 ref。
<script setup> import { reactive, computed } from 'vue' const author = reactive({ name: 'John Doe', books: [ 'Vue 2 - Advanced Guide', 'Vue 3 - Basic Guide', 'Vue 4 - The Mystery' ] }) // 一个计算属性 ref const publishedBooksMessage = computed(() => { return author.books.length > 0 ? 'Yes' : 'No' }) </script> <template> <p>Has published books:</p> <span>{{ publishedBooksMessage }}</span> </template>
四、生命周期:
<script setup> import { onMounted } from 'vue' onMounted(() => { console.log(`the component is now mounted.`) }) </script>
五、侦听器:
<script setup> import { ref, watch } from 'vue' const question = ref('') const answer = ref('Questions usually contain a question mark. ;-)') // 可以直接侦听一个 ref watch(question, async (newQuestion, oldQuestion) => { if (newQuestion.indexOf('?') > -1) { answer.value = 'Thinking...' try { const res = await fetch('https://yesno.wtf/api') answer.value = (await res.json()).answer } catch (error) { answer.value = 'Error! Could not reach the API. ' + error } } }) </script> <template> <p> Ask a yes/no question: <input v-model="question" /> </p> <p>{{ answer }}</p> </template>
六、模板引用(即DOM引用)
为了通过组合式 API 获得该模板引用,我们需要声明一个同名的 ref:
<script setup> import { ref, onMounted } from 'vue' // 声明一个 ref 来存放该元素的引用 // 必须和模板里的 ref 同名 const input = ref(null) onMounted(() => { input.value.focus() }) </script> <template> <input ref="input" /> </template>
七、组件基础