Vue3基础学习笔记

40 阅读9分钟

1、toRef -toRefs学习

toRef :由非响应式对象转换为响应式对象,用在{ }对象

eg:

<template>
  <div>{{ name1 }}</div>
  <div>{{ name2 }}</div>
</template>
<script setup>
//toRef
//  由非响应式对象 转换为 响应式对象
//  用在{ }中
import { toRef } from 'vue';
let cat = {myName: 'Tom',age:5}
//直接提取,不会建立联系
let name1 = cat.myName

//通过 toRef 转换,可以建立联系,形成响应式数据
const name2 = toRef(cat, 'myName')

cat.myName = 'Tom2'
</script>
<style>

</style>

image.png

2、toRefs

<template>
  <div>{{ newCat }}</div>
</template>
<script setup>
//toRef
//  由非响应式对象 转换为 响应式对象
//  用在{ }中

//  toRef 一次,建立一个属性的连接
//  toRefs 整体建立连接
import {  toRefs } from 'vue';

let cat = {myName: 'Tom',age:5}

const newCat = toRefs(cat)
 
cat.myName = 'Jerry'
cat.age = 6
</script>
<style>

</style>

image.png

2、v-text、v-html学习

3、v-text:

<template>
  <div>{{ msg }}</div>
  <div v-text="msg"></div>
</template>
<script setup>
import { ref } from 'vue';

//指令
//  是Vue语法,用在 标签属性中
//  以v- 开头

//v-text
//  文本渲染、文本插值
//  其原理 等同 {{  }}
//  不推荐用,太麻烦
//用法
//  v-text="变量"

const msg = ref('hello')

</script>
<style>

</style>

image.png

4、v-html:

<template>
  <div>{{ msg }}</div>
  <div v-text="msg"></div>
  <div v-html="msg"></div>
</template>
<script setup>
import { ref } from 'vue';
//v-html
//  文本渲染、文本插值
//  会对传入的字符串进行解析
//用法
//  v-html="变量"

const msg = ref('<a href="#">百度</a>')

</script>
<style>

</style>

image.png

3、v-bind学习

<template>
  <div style="color: red;"> 你好 </div>
  <div v-bind:style="x"> 你好 </div>
  <button @click="run1">变红</button>
  <button @click="run2">变绿</button>
  <div :class="y">hello</div>
</template>
<script setup>
import { ref } from 'vue';
//v-bind
//  属性绑定指令
//  指,可以动态的给属性赋值
//用法
//  v-bind:属性值="变量名"
//  v-bind:  可以简写 :
//  即   :属性值="变量名"
const x = ref( );
const run1 = () => {
  x.value = {
    color: 'red'
  }
}
const run2 = () => {
  x.value = {
    color: 'green'
  }
}
const y = ref( 'myC2' );
</script>
<style>
.myC1{
  background: rgb(0,0,255);
  color: yellow;
}
.myC2{
  background: rgb(110, 226, 114);
  color: rgb(221, 16, 16);
}
</style>

image.png

image.png

4、样式绑定

<template>
  <div :style="x">你好1</div>
  <div :style="y">你好2</div>
  <div :style="{color:z}">你好3</div>
  <div :style="[a1,a2]">你好4</div>
</template>
<script setup>
import { reactive,ref } from 'vue';

// 方式一:字符串方式,推荐
const x = ref('color: red;')

// 方式二:对象方式
const y = reactive({
  color: 'blue',
  fontSize: '16px',
  backgroundColor: 'yellow',
})

//方式三:插值方式,推荐
const z = ref('green')

//方式四:数组方式
const a1 = ref('color: orange;')
const a2 = reactive('font-size: 20px;background-color: pink;')
</script>
<style>

</style>

image.png

5、类绑定

<template>
  <div :class="x">hello1</div>
  <div :class="y">hello2</div>
  <div :class="{myC3:z}">hello3</div>
  <div :class="['myC1','myC4']">hello4</div>
</template>
<script setup>
  import { ref } from 'vue'
