vue笔记

模板中需要用方法/复杂逻辑:里就用计算属性computed:{} 类似方法,在模板中调>用时不需要加括号

模板里若需要调用方法则要加括号,用计算属性更优

  • 安装yarn npm i -g yarn
  • 安装vue-Cli npm i -g @vue/cli or yarn global add @vue/cli 创建项目 vue create my-app
  • 运行项目npm run serve or yarn run

vue3+ts


js,ts变量名和值名字一样直接省略写法:name:name->name

箭头函数vscode快捷写法:dfi


创建项目

1.Vue-CLi

vue create 项目名

2.Vite

基于create-vue 创建出来的项目默认没有初始化git仓库

  • npm create vue@latest

  • npm init vue@latest

以上两种方法创建的项目相同

创建vite项目

  • ```npm create vite@latest``

图形化界面创建

vue ui


状态管理工具

1.Vue3 -> Piania(good),Vuex

2.Vue2 -> Vuex


语法检查工具

ESLint

  • 其他:获取id:uuid,nanoid

组合式api命名组件的两种方式:

1
2
3
4
5
6
7
8
9
10
11
1.命名组件:2个script
<script lang='ts'>
export default(){
name:'Person'//name='Person'命名组件
data(){
}
}
</script>

<script lang='ts' setup>
</script>
1
2
3
4
5
6
2.命名组件:
需先安装插件`npm i vite-plugin-vue-setup-extend -D`
再到vite.config.ts引用
<script lang='ts' setup name='Person'>//name='Person'命名组件

</script>

项目结构

1
2
3
4
5
6
7
//main.ts
import './assets/main.css'

import { createApp } from 'vue'
import App from './App.vue' //根组件App

createApp(App).mount('#app') //创建App并挂载到index.html的id为app的元素
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//根目录的index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="icon" href="/favicon.ico">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vite App</title>
</head>
<body>
<div id="app"></div>
<!-- 引入main.ts -->
<script type="module" src="/src/main.ts"></script>
</body>
</html>

ref和reactive-响应式数据

import {ref,reactive} from 'vue'

  • ref:适用于基本类型和对象。

    • let name = ref('Coffee') let person = ref({name:'Coffee',age:22}) let arr = ['a',{name:'Coffee',age:22}]
    • 在模板直接使用{{arr[1]}}
    • 改数据:在方法中需要先.value再赋值name.value person.value.name arr.value[1].name
  • reactive:适用于对象和数组。

    • let person = reactive({name:'Coffee',age:22})。获取属性值直接对象.属性名

toRefs和toRef

  • 将reactive定义的对象的属性转为ref

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    //toRefs
    let person = reactive({
    name:'Coffee',
    age:22
    })

    let {name,age} = toRefs(person)
    /*let person = reactive({
    name:'Coffee', ->ref
    age:22 ->ref
    })*/person仍为reactive

    console.log(name.value,age.value)
    console.log(person.name,person.age)

    //toRef
    let {name,age} = toRef(person,'name')
    console.log(name.value)
    console.log(person.name)

v-for为什么加:key

例:用删除操作删除复选框,如果不加:key,则会出错。:key用于标识每个循环的元素,防止诸如删除出错等问题。


computed计算属性:

  • 计算属性也是属性且是只读的。默认为ref响应式数据
  • 计算属性有缓存,只计算一次,缓存中数据变化时才再次计算。而方法每次调用都计算一次。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
let a = ref('a')
let b = ref('b')

let c = computed(()=>{
return a.value + b.value //回调函数
})

//通过getter和setter获取和更改计算属性
let c = computed(()=>{
get(){
return a.value + b.value //回调函数
}
set(val){
a.value = val
b.value = val
}
})

Watch监视

参数:

watch(被监视数据,(newValue,oldValue)=>{ },配置对象)

  • ref:

    • 监视ref定义的基本类型数据:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      import {ref,watch} from 'vue'

      let a = ref(0)

      //watch()调用时有返回值,调用停止监视
      const stopWatch = watch(a,(newValue,oldValue)=>{
      console.log(newValue,oldValue)
      if(条件){
      stopWatch() //结束监视
      }
      })
    • 监视ref定义的对象数据:监听对象属性时:deep:true

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      import {ref,watch} from 'vue'

      let person = ref({
      name:'Coffee',
      age:22
      })

      //监视整个对象的变化,对象本身变成新的对象才监视
      watch(person,(newValue,oldValue)={
      console.log(newValue,oldValue)
      })

      //监视对象的属性和对象本身,手动开启深度监听
      //添加配置对象{deep:true,immediate:true}
      //修改属性时,对象地址不变属性值变,oldValue仍指向原来的对象,故newValue=oldValue
      watch(person,(newValue,oldValue)={
      console.log(newValue,oldValue)
      },{deep:true,immediate:true})
    • 监视ref定义的对象的某个属性:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      let person = ref({
      name:'Coffee',
      age:22
      })

      watch(() => person.name,(newValue,oldValue)={
      console.log(newValue,oldValue)
      })

      //监视多个属性
      watch([() => person.name,() => person.age],(newValue,oldValue)={
      console.log(newValue,oldValue)
      })
  • reactive

    • 监视reactive定义的对象类型数据,默认开启深度监视(隐式创建):

      1
      2
      3
      4
      5
      6
      7
      8
      9
      let person = reactive({
      name:'Coffee',
      age:22
      })

      //监视属性变化和对象本身变化
      watch(person,(newValue,oldValue)=>{
      console.log(newValue,oldValue)
      })
    • 监视监视reactive定义的对象类型数据的属性:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      let person = reactive({
      name:'Coffee',
      age:22,
      car:{
      c1:'gti',
      c2:'a4l'
      }
      })

      //监视的对象的属性为基本类型
      watch(()=>person.name,(newValue,oldValue)=>{
      console.log(newValue,oldValue)
      })

      //1.监视的对象的属性为对象,监视car本身而不监视car的属性变化:
      watch(()=>person.car,(newValue,oldValue)=>{
      console.log(newValue,oldValue)
      })

      //2.监视的对象的属性为对象,监视car的属性变化,需要手动开启深度监视
      watch(()=>person.car,(newValue,oldValue)=>{
      console.log(newValue,oldValue)
      },{deep:true})

      //监视多个属性
      watch([() => person.name,() => person.age,person.car],(newValue,oldValue)=>{
      console.log(newValue,oldValue)
      },{deep:true})

      tip:无论是ref还是reactive定义的对象:要监视对象的某个属性,watch里要用回调函数监视,

      watch(()=>person.car,(newValue,oldValue)=>{},{})


html标签中的ref:

1
2
3
4
5
6
7
template中:
<h1 ref='tag'></h1>

ts/js中:
let tag = ref()

可以通过tag变量名标识h1和获取h1

限制对象属性的名字和类型

定义接口

创建文件夹:types->index.ts

1
2
3
4
5
6
7
8
9
10
11
12
13
//index.ts
//限制对象Obj的属性
export interface ObjInter{
id:string,
age:number,
sex?:string //加?表示为可选项
}

//用export暴露出去

//限制数组的元素为对象类型的属性
export type Objs = Array<ObjInter>
export type Objs = ObjInter[]

引用:

import {type ObjInter,type Objs} from '@/types'

使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
let obj:ObjInter = {id:'1',age:1}
let objs:Array<ObjInter> = [
{id:'1',age:1},
{id:'2',age:2}
]

let objs:Objs = [
{id:'1',age:1},
{id:'2',age:2}
]

//<泛型>
let objs = reactive<Objs>([
{id:'1',age:1},
{id:'2',age:2}
])

defineProps

父组件传

子组件收:

1
2
3
4
5
6
7
8
9
10
import {defineProps,withDefault} from 'vue'//宏函数可以不引入

defineProps(['a','b'])

//限制类型
defineProps<{a:Objs}>()

withDefault(defineProps<{a?:Objs}>(),{
a:()=>[{默认值}]
})//'?'表可选项,

defineExpose

vue3子组件的数据只有暴露之后父组件才能获取到

1
defineExpose('a','b')//a,b为子组件数据名,暴露后父组件可以获得

组件生命周期

1. vue2组合式api

生命周期 钩子

  • 创建 (创建前beforeCreate(),创建完毕created())

  • 挂载 (挂载前beforeMounte(),挂载完毕mounted())

  • 更新 (更新前beforeUpdate(),更新完毕updated())

  • 销毁 (销毁前beforeDestory(),销毁完毕destoryed())

钩子:生命周期函数

2. vue3选项式api

生命周期

1
import {onBeforeMount,onMounted,onBeforeUpdate,onUpdated,onBeforeUnmounte,onUnmounted,onBeforeDestory,onDestoryed} from 'vue'
  • 创建:
    • setup。setup时自动return,setup时创建完毕。
  • 挂载:子组件挂载到父组件,父组件再挂载到
    • 挂载前:onBeforeMount( ( ) => { } )
    • 挂载完毕:onMounted( ( ) => { } )
  • 更新:
    • 更新前:onBeforeUpdate( ( ) => { } )
    • 更新完毕:onUpdated( ( ) => { } )
  • 卸载:v-show()
    • 卸载前:onBeforeUnmounte( ( ) => { } )
    • 卸载完毕:onUnmounted( ( ) => { } )

Hooks:useXxx.ts命名文件的为hooks

创建hooks文件夹,hooks->useName.ts

1
2
3
4
5
//useName.ts
export default function(){

return {name,age}
}
1
2
3
4
5
6
7
//调用useName.ts的vue文件
<script setup lang='ts'>
import useName from '@hooks/useName'

//调用
const {name,age} = useName()
</script>

组件通信

  • 父传子:

    • props:父组件直接传给子组件。父组件传<Son name='coffee' />,子组件接收defineProps(['name'])
  • 子传父:

    • props:通过传递函数给子组件,子组件将数据传给函数,父组件接收到数据
      • 父组件定义一个方法f(value)
      • 父组件将该方法传给子组件<Son :func='f' />
      • 子组件接收方法defineProps(['func'])
      • 子组件调用方法func(params)
    • 自定义事件:
      • 父组件定义方法getSon(value:string)
      • 父组件给子组件绑定自定义事件<Son @send-from-son='getSon' /> 自定义事件的事件名命名规范:a-b-c,v-on对大小写不敏感
      • 子组件接收自定义事件const emit = defineEmits(['sendFromSon'])
      • 子组件调用事件,<button @click='emit('sendFromSon',name)'></button>

v-bind

v-bind传对象,对象里面是key:value

v-bind='{a:'1',b:'2'}' ==传递==>a:'1',b:'2'


宏函数

define开头

钩子

use开头或者on开头


forin遍历

forin遍历根据索引遍历:

1
2
3
for(index in arr){
console.log(arr[index])
}

当索引值是key时

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<Child1 ref='c1' />
<Child2 ref='c2' />
<button @click='getAllChilds($refs)'></button>

---

getAllChilds(refs:any){
console.log(refs)
/* key:value
refs:{
c1:Child1,
c2:Child2
}
*/

//同样地,遍历refs
for(key in refs){
console.log(refs[key])
}
}

插槽

  • 数据源在父组件,用默认插槽具名插槽给子组件插标签

  • 数据源在子组件,用作用域插槽。处理过程:子组件先给插槽传数据,插槽再将数据传给父组件中的子组件标签,从而实现数据访问

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    //父组件
    <template>
    <Child>
    <template #insert="params"> //#insert="params"等价于v-slot:insert="params"
    <ul>
    <li v-for="games111 in params.games111" :key="games111.id">
    {{game111.name}}
    <li>
    </ul>
    <template>
    </Child>
    </template>
    1
    2
    3
    4
    5
    6
    //子组件,数据在子组件
    <template>
    <div>
    <slot name="insert" :games111="game" x="1" y="2"> //作用域插槽子组件传数据给插槽,数据包装成一个对象
    </div>
    </template>

路由传参

/api/category?a=1&b=2&c=3

?表示要开始传参了

&用来分隔参数

prams传参::路由中的表示占位符


全局api(vue2)转移到应用对象(vue3)

  1. vue2:Vue.use(),Vue.mount()
  2. vue3: const app = createApp(App) app.use(),app.mount()
Donate
  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.

扫一扫,分享到微信

微信分享二维码
  • Copyrights © 2022-2024 CoffeeLin
  • Visitors: | Views:

请我喝杯咖啡吧~

支付宝
微信