一、项目配置
1、创建Vue应用 (main.js)
import { createApp } from 'vue'
import App from './App.vue'; //根组件
const app = createApp(App);
1)、挂载应用:应用实例必须在调用了 .mount() 方法后才会渲染出来。该方法接收一个“容器”参数,可以是一个实际的 DOM 元素或是一个 CSS 选择器字符串:
app.mount('#app')
例:<div id="app"></div>
2)、应用配置:通过 .config 对象配置应用级的选项
2、配置本地域名 (vite.config.js)
//vite 相关配置--代理转发
server: {
port: 80,
host: '0.0.0.0',
hmr : true,
open: true,
proxy: {
'/dev-api': { //开发环境
target: 'XXX', 域名
changeOrigin: true,
rewrite: (p) => p.replace(/^\/dev-api/, ''),
},
'/prod-api': { //生产环境
target: 'XXX',
changeOrigin: true,
rewrite: (p) => p.replace(/^\/prod-api/, ''),
},
},
},
二、模板语法
单文件组件 (SFC) 语法格式: <script setup>为例,使用组合式 API 的编译 (默认官方推荐)。
组件定义在一个单独的 .vue 文件中
vue样式 :
<style lang="scss" scoped></style> :只影响当前组件的样式,否则为全局样式
响应式状态需要明确使用响应式 API 来创建: import { ref } from 'vue'
注:在 DOM 中书写模板时,应该使用 kebab-case 格式并显式地关闭这些组件的标签,例:<template></template>
双大括号会将数据解释为纯文本
1、属性绑定:
1)、v-bind:属性名=> 简写 :属性名
2)、v-on 指令(简写 @):DOM事件监听,用法:v-on:click="handler" 或 @click="handler"
指令(内置指令):带有 v- 前缀的特殊属性
1)动态参数绑定:
例:<a @[eventName]="doSomething"> :表示当 eventName 的值是 "focus" 时,v-on:[eventName] 就等价于 v-on:focus
2)、绑定 HTML class
例:<div :class="{ active: isActive }"></div> :表示 active 是否存在取决于属性 isActive 的真假值
2、条件渲染
1)、v-if(必须依附于某个元素,也可在<template>上使用) /v-else-if / v-else(必须跟在一个 v-if 或者 v-else-if 元素后面,否则它将不会被识别)
2)、v-show(在 DOM 渲染中保留该元素,仅切换了该元素上名为 display 的 CSS 属性,可在<template>上使用,也不能和 v-else 搭配使用)
v-show:dom中增加一个行内样式 display: none
3)、v-if 和 v-show的区别:
v-if 是“真实的”按条件渲染,因为它确保了在切换时,条件区块内的事件监听器和子组件都会被销毁与重建。
v-if 也是惰性的:如果在初次渲染时条件值为 false,则不会做任何事。条件区块只有当条件首次变为 true 时才被渲染。
相比之下,v-show 简单许多,元素无论初始条件如何,始终会被渲染,只有 CSS display 属性会被切换。
总的来说,v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。
因此,如果需要频繁切换,则使用 v-show 较好;如果在运行时绑定条件很少改变,则 v-if 会更合适。
3、列表遍历(v-for)
注:官方推荐, 使用v-for的时候, 加上一个 key 属性,key的作用是为了高效的更新虚拟DOM,具有唯一性, 不然就没意义
可在<template>上使用;同时使用 v-if 和 v-for 是不推荐的,因为这样二者的优先级不明显。
若 v-if 和 v-for 同时存在于一个元素上的时候,v-if 的优先级更高,会首先被执行;
解决:
<template v-for="todo in todos">
<li v-if="!todo.isComplete">
{{ todo.name }}
</li>
</template>
1)、遍历一个数组:v-for="item in items" / v-for="item of items"
使用 item in items 形式的特殊语法,其中 items 是源数据的数组,而 item 是迭代项的别名;
也支持使用可选的第二个参数表示当前项的位置索引 v-for="(item, index) in items";
例:<li v-for="(item, index) in items">
{{ parentMessage }} - {{ index }} - {{ item.message }}
</li>
语法和JavaScript类似
items.forEach((item, index) => {
console.log(item.message, index)
})
2)、遍历对象及属性:
第二个参数表示属性名,第三个参数表示位置索引;
例:<li v-for="(value, key, index) in myObject">
{{ index }}. {{ key }}: {{ value }}
</li>
3)、模板引用
响应式数据:ref、reactive、computed、watch,通过 provide 和 inject 来实现父子组件之间的数据传递
A. ref 函数用于创建一个包装器对象,它会将值转化为响应式对象。在访问 ref 包装的值时需要使用 .value 属性
如果是基本数据类型 :则使用ref函数,它是一个特殊的属性,它允许在一个特定的 DOM 元素或子组件实例被挂载后,获得对它的直接引用;
例:import { ref } from 'vue'
const count = ref(0)
count.value++; // 视图将自动更新
B. reactive 函数用于将普通 JavaScript 对象转化为响应式对象。响应式对象中的属性被修改时,可以自动更新视图。
如果是一个对象或数组,则使用reactive函数。
注:局限性:它只能用于对象类型 (对象、数组和如 Map、Set 这样的集合类型),不适用string、number 或 boolean等类型
例:import { reactive } from 'vue'
const state = reactive({
count: 0
})
state.count++; // 视图将自动更新
C. computed 函数用于创建一个计算属性,它会根据响应式对象中的属性值来计算一个新的值。
例:import { reactive, computed } from 'vue'
const state = reactive({
count: 0
})
const doubleCount = computed(() => state.count * 2)
console.log(doubleCount.value) // 0 注:在访问计算属性的值时需要使用 .value 属性。
D. watch(侦听器) :用于监测响应式对象中的属性变化,并执行对应的回调函数。
4)数据绑定:v-model实现表单元素和数据的双向绑定
computed / methods区别 :
若多次使用的时候:
methods: 每次都会调用;
computed: 计算机会缓存, 不变的情况下只调用一次
4、使用组件 (组件通讯)
1)、要使用一个子组件,需要在父组件中导入它;
若要将导入的组件暴露给模板,需要在 components 选项上注册它。这个组件将会以其注册时的名字作为模板中的标签名。
在单文件组件中,推荐为子组件使用 PascalCase 的标签名
例:子组件注册名称:<user-list ref="materialsRef" />
引入组件:import UserList from './UserList.vue'
2)、传递 Props :用于将数据从父组件传递到子组件。
子组件可以通过定义 props 对象来声明需要接收的属性及其类型。
父组件可以通过向子组件添加属性来将数据传递给子组件。
遵循单向绑定原则,props 因父组件的更新而变化,自然地将新的状态向下流往子组件,而不会逆向传递,但不可在子组件中更改 props 绑定值;
Props 是一个特殊的属性,在组件上声明注册。若要传递给子组件,必须在父组件的 props 列表上声明它;
一个组件可以有任意多的 props,默认情况下,所有 prop 都接受任意类型的值
如果一个 prop 的变量名很长,则采用 camelCase 形式;
Props 参数校验:
所有 prop 默认都是可选的,除非声明了 required: true;
除 Boolean 外的未传递的可选 prop 将会有一个默认值 undefined;
Boolean 类型的未传递 prop 将被转换为 false。
例:
defineProps({
// 基础类型检查
propA: Number, //给出 `null` 和 `undefined` 值则会跳过任何类型检查
// 多种可能的类型
propB: [String, Number],
// 必传,且为 String 类型,且有默认值
propC: {
type: String,
required: true,
default: 'aaa'
},
// Number 类型的默认值
propD: {
type: Number,
default: 100
},
// 对象类型的默认值
propE: {
type: Object,
// 对象或数组的默认值
// 必须从一个工厂函数返回。
// 该函数接收组件所接收到的原始 prop 作为参数。
default : () => {
//return { message: 'hello' }
},
},
})
3)传递 emit :子组件数据传递到父组件-用来触发父组件里面绑定的函数并可以传参回父组件(刷新父页面)
4)、子组件中,vue提供了 defineExpose 来向外暴露属性和方法
defineExpose({
handleEdit(方法)
})
5)要等待 DOM 更新完成后再执行额外的代码,可以使用 nextTick() 全局 API
5、组件注册
组件注册有两种方式:全局注册和局部注册。
一般会将 Vue 组件定义在一个单独的 .vue 文件中,叫做单文件组件 (简称 SFC)
1)、全局注册、局部注册
2)、将模板中使用 kebab-case 的标签解析为使用 PascalCase 注册的组件;
使用 kebab-case 形式作为注册组件的格式,并以"/>" 结束标签;
使用 PascalCase 形式作为组件名。
例:<user-list ref="materialsRef" />
import UserList from "./UserList"
3)、<script setup> 是在单文件组件 (SFC) 中使用 composition api 的编译时语法糖(ES6的编码规范风格)。
若需要使用 TypeScript,则将 lang 属性添加到 <script> 代码块上,并赋值 ts;
例:<script lang='ts' setup>
6、事件
1)使用 camelCase 形式命名事件,使用 kebab-case 形式来监听事件;
例:<el-icon @click="handleClick"><RefreshRight /></el-icon>
<el-icon @some-event="handleClick"><RefreshRight /></el-icon>
2)声明触发的事件
const emit = defineEmits(['inFocus', 'submit'])
7、表单验证规则 rules:
trigger属性值: 'change'、'blur'、‘submit’
8、插槽slot:默认值 button,使封装的组件更加具有扩展性
9、CLI (Command-Line Interface) 命令行界面, 俗称脚手架
10、Axios 是一个基于 Promise 用于浏览器和 nodejs 的 HTTP 客户端。简单的理解就是 Ajax 的封装库。
1)功能强大: 基于 Ajax 封装的 XMLHttpRequest 网络请求库,拥有多种请求方式;
2)支持Promise API 且 浏览器支持良好;
3)支持并发请求,提高了请求效率及性能;
4)能够拦截请求和响应: 便于自定义封装一些根据实际请求,需要更改的内容;
5)promise是对象接受resolve和reject两个参数,当一个异步动作发生时,promise对象会通过resolve完成对动作成功进行解析,reject会捕获这个动作的异常。
例:
return new Promise((resolve, reject) => {
axios.get(url, {params}
).then((res) => {
//成功的时候调用resolve
resolve(res.data);
}).catch((err) => {
//失败的时候调用reject
reject(err);
});
});