// 类绑定、类属性绑定
// 方式1:字符串方式
const x = ref('myC1')
// 方式2:对象方式
const y = ref({myC2: true})
// 方式3:插值方式
const z = ref(true)
// 方式4:数组方式
//数组内的样式同时生效
</script>
<style>
.myC1 {
  color: red;
}
.myC2{
  color: #079f09;
}
.myC3{
  color: #fbcd00;
}
.myC4{
  background: #52daff;
}
</style>

image.png

6、v-on学习

<template>
  <div v-on:click="run" :style="myS">你好</div>
  <button @dblclick="c++">双击+1,{{ c }}</button>
</template>
<script setup>
  import { ref } from 'vue'
  //v-on
  //    事件绑定

  //用法
  //    v-on:事件名="js表达式 "
  //    简写:@事件名="js表达式 "
  const myS = ref('color:red;')
  const c = ref(10) 
  const run = ()=>{
    myS.value = 'color:blue;'
  }
</script>
<style>

</style>

image.png

7、v-model学习

<template>
  <input type="text" v-model="tx" />
  <div>你刚刚输入的是:{{ tx }}</div>
  <hr />
  <input type="radio" value="A" name="one" v-model="ra" />A.篮球
  <input type="radio" value="B" name="one" v-model="ra" />B.足球
  <div>你刚刚选择的是:{{ ra }}</div>
  <hr />
  <input type="checkbox" name="mul" v-model="cb" value="A" />A.篮球
  <input type="checkbox" name="mul" v-model="cb" value="B" />B.足球
  <hr />
  <div>你刚刚选择的是:{{ cb.sort().join("") }}</div>
  <textarea v-model="ta"></textarea>>
  <pre>你刚刚输入的是:{{ ta }}</pre>
  <hr />
  <select value="" v-model="sl">
    <option value="">--请选择--</option>
    <option value="bj">北京</option>
    <option value="sh">上海</option>
  </select>
  <div>你刚刚选择的是:{{ sl }}</div>
  <hr />
  v-model的扩展
  <hr />
  <input type="text" v-model.lazy="t1" />
  <div>你刚刚输入的是:{{ t1 }}</div>
  <hr />
  <input type="text" v-model.number="t2" placeholder="数字"/>
  <div>你刚刚输入的是:{{ t2 + 100 }}</div>
  <hr />
  <input type="password" v-model.trim="t3" placeholder="密码"/>
  <div>你刚刚输入的是:{{ t3 }}</div>
  <hr />
</template>
<script setup>
import { ref } from "vue";
//  v-model
//      双向绑定、表单绑定
//      用来监听
//               <input type="text" >
//               <input type="checkbox" >
//               <input type="radio" >
//               <select>
//               <textarea>
//          当发生改变时,将标签的value的值,传递给v-model

//  v-model的扩展
//  lazy: 当失去焦点时,才传递数据
//  trim: 去掉输入框的左右两边的空格
//  number: 将输入的数据转为数字再传递
const tx = ref();
const ra = ref();
const cb = ref([]); // 多选框需要用数组来接收
const ta = ref();
const sl = ref();
const t1 = ref();
const t2 = ref();
const t3 = ref();
</script>
<style>
</style>

image.png

image.png

8、v-if学习

<template>
  <div v-if="h<12">上午好</div>
  <div v-else-if="h<18">下午好</div>
  <div v-else>晚上好</div>
</template> 
<script setup>
//  v-if
//    条件渲染指令

//  用法
//    v-if="布尔表达式"
//    v-else-if="布尔表达式"
//    v-else
//  若,布尔表达式 为真,则显示该标签
//  若,布尔表达式 为假,则移出该标签
import { ref } from 'vue'
const h = ref(16)
</script>
<style>

</style>

image.png

9、v-show学习

<template>
  <div v-if="2>3">111</div>
  <div v-show="2>3">222</div>
  <div style="display: none;">333</div>
  <hr>
  <div>1+1=?</div>
  <button @click="x = !x">答案</button>
  <div v-show="x">2</div>
  </template> 
<script setup>
//  v-show
//    条件渲染指令

//  用法
//    v-show="布尔表达式"
 
