DOM BOM
JavaScript = ECMAscript + BOM + DOM
ECM为浏览器处理js语言的规范
DOM为js提供了访问和操作元素的接口 document对象
BOM为js提供了一种控制浏览器的方法 window对象
DOM树指各级元素标签之间的父子关系
Vue语法结构
Vue通过虚拟DOM来进行更新,只更新差异化的部分,而不是整个DOM更新,因此效率高
使用Vue:
1、从Vue对象中导入函数
2、通过 creatApp() 创建一个vue实例
3、使用Vue实例对象的 mount() 和所在页面建立联系,将Vue挂载到页面上
const { createApp } = Vue
const app = createApp({})
app.mount("#app")
4、setup函数 使用在 createApp() 函数的参数对象中,用来声明响应式变量或者函数
5、在 setup函数 中通过 return 返回的对象会暴露在页面中(所有对象和函数都得暴露才能使用)
6、ref函数,也是需要在Vue对象中导入
<script>
const {createApp, ref} = Vue
window.onload = function(){
createApp({
setup() {
const message = ref('hellow vue')
const num1 = ref(1)
const num2 = ref(2)
function num1_add(){
num1.value += 1
}
function num1_remove(){
num1.value -= 1
}
return {
num1,
num2,
message,
num1_add,
num1_remove
}
}
}).mount('#app')
}
</script>
模板语法
1、文本插值:在script中将变量定义并且暴露出来,在html结构中可以使用 {{ value }} 进行取值
2、JS表达式: {{ a }} 其中a可以作为js表达式出现,也会正常执行
3、调用函数:{{ func }} func可以是自定义函数(需要在scipt中定义并暴露),也可以是内置函数
4、vue指令: v-html
和 v-text
是 Vue 提供的两个指令,它们用于处理模板中的文本内容。
<!-- 使用 v-text 渲染 -->
<div v-text="mesB">v-text 渲染</div>
<!-- 使用 v-html 渲染 -->
<div v-html="mesC">v-html 渲染</div>
属性绑定
1、使用:v-bind: 或 **: **
2、绑定单个属性:字符串,布尔值,整形等等
<!-- v-bind完整写法 跳转到百度首页 -->
<p><a v-bind:href="baidu">访问百度</a></p>
<!-- v-bind缩写形式 跳转到必应首页-->
<p><a :href='bing'>访问必应</a></p>
3、绑定多个属性
script
const style1 = ref({"width":"100px", "color":"red"})
body
<h1 :style="style1">多个属性绑定</h1>
事件绑定
1、 v-on: 简写为 @
2、内联js语法:
<p><input type="button" v-on:click="numA++" value="点击加1" /> {{numA}}</p>
3、绑定函数:有参函数 @add = “add_num(参数)” 无参函数 @add = “add_num”
双向绑定
1、 v-model:
2、文本的单项绑定:只需要将v-model绑定到对应的变量上即可
3、表单绑定:表单存在单选或多选情况,如果是多选情况,则需要在ref定义时加上 【】表示多元素
4、修饰符:使用 v-model.修饰符:
4.1、lazy修饰符:用于事件之后同步,比如输入框输入完成后再显示结果
4.2、number修饰符:将用户输入的值转换为数值类型。一般情况下所有输入都当成字符串处理,这个修饰符可以将数字自动转换成数字类型
4.3、trim修饰符:自动过滤输入的前后空格,中间的空格不会过滤
条件渲染
1、v-if = “flag” if需要参数 v-elseelse不需要参数
2、if/else语句只会创建符合条件的元素
3、v-show = “flag” 针对css中的display属性进行操作,隐藏则显示 none
列表渲染
1、v-for=”item in items“
2、带索引渲染:v-for=“(item, index) in data” item为值,index为下标索引
3、索引对象可以是普通的数组(【】), 或者js对象({name: “Tom”, age:18})
4、带属性名的渲染:对js对象的渲染v-for=“(value, key) of data”
5、带索引值的渲染:v-for=“(item, key, index) of items”
6、多层数据列表的渲染: Vue 默认按照就地更新 的策略来更新通过 v-for
渲染的元素列表。所以最好挂载在一个唯一的值做为 :key
属性的值,避免出现渲染错误
const data = ref([{
id:"s01",
name: "Tom",
age: 22,
gender: "male",
address: "BeiJing"
},{
id:"s02",
name: "Jack",
age: 23,
gender: "male",
address: "ShangHai"
}
<li v-for="(obj,index) in data" :key="index">
计算属性
1、const { createApp, ref,computed } = Vue 需要导入实例对象
2、computed期望接受一个get函数,返回值为一个计算数学ref,且该ref已经解包
3、和普通的响应式相同,都需要在 setup 中暴露
window.onload = function(){
createApp({
setup() {
const firstName = ref("Michael")
const lastName = ref("Jordan")
// 添加计算属性
const fullName = computed(()=>{
console.log("FullName")
return firstName.value + "." + lastName.value
})
return {
// 暴露计算属性
fullName
}
}
}).mount('#app');
4、计算属性与方法的区别:计算属性存在缓存,计算属性的响应式依赖更新才会进行重新计算,否则会直接调用缓存值;而函数方法每次计算都会重新取值计算
5、计算属性可写:计算属性默认可读的,尝试修改一个计算属性时会受到警告;同时通过get()方法对修改源值进行响应,使用set()方法对修改结果值进行响应
// 计算属性
const fullName = computed({
get(){
console.log("FullName")
return firstName.value + "." + lastName.value
},
set(newValue){
[firstName.value, lastName.value] = newValue.split(".")
}
})
// 函数
function getfullName(){
console.log("GetFullName")
return firstName.value + "." + lastName.value
}
// 事件响应函数
function changeFirstName(){
// 修改计算属性的值
fullName.value = "A.B"
console.log(firstName.value)
console.log(lastName.value)
}
function changeFirstName2(){
firstName.value += "A"
}
Vite 项目构建
view组件基础
1、定义组件:<script setup></script>
+<template></template>
+<style></style>
2、在App.vue中集合调用:导入各种组件,在其中组合调用
3、注意:需要导入vue中的某些对象 import { ref } from "vue"
vue组件的正向数据传递
1、声明:子组件声明 defineProps(["title", "name", ……})
2、使用:
2.1:子组件占位
<h3>{{name}}</h3>
<p>{{age}}</p>
2.2:父组件传值
const content = ref( content_value)
<!-- title 使用普通方式传递数据, content 使用v-bind方式传递动态数据 -->
<SC title="Vue 组件传递数据" :content="content"></SC>
3、注意:prop只能以字符串的形式声明注册,但是可以接受任何值;使用prop属性名传递数据时,可以传递字面值,也可以结合 v-bind 传递动态数据
vue反向传递数据
1、反向传递数据过程:
1.1、在父组件中绑定一个自定义事件,并定义该事件的响应方法
1.2、在子组件中触发自定义事件
1.3、父组件监听子组件,若触发事件,则执行相对应的方法
2、$emit方法时vue中自带的方法,不适用于自定义函数
<script setup>
import RSC from './RSC.vue';
function recvMsg(msg){
alert(msg)
}
</script>
<template>
<RSC @msg="recvMsg" />
</template>
-------------------------------------------------------------------------
子组件
<template>
<button @click="$emit('msg', 'Hello Vue')">点击触发msg事件</button>
</template>
3、 defineEmits() 函数 与 emit() 函数
3.1、defineEmits([“父组件函数名”])类似defineProps(),都是宏定义,用于子组件中,用来注明需要抛出的事件
3.2、defineEmits会返回一个等同于$emit方法的emit函数
3.3、返回的emit函数可以被用于组件的 <script setup>
中抛出事件
子组件
<script setup>
defineProps(["data"])
const emit = defineEmits(["delData"])
function deleteData(item){
emit("delData", item)
}
</script>
<template>
<div class="rsc">
<table>
<tr>
<th>编号</th>
<th>姓名</th>
<th>年龄</th>
<th>操作</th>
</tr>
<tr v-for="item in data" :key="item.sid">
<td> {{ item.sid }}</td>
<td> {{ item.name }}</td>
<td> {{ item.age }}</td>
<td> <button @click="deleteData(item)">删除</button> </td>
</tr>
</table>
</div>
</template>
----------------------------------------------------------------------------------
父组件
<script setup>
import RSC from './RSC.vue';
import {ref} from "vue"
const data = ref([
{sid: "s01",name: "Tom",age: "23"},
{sid: "s02",name: "Jack",age: "24"},
{sid: "s03",name: "Rose",age: "25"}
])
function delDataAction(obj){
const idx = data.value.indexOf(obj)
data.value.splice(idx,1)
}
</script>
<template>
<RSC :data="data" @delData="delDataAction" />
</template>
插槽
1、作用:在某些场景中需要父组件往子组件中加塞一些片段
2、使用:标准形式 v-slot:name 简写为 #name
3、插槽内容:写在父组件中引用子组件的中间片段
4、出口:在子组件的template中加入 <slot>内容</slot> 块
5、具名插槽:父组件向某一个子组件中传递多个插槽元素
<!-- 具名插槽 -->
<slot name="sloatname"></slot>
<!-- 未具名插槽,默认名为 default -->
<slot></slot>
<template>
<h1>这是父组件内容</h1>
<SlotnameSC>
<template v-slot:header>
<h1>这是页面标题</h1>
</template>n
<template #default>
<p>这是内容显示区域</p>
<p>用来显示文本和图片</p>
</template>
<template #footer>
<p>这里显示页脚信息</p>
</template>
</SlotnameSC>
</template>
动态组件
1、用于在同一个页面切换不同的组件
2、使用:<component :is=“…”></component>
3、难点在于切换的逻辑
路由管理
1、使用
1.1、在src目录下新建router文件夹,在其下新建index.js文件
在index.js处定义路由
import {createRouter,createWebHashHistory} from 'vue-router'
import Ceshiren from '../views/Ceshiren.vue'
import Hogwarts from '../views/Hogwarts.vue'
const routes=[
{
path:"/ceshiren",
component:Ceshiren
},
{
path:'/hogwarts',
component:Hogwarts
}
]
const router = createRouter({
// 路由模式
history:createWebHashHistory(),
routes,// `routes:routes` 的缩写
})
export default router
1.2、在main.js中注册路由
import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
import router from './router'
//注册路由
createApp(App).use(router).mount("#app")
1.3、在App.vue中使用路由
<template>
...
<div>
<p><router-link to="/ceshiren">点击进入 Ceshiren 页面</router-link></p>
<p><router-link to="/hogwarts">点击进入 Hogwarts 页面</router-link></p>
<router-view></router-view>
</div>
</template>
2、路由模式: hash模式 与 history模式