単一ファイルコンポーネント
(1)<スクリプトの設定>
<script setup> は、単一ファイル コンポーネント (SFC) で構成 API を使用するためのコンパイル時の構文糖です。この構文は、SFC と複合 API の両方を使用する場合のデフォルトの推奨事項です。
この構文を有効にするには、setup 属性を <script> コード ブロックに追加する必要があります。これにより、内部のコードがコンポーネントの setup() 関数のコンテンツにコンパイルされます。
通常の <script> は、コンポーネントが最初に導入されたときに 1 回だけ実行されます。
<script setup> 内のコードは、コンポーネント インスタンスが作成されるたびに実行されます。
<script setup> はコンポーネントの先頭に記述する必要があります
(2) 入口
setup() フックは、コンポーネントで合成 API を使用するためのエントリ ポイントです。
記述方法:setup(){ }
注: セットアップではこれを使用しないでください。
(3) 実行タイミング
実行タイミング: コンポーネントが作成される前に実行します。
beforeCreate および作成された関数の代わりにセットアップ フックを使用します。すべての vue3 には beforeCreate および created フック関数はありません。
2.使用する
(1) トップレベルのバインディングがテンプレートに公開されます
<script setup> を使用する場合、<script setup> 宣言の最上位レベルのバインディング (変数、関数宣言、インポートインポートを含む) をテンプレート内で直接使用できます。
インポートされたコンテンツも同様に公開されます。インポートされた関数は、メソッド オプションを介して公開しなくても、テンプレート式で直接使用できます。
<script setup>
import ToDoHeader from './SetupToDoHeader.vue'
// 使用任<script setup> 其中声明的顶层的绑定 (包括变量,函数声明,以及 import 导入的内容) 都能在模板中直接使用, 不需要再使用components, methods, data()等注册:
</script>
<template>
<ToDoHeader @add="addList" @deleteAll="delAll"> </ToDoHeader>
</template>
(2) 小道具の使用
// 用于接收父组件传的的值 props的用法
// 方式1
// const props = defineProps(['todoList'])
// 方式2
const props = defineProps({
todoList:{
type: Array,
require: true,
},
title:{
type: String,
default: '待办事项'
},
flag: {
type: Boolean,
defalut: false
}
})
(3) レスポンシブ ref()
Responsive ref(): 内部値 (数値|文字列) を受け入れ、内部値を指すプロパティが 1 つだけある、応答性の変更可能な ref オブジェクトを返します。
//使用前引入
import { ref,reactive } from 'vue'
// 此处声明的是 非响应式的
const msg = 'Hello!'
// 使用ref ,使得变量成为 响应式的, 使用前先引入 数组在删除时, 有问题, 故改为对象的形式进行删除
const todoVal = ref('')
// 避免使用this 常量修改值时, 需要通过 .value来修改, 在显示时不需要.value
(4) リアクティブ応答プロキシ
const obj = reactive({ todoList : [] })
// reactive(引用类型) 响应式代理
// const obj = reactive({})
リアクティブ オブジェクトのプロパティに基づいて、対応する参照を作成します。このようにして作成された参照は、そのソース プロパティとの同期が維持されます。ソース プロパティの値を変更すると、参照の値が更新され、その逆も同様です。
toRef()
const state = reactive({
foo: 1,
bar: 2
})
const fooRef = toRef(state, 'foo')
// 更改该 ref 会更新源属性
fooRef.value++
console.log(state.foo) // 2
// 更改源属性也会更新该 ref
state.foo++
console.log(fooRef.value) // 3
これは次のものとは異なることに注意してください。
const fooRef = ref(state.foo)
ref() はプレーンな値を受け取るため、上記の ref は state.foo との同期が保たれません。
toRefs()
リアクティブ オブジェクトを通常のオブジェクトに変換します。この通常のオブジェクトの各プロパティは、ソース オブジェクトの対応するプロパティを指す参照です。個々の ref は toRef() を使用して作成されます。
const state = reactive({
foo: 1,
bar: 2
})
const stateAsRefs = toRefs(state)
/*
stateAsRefs 的类型:{
foo: Ref<number>,
bar: Ref<number>
}
*/
// 这个 ref 和源属性已经“链接上了”
state.foo++
console.log(stateAsRefs.foo.value) // 2
stateAsRefs.foo.value++
console.log(state.foo) // 3
//当从组合式函数中返回响应式对象时,toRefs 相当有用。使用它,消费者组件可以解构/展开返回的对象而不会失去响应性:
function useFeatureX() {
const state = reactive({
foo: 1,
bar: 2
})
// ...基于状态的操作逻辑
// 在返回时都转为 ref
return toRefs(state)
}
// 可以解构而不会失去响应性
const { foo, bar } = useFeatureX()
(5)計算された()
//创建一个可写的计算属性 ref:
const count = ref(1)
const plusOne = computed({
get: () => count.value + 1,
set: (val) => {
count.value = val - 1
}
})
(6)watch()/watchEffect()
watch() は 1 つ以上のリアクティブ データ ソースをリッスンし、データ ソースが変更されたときに指定されたコールバック関数を呼び出します。
import { ref , watch, watchEffect} from 'vue'
const before = ref(0)
const after = ref(0)
// watch() 默认是懒侦听的(深度侦听),即仅在侦听源发生变化时才执行回调函数
watch(props.todoList, (newList, preList)=>{
after.value = newList.filter(item=>item.done).length
before.value = newList.length - after.value
})
// 立即执行 一个函数,同时响应式地追踪其依赖,并在依赖更改时重新执行
// watchEffect(()=>console.log(before.value++))
// 停止侦听器
// const stop = watchEffect(()=>{})
// stop()
(7) 提供および注入
import { provide } from 'vue'
// 向后代传参 provide(键,值)
// 提供静态值
provide('msg','hahahaah')
// 提供响应式的值
const count = ref(0)
provide('count',count)
// 接收发送方传递的值
const message = inject('msg')
(8) 親コンポーネントに値を渡す
//子组件
// 向父组件传值
<script setup>
// 向父组件传值
const emit = defineEmits(['add'])
const addList = ()=>{
emit('add', todoVal.value) //传值时需要使用 .value
todoVal.value = ''
}
const delAll = () => {
emit('deleteAll')
}
</script>
<template>
<header>
<span class="submit" @click="addList">提交</span>
<span class="clear" @click="delAll">清空</span>
</header>
</template>
//父组件
<script setup>
// 避免使用this 常量修改值时, 需要通过 .value来修改, 在显示时不需要.value
const addList = (todoVal)=> {
if (todoVal=== '') return alert('输入内容不能为空!!!')
obj.todoList.unshift({
// id : `${new Date().getTime()}`,
todoName: todoVal,
done: false
});
}
// 删除单个
const delOne = index =>{
obj.todoList.splice(index,1)
}
//删除全部
const delAll = ()=>{
// 从索引为0的开始全删掉 如果使用直接让数组=[]的方式,只是清空了数组, 地址没有变, 无法触发watch监听 使用todoList.value.splice(0) 或 todoList.value.length=0的方式清空 todoList如果是数组需要 .value, 对象不需要写
obj.todoList.splice(0)
}
</script>
<template>
<ToDoHeader @add="addList" @deleteAll="delAll"> </ToDoHeader>
</template>