//  若,布尔表达式 为真,则显示该标签
//  若,布尔表达式 为假,则隐藏该标签
//  v-if   ,若布尔表达式为假,移出
//  v-show ,若布尔表达式为假,隐藏,是css将display设为none
//v-if 常用于 只显示一次
//v-show 常用于 (来回显示隐藏)频繁切换显示隐藏的场景,用于开关
import { ref } from 'vue'
const x = ref(false)
</script>
<style>

</style>

image.png

10、v-for学习

1.v-for基础

<template>
  <div>喜欢的球类运动:</div>
  <div v-for="(x,i) in arr" :key="i">{{i+1+'.'+x}}</div>
  <hr/>
  <div v-for="y in 3">{{ y }}</div>
  <hr>
  <div v-for="z in 'abc'">{{ z }}</div>
  <hr>
  <div v-for="h in obj">{{ h }}</div>
  </template> 
<script setup>
//  v-for
//    列表渲染指令

//  用法
//    v-for="(x,i) in 容器"
//    x:遍历容器取内容
//    i:取下标,从0开始编号
//  简写
//    ()和i可以省

//  容器:
//      数字:是指,遍历 1-该数字
//      数组:是指,遍历数组元素
//      对象:是指,遍历数组元素
//      字符串:是指,遍历字符串的每一个字符
import { reactive, ref } from 'vue'
const arr = ref(['足球','篮球','排球','羽毛球'])
const obj = reactive({
  myName:'小猫',
  myAge:5,
})
</script>
<style>
</style>

image.png

2.v-for-key知识

<template>
  <div>喜欢的球类运动:</div>
  <button @click="arr.splice(1,1)">删除第2个</button>
  <div v-for="x in arr" :key="x.id">{{ x }}</div>
  <input type="text" placeholder="输入球" v-model="bool">
  <button @click="arr.push(bool)">添加</button>
  </template> 
<script setup>
//:key
//  当 v-for 遍历的容器,数据量过大时
//  其 插入 或 删除 要耗费大量事件
//  原因是:数组属于 顺序存储
//  通过 :key="固定唯一值" 去优化此问题

//  建议每个 v-for 都配合 :key 进行优化
//  禁止: 用v-for 中的 索引下标,当作 :key 的值
//  原因: 其下标,动态可变,虽然不报错,但没有优化效果
import {  ref } from 'vue'
const arr = ref([])
const bool = ref()
for (let i = 0;i < 100000;i++){
  arr.value.push({id:'i',data:'球'+i});
}
</script>
<style>
</style>

image.png

11、事件修饰符

<template>
  <div @click.once="c++">单击+1,{{ c }}</div>
  <hr>
  <a href="https://www.baidu.com" @click.prevent.once="c++">百度</a>
  <hr>
  <div @click="mySS='background-color:yellow'" :style="mySS">
    父标签
    <div @click.stop="myS='color:red'"  :style="myS">子标签</div>
  </div>
  <div @click.self="mySS2='background-color:green'" :style="mySS2">
    父标签
    <div @click="myS2='color:blue'"  :style="myS2">子标签</div>
  </div>
  </template> 
<script setup>
import { ref } from 'vue'
//  事件修饰符
//  常见的:
//  once      只执行一次
//  prevent   阻止默认事件
//  stop      阻止事件,停止事件冒泡(用于子标签)【孩子不给父亲传】
//  self      自身触发事件(用于父标签)【孩子给父亲传父亲不要】
//  passive   滚动优化,当页面内容过多,移动端滚动时,可能会卡顿
//            @scroll.passive="fn函数"  告诉浏览器,我不会调用preventDefault(),可以优化滚动性能


//  附注:
//    事件冒泡:子标签触发事件时,会向上传递给父亲
const c = ref(10)
const myS = ref()
const mySS = ref()
const myS2 = ref()
const mySS2 = ref()
</script>
<style>
</style>

image.png

image.png

12、按键修饰符

<template>
  <div v-for="x in arr">{{ x }}</div>
  <textarea :style="{color:x}"  v-model="ta"
    @keydown.a.exact="x='red'"
    @keydown.b.exact="x='green'"
    @keydown.esc.exact="ta=''"
    @keydown.meta="x='yellow'"
    @keydown.f1.exact="x='orange'"
    @keydown.enter.prevent.exact="arr.push(ta);ta=''"
  ></textarea>
  <button @click="arr.push(ta);ta=''">提交</button>
  </template> 
