Vue3笔记
创建组件并绑定到DOM
import { createApp } from 'vue';
import MyApp from './MyApp.vue';const myApp = createApp(MyApp);
myApp.mount('#myApp'); // <div id="myApp"></div>
Vue文件示例
<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>
全局错误处理
myApp.config.errorHandler = (error) => {};
模板语法
文本插值
<!--
import { ref } from 'vue';
const userName = ref("");
-->
<p>Hello, {{ userName }}!</p>
绑定动态属性
<!-- 绑定属性 -->
<p v-bind:id="dynamicId"></p>
<p :id="dynamicId"></p>
<p v-bind:id></p> <!-- 等效于 v-bind:id="id",下同 -->
<p :id></p><!-- 绑定多个属性 -->
<!--
const multiplyAttributes = {id: 'myId',class: 'myClass',style: 'background-color:green'
};
-->
<div v-bind="multiplyAttributes"></div><!-- 绑定参数 -->
<a v-bind:href="url"></a>
<a :href="url"></a><!-- 条件指令 -->
<div v-if="display"></div>
<div v-show="display"></div><div v-if="type === 'A'"></div>
<div v-else-if="type === 'B'"></div>
<div v-else></div><!-- 绑定事件 -->
<div v-on:click="clickFunction"></div>
<div @click="clickFunction"></div><!-- 绑定动态参数/事件 -->
<a v-bind:[dynamicAttributeName]="url"></a>
<a :[dynamicAttributeName]="url"></a>
<div v-on:[dynamicEventName]="functionName"></div>
<div @[dynamicEventName]="functionName"></div><!-- 修饰符 -->
<div @submit.prevent="submitFunction"></div> <!-- 调用event.preventDefault() --><!-- 绑定样式类 -->
<!--
const isActive = ref(true);
// 当isActive为真时,渲染为 <div class="active"></div> 。
-->
<div :class="{ active:isActive }"></div><!-- 列表渲染 -->
<li v-for="item in items">{{ item.name }}
</li>
<li v-for="(item,index) in items">{{ index }} {{ item.name }}
</li>
<span v-for="n in 10"> {{ n }} </span> <!-- 渲染1..10。 --><MyComponent v=for="item in items" :key="item.id" />
<MyComponent v-for="(index,item) in items" :key="item.id" :index="index" :item="item" />
声明响应状态并发布
<script setup>
import { ref } from 'vue';
const count = ref(0);function increaseCount() {count.value++;
}
</script>
组件
注册组件
<script setup>
import MyComponent from './MyComponent.vue';
</script>
声明属性
<script setup>
defineProps(['foo']);
defineProps({name: String
});
</script>
监听属性变化
<script setup>
const props = defineProps(['foo']);
watchEffect(() => { console.log(props.foo); });
</script>
声明自定义事件
<script setup>
const emit = defineEmits(['foo', 'bar']);function fire() {emit('foo');
}
</script>
定义模型
<script setup>
const first = defineModel(first');
const second = defineModel(second');
</script><template>
<input type="text" v-model="first" />
<input type="text" v-model="second" />
</template>
模型实际上是双向的ref。每个v-model只包含一个简单的状态,并非整个组件整体状态的聚合。组件的整体状态由多个v-model组成。
响应状态ref、属性props、模型model的区别
响应状态用于单向输出,负责控制界面状态。属性用于单向输入,负责向组件传递信息。模型用于双向绑定,用于向组件传递信息,并且这个信息也要同步输出到界面的情况。
插槽
插槽是模板中的动态部分,其内容根据组件标签的innerHTML动态替换。假设有下面的组件
<!-- FancyButton -->
<template><button class="fancy"><slot></slot></button>
</template>
我们给出组件的使用示例和实际渲染结果。
<FancyButton>Haha</FancyButton>
<button class="fancy">Haha
</button>
组件可以包含多个插槽,此时要为插槽分配名字。
<template><slot name="header"></slot><slot name="body"></slot>
</template>
在使用这种组件时,需要通过<template>标签绑定对应插槽。
<div><MyComponent><template v-slot:header>header line</template><template #body> <!-- #是v-slot:的缩写 -->body content</template></MyComponent>
</div>
非本地属性
组件可以将自己的属性提供给下级组件使用。
<script setup>
import { ref, provide } from 'vue';const count = ref(0);
function increase() {count.value++;
}provide('count', {count,increase
});
</script>
<script setup>
import { inject } from 'vue';const { count, increase } = inject('count');</script>
如果不希望下级组件修改属性,可以通过readonly方法提供只读属性。
<script setup>
import { ref, readonly, provide } from 'vue';
const count = ref(0);
provide('count', readonly(count));
</script>
定义和使用组合式函数
// mouse.js
import { ref, onMounted, onUnmounted } from 'vue';export function useMouse() {const x = ref(0);const y = ref(0);function update(event) {x.value = event.pageX;y.value = event.pageY;}onMounted(() => window.addEventListener('mousemove', update));onUnmounted(() => window.removeEventListener('mousemove', update));return {x, y};
};
<script setup>
import { useMouse } from './mouse.js';const { x, y } = useMouse();
</script>
import { ref } from 'vue';export function useFetch(url) {const data = ref(null);const error = ref(null);fetch(url).then((res) => res.json()).then((json) => (data.value = json)).catch((err) => (error.value = err));return { data, error };
}
选项式API
选项式API的最大优点在于可以脱离打包工具,使用传统的 <script>
标签就可以使用Vue。选项式API创建和挂载应用的方法和组合式API一致,区别在于定义组件的方法。选项式API返回一个对象作为组件,对象包含以下成员:
- template 字符串,包含HTML模板。
- data 方法,返回值是组件的状态。
- computed 方法,返回值是组件的只读状态。
- props 数组,组件属性名列表。
- methods 对象,定义了组件上的方法。
- created/mounted/unmounted 方法,生命周期回调方法。
- provide 对象,提供给下级组件的对象的名字和值。
- inject 数组,从上级组件接受的对象名字列表。