1.构建 Vue3 + Typescript 项目
(1)创建项目
vue create 项目名
$ cd 项目名
$ yarn serve
(2)安装Typescript
vue add typescript
根据需求选择
(3)安装sass
npm install -D node-sass sass-loader sass
页面中使用
(4)启动项目如果报错 (Error: Cannot find module 'vue-loader-v16/package.json')执行npm install 就可以了
2.模板语法指令
v-once 执行一次性地插值,当数据改变时,插值处的内容不会更新
<span v-once>这个将不会改变: {{ msg }}</span>
3.使用 JavaScript 表达式
{{ number + 1 }}
{{ ok ? 'YES' : 'NO' }}
{{ message.split('').reverse().join('')}}
4.计算属性computed
模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的。在模板中放入太多的逻辑会让模板过重且难以维护。例如,有一个嵌套数组对象:
<div id="computed-basics">
<p>Has published books:</p>
<span>{{ publishedBooksMessage }}</span>
</div>
Vue.createApp({
data() {
return {
author: {
name: 'John Doe',
books: [
'Vue 2 - Advanced Guide',
'Vue 3 - Basic Guide',
'Vue 4 - The Mystery'
]
}
}
},
computed: {
// 计算属性的 getter
publishedBooksMessage() {
// `this` points to the vm instance
return this.author.books.length > 0 ? 'Yes' : 'No'
}
}
}).mount('#computed-basics')
我们也可以通过在表达式中调用方法来达到同样的效果:
<p>{{ calculateBooksMessage() }}</p>
// 在组件中
methods: {
calculateBooksMessage() {
return this.author.books.length > 0 ? 'Yes' : 'No'
}
}
计算属性computed和methods里定义一个方法的区别
也可以将同一函数定义为一个方法而不是一个计算属性。两种方式的最终结果确实是完全相同的。计算属性是基于它们的反应依赖关系缓存的,只在相关响应式依赖发生改变时它们才会重新求值。多次访问 publishedBookMessage
这个计算属性会立即返回之前的计算结果,而不必再次执行函数。
methods里定义一个方法:每当触发重新渲染时,调用方法将总会再次执行函数
5.监听器watch
当需要在数据变化时执行异步或开销较大的操作时,监听器是最有用的。
例如:
<div id="watch-example">
<p>
<input v-model="question" />
</p>
<p>{{ answer }}</p>
</div>
<script>
export default {
data() {
return {
question: '',
answer: '我是一个值'
}
},
watch: {
// newQuestion新的值 oldQuestion旧的值
question(newQuestion, oldQuestion) {
if (newQuestion.length > 10) {
this.getAnswer()
}
}
},
methods: {
getAnswer() {
this.answer = '变化了'
axios
.get('https://yesno.wtf/api')
.then(response => {
this.answer = response.data.answer
})
.catch(error => {
this.answer = 没变化
})
}
}
}
</script>
6.事件处理
事件修饰符(常见)
<!-- 阻止事件冒泡 -->
<a @click.stop="doThis"></a>
<!-- 阻止默认事件,提交事件不再重载页面 -->
<form @submit.prevent="onSubmit"></form>
<!-- 点击事件将只会触发一次 -->
<a @click.once="doThis"></a>
按键修饰符
Vue 为最常用的键提供了别名:
.enter
.tab
.delete
(捕获“删除”和“退格”键).esc
.space
.up
.down
.left
.right
<!-- 只有在 回车的时候按键才会触发 -->
<input @keyup.enter="submit" />
系统修饰键
可以用如下修饰符来实现仅在按下相应按键时才触发鼠标或键盘事件的监听器。
.ctrl
.alt
.shift
.meta
鼠标按钮修饰符
.left
.right
.middle
这些修饰符会限制处理函数仅响应特定的鼠标按钮。
7.表单输入绑定
修饰符
<!-- 在“change”时而非“input”时更新 (取代输入框监听change事件,当鼠标移开时在触发-->
<input v-model.lazy="msg" />
<!-- 将用户的输入值转为数值类型 -->
<input v-model.number="age" type="number" />
<!-- 自动过滤用户输入的首尾空白字符 -->
<input v-model.trim="msg" />
8.vue生命周期
与vue2相比,销毁的函数由beforeDestroy,destroyed改为beforeUnmount,unmounted
9.setup
执行顺序在生命周期和data前面 ,并且setup
选项中没有 this
9.1 ref
响应式变量(适用于单个变量)
<div @click="changnum()">{{num}}</div>
import { ref } from 'vue'
const num= ref(0)
const changnum = () => {
// 获取num的值使用.value
console.log( num.value)
}
return {num,changnum}
9.2 reactive(适用于对象)
import {reactive} from "vue";
const carouselItem = reactive({
// 链接的标题
title: "",
// 图片地址
imageUrl: "",
// 链接类型
linkType: "0",
// 链接
link: ""
})
return {carouselItem }
9.3 toRefs(将对象转换,直接使用)
直接解构 ,双向绑定数据失效,使用toRefs不会
import { reactive,toRefs} from 'vue'
const user = reactive({
name: "kk",
age: 18,
lick: '洗碗'
})
return {
// ...user 错误写法 会导致user 失去响应式
...toRef(user )
}
页面中直接使用
<div> 姓名是{{name}}</div>
<div> 年龄是{{age}}</div>
<div> 爱好是{{lick}}</div>
得到
9.4 provide /inject
provide可以向所有子孙组件提供数据以及提供修改数据的方法,子孙组件用inject使用数据。(这两个api就提供了更方便的传值方式,无论你的组件嵌套有多深,只要你在父组件定义了provide,那么在子孙组件调用inject就可拿到provide所在父组件定义的值,子孙组件数据改变时父组件数据也会改变,所以他们是成对出现)
// 父组件
<template>
<div>
<son />
</div>
</template>
<script setup>
import son from "./son.vue";
import { provide } from "vue";
provide("abc", "123");
</script>
//子组件
<template>
<div>我是子组件</div>
</template>
<script setup>
import { inject } from "vue";
const abc = inject("abc");
console.log(abc);
</script>