<script setup>
import { ref } from 'vue'
//  按键修饰符
//     按键事件: keyup、keydown、keypress
//  用法
//      @keydown.任意键
//  特殊按键
//      @keydown.enter    回车键
//      @keydown.esc      esc键
//      @keydown.f1       f1键
//      @keydown.ctrl     ctrl键
//      @keydown.alt      alt键
//      @keydown.shift    shift键
//      @keydown.meta     开始菜单键
const x = ref()
const ta = ref()
const arr = ref([])
</script>
<style>
</style>

image.png

image.png

13、鼠标键修饰符

<template>
  <div @click.left="myC='red-style'" 
  @click.middle="myC='green-style'" 
  @click.right.prevent="myC='blue-style'" 
  :class="myC">你好</div>
</template> 
<script setup>
//  鼠标键修饰符
//    @click.left        左键
//    @click.middle      右键
//    @click.right       中键
import { ref } from 'vue'
const myC = ref()

</script>
<style>
.red-style{
  color: red;
}
.green-style{
  color: green;
}
.blue-style{
  color: blue;
}
</style>

image.png

14、事件对象

<template>
  <div @click="run(11,22,$event)">求和:{{ sum }}</div>
  <div @click="run2">你好</div>
  <hr>
  <textarea @keydown="run3"></textarea>
  <div>您输入的是:{{ tt }}</div>
  <hr>
  <div class="box1" @mousemove="run4($event)">
    <div>X:{{ x1 }} ,{{ x2 }}</div>
    <div>Y:{{ y1 }} ,{{ y2 }}</div>
  </div>
</template> 
<script setup>
//  事件对象(event)
//     $event  是系统 内置的参数,可以调用 JS 的DOM方法
//     $event  对象,有以下的属性

//   @click="run($event)"    完整写法
//   @click="run"            简写方式,系统会自动传入 $event 参数
//                          【系统也会传递一个参数  $event】
//   @click="run(11,22)"     系统会传递11,22   不会传递$event 参数
//   @click="run()"          系统不会传递任何参数
//        e.target   是指向DOM标签(相当于document.getElementById())
//        e.key      捕获键盘按键
//        e.screenX  获取鼠标指针 在屏幕的X坐标
//        e.screenY  获取鼠标指针 在屏幕的X坐标
//        e.clientX  获取鼠标指针 在浏览器的X坐标
//        e.clientY  获取鼠标指针 在浏览器的Y坐标

//        浏览器的坐标,左上角为(0,0)
//        往右、右下 为正方向
import { ref } from 'vue'
const sum = ref()
const run =(a,b,e)=>{
  sum.value = a + b
  e.target.style.color = 'red'
}
const run2 =(e)=>{
  e.target.style.color = 'blue'
}
const tt = ref('')
const run3 =(e)=>{
  tt.value += e.key
  if(tt.value.length > 20){
    tt.value = ''
  }
}
const x1 = ref()
const y1 = ref()
const x2 = ref()
const y2 = ref()
const run4 =(e)=>{
  x1.value=e.clientX
  y1.value=e.clientY
  x2.value=e.screenX
  y2.value=e.screenY
  }
</script>
<style>
.box1{
  background: #d4e932;
  width: 200px;
  height: 200px;
  text-align: left;
  position: fixed;
  left: 0;
}

</style>

image.png

image.png

image.png

15、函数computed

<template>
  <!-- sum1 是函数 --->
  <div>{{ sum1() }}</div>
  <!-- sum2 是计算属性 --->
  <div>{{ sum2 }}</div>
  <!-- sum3 是 变量,要调用sum1--->
  <div>{{ sum3 }}</div>
  <!-- sum4 是 变量,要调用sum2 --->
  <div>{{ sum4 }}</div>
</template> 
<script setup>
import { computed } from 'vue';

//  计算属性(computed)
//    函数(method),当页面发生变化时,函数就会重新执行
//         return 可写可不写
//    计算属性(computed),只有当其所依赖的数据发生变化时,才重新执行
//             return 必须写
//             计算形式的底层是 ref
//  建议:为了提高效率,有return,使用 计算属性,没有 return 使用函数

const sum1 = ()=>{
  return 11+22
}
const sum2 = computed(()=>{
  return 11+22
})
const sum3 = sum1()+66
const sum4 = sum2.value+66
</script>
<style>


</style>

image.png

16、watch

<template>
  <button @click="gd++">功德+1,{{ gd }}</button>
  <div>功德变化:{{ oldv }} --&gt;{{ newv }}</div>
  <hr>
  <div>{{ cat }}</div>
  <button @click="cat.myAge++">明年</button>
  <div>年龄变化:{{ ov }} --&gt;{{ nv }}</div>
</template> 
<script setup>
import { reactive, ref, watch } from 'vue';
//  监听器(watch)
//  用法
//    watch{ 要监听的数据,(新值,旧值)=>{ 监听到变化时要执行的代码【发生后的操作】 },附加选项 }
//  注意:
//    要监听的数据,若为 基本数据类型,直接监听
//    要监听的数据,若为 对象中的数据,则通过匿名函数进行监听

const gd = ref(100);
const oldv = ref();
const newv = ref();
watch(gd,(n,o)=>{
  oldv.value = o;
  newv.value = n;
})
const cat = reactive({
  myName:'小花',
  myAge:3
})
const ov = ref();
const nv = ref();
watch(()=>cat.myAge,(n,o)=>{
  ov.value = o;
  nv.value = n;
})
</script>
<style>

</style>

image.png

17、生命周期

<template>
  <div>{{ aa }}</div>
  <div id="dd">你好</div>
  <button @click="run">单击+1,{{ cc }}</button>
</template> 
<script setup>
//  生命周期,Vue的运行,有一定的顺序
//    1、先执行<script> 中的setup
//        1.导入内存

//    2、再执行 挂载 操作
//        1.先执行  挂载前 onBeforeMount()
//        2.再执行  挂载中 
//        3.最后执行  挂载后 onMounted() ⭐

//    3、再执行 更新 操作
//        0.内存的 响应式数据发生改变
//        1.先执行  更新前 onBeforeUpdate()
//        2.再执行  更新中
//        3.最后执行  更新后 onUpdated() ⭐

//    4、再执行 卸载 操作
//        1.先执行  卸载前 onBeforeUnmount()
//        2.再执行  卸载中
//        3.最后执行  卸载后 onUnmounted()

import { onBeforeMount, onMounted, ref ,onBeforeUpdate, onUpdated} from 'vue';
const aa = ref(666);

onBeforeMount(()=>{
  //此时还没有标签,还不能调用 DOM 操作
  //document.getElementById('dd').style.color='red';
})
onMounted(()=>{
  document.getElementById('dd').style.color='red';
})

const cc = ref(100);
const run=()=>{
  cc.value++;   //  先在内存中,将 c 改为101
  console.log('内存改变')  
}
onBeforeUpdate(()=>{
  console.log('更新前')
})
onUpdated(()=>{
  console.log('更新后')
})
</script>
<style>
</style>

image.png

image.png

18、模板引用

<template>
  <div ref="myDiv">你好1</div>
  <div id="dd">你好2</div>
  <div :style="myS">你好3</div>
  <div :class="myC">你好4</div>
  <div @mouseover="run($event)">你好5</div>
</template> 
<script setup>
//  模板引用(ref属性)
//    1、用来操作DOM
//    2、其初始值,必须为 ref(null)
//    3、通过 .value 调用DOM方法
//    4、要在 onMounted 中调用
//    示例中125用的DOM操作,在12在mounted中调用
import { onMounted, ref } from 'vue'
const myDiv = ref(null)
onMounted(() => {
  myDiv.value.style.color = 'red'  
  document.getElementById('dd').style.color = 'yellow'
})

const myS = ref({'color':'blue'})
const myC = ref('org-style')
const run = (e) => {
  e.target.style.color = 'pink'
}
</script>
<style>
  .org-style{
    color: green;
  }
</style>

image.png

19、组件引入