1
头图

Vue3.0 + Ts

仅个人使用+简易理解笔录

环境配置

  1. 基础搭建
npm install -g @vue/cli

yarn global add @vue/cli
  1. 创建项目
vue create projectName

注:vue2.0 升级到vue3.0

vue add typescript

vue2.0存在许些问题

  1. 组件与组件之间依赖深,导致组件维护困难
  2. 跨组件代码重用不是特别友好

Vue3.0 API

  • 1.用于否
可不用情况 Composition Api 来编写组件,也可以不用此api来做组件
  • 2.用此API情况
TypeScript 支持

大型组件,Composition Api 组合可很好的管理状态

跨组件代码重用
  • 3. steup 简易介绍

setup 是用来配置组件状态的另一种实现。

在setup 中定义的状态,方法要想在模板中使用,必须 return

setup: () => {
    const list = ref([])

    // 赋值
    list.value = []

    return {
        list
    }
}

特别注意:

setup 方法是在 [components , props data Methods Computed Lifecycle methods] 之前执行

setup 中无法访问this
  • 4.ref 创建响应式变量
之前 Vue2 中,定义一个响应式变量直接在 data 中 定义即可。

而使用 composition api,我们得在 setup 中使用 ref 来创建响应式变量,并且得将它返回,才能在页面中使用。

使用示例

import { ref } from 'vue'
// 初始化变量
const test = ref('默认值')
// 赋值 
test.value = 'kai shi ....'
// 返回(可返回方法)
return {
    test
} 

实际使用栗子

<template>
    <div>
        <h1>{{test}}</h1>
    </div>
</template>

<script>
import {ref,defineComponent} from 'vue'
export default defineComponent({
    setup () {
        // 定义响应式变量
        const test = ref('栗子')
        
        // 输出
        console.log(test.value)

        // 变量赋值
        test.value = '来个新的值'
        // 返回变量
        return {
            test
        }
    }
})
</script>
  • 5. 生命周期
Composition Api 生命周期钩子与vue2.0一样只是多了一个前缀on
vue2.0生命周期

    beforeCreate: function() {
        console.log('Before Create');
    },
    created: function() {
        console.log('Created');
    },
    beforeMount: function() {
        console.log('Before Mount');
    },
    mounted: function() {
        console.log('Mounted');
    },
    beforeUpdate: function() {
        console.log('Before Update');
    },
    updated: function() {
        console.log('Updated');
    },
    beforeDestroy: function() {
        console.log('Before Destroy');
    },
    destroyed: function() {
        console.log('Destroyed');
    }
注:onMounted 在mounted之前执行
  • 对照表
APIHook (setup)
beforeCreate
created
beforeMountonBeforeMount
mountedonMounted
beforeUpdateonBeforeUpdate
updatedonUpdated
beforeUnmountonBeforeUnmount
unmountedonUnmounted
errorCapturedonErrorCaptured
renderTrackedonRenderTracked
renderTriggeredonRenderTriggered
  • 6.setup 中使用 watch响应式更改
// 引入
import { watch } from 'vue'
// 它有三个参数
1. 要监听更新的响应式引用或者 getter 函数
2. 一个回调用来做更新后的操作
3. 可选配置项

<template>
    <div>
        {{ count }}
    </div>
</template>
<script lang="ts">
    import { ref, watch } from 'vue'
    
    export default defineComponent({
        name: 'Demo',
        data() {
            return {
            }
        },
        setup(props) {
            const count = ref(10)

            setTimeout(() =>{
                count.value = 20
            })

            watch(count,(nVal, oVal) =>{
                console.log(`新值:${nVal} 旧值:${oVal}`) // 新值:20 旧值:10
            })

            return {
                count,
            }
        }
    })
</script>
  • 7.setup 中使用 computed
computed是从 vue 导入,computed 函数返回一个作为 computed 的第一个参数传递的 getter 类回调的输出的一个只读的响应式引用。为了访问新创建的计算变量的 value,我们需要像使用 ref 一样使用 .value property
<template>
    <div>
        {{ n }}
    </div>
</template>
<script lang="ts">
    import { ref, computed } from 'vue'
    
    export default defineComponent({
        name: 'Demo',
        data() {
            return {
            }
        },
        setup(props) {
            const count = ref(10)

            setTimeout(() =>{
                count.value = 20
            })

            const n = computed(() =>{
                return count.value
            })
            console.log(n.value)

            return {
                n,
            }
        }
    })
</script>
  • 8.关于setup
  1. 接收两个参数
props : 父组件传递过来的属性, setup` 函数中 props 是响应式的,它会随着数据更新而更新,并且不能使用 ES6 解构,因为它会不能使 props 为响应式。
context : 它是一个普通的对象,它暴露3个组件的· property, context不是响应式,可用es6解构解析
Attribute(attrs)
插槽(slots)
触发事件
<template>
    <div>
        
    </div>
</template>
<script lang="ts">    
    export default defineComponent({
        name: 'Demo',
        props:{
            list:{
                type: Object,
                default: {}
            }
        },
        data() {
            return {}
        },
        // 1
        setup(props, context) {
            console.log(`props:---- ${JSON.stringify(props)}`)

            console.log(`context:---- ${JSON.stringify(context)}`)
            // 解构解析
            const {attrs, slots, emit} = context
        },
        // 2 
        setup(props, {attrs, slots, emit}) {
            console.log(`props:---- ${JSON.stringify(props)}`)

            console.log(`context:---- ${attrs}`)
            console.log(`context:---- ${slots}`)
            console.log(`context:---- ${emit}`)
        },
    })
</script>
  1. 组件加载 setup 时注意事项
在组件执行 setup 时, 组件实例没有被创建,无法访问以下属性:
data
computed
methods
  • 9.跨组件传值
Vue2 中可以使用 Provide/Inject 跨组件传值,Vue3中也可以。
setup中使用
使用 Provide
  1. 用 ref / reactive 创建响应式变量
  2. 用 provide('name', '要传递的响应式变量')
  3. 添加一个更新 响应式变量的事件,这样响应式变量更新, provide 中的变量也跟着更新

使用示例:

父组件

<template>
 <div>
   <Child/>
   <button @click="abc">abc</button>
 </div>
 
</template>

<script lang="ts">
   import { provide, defineComponent, ref, reactive } from "vue";

   import Child from './child.vue'

   export default defineComponent({
       components:{
           Child
       },
       methods: {
           abc() {
               // 更新time值
               this.changeProvide(new Date().getTime()) // 改变值
           },
       },
       setup() {
           const list = ref("父组件");
           const testInfo = reactive({
               id: 100,
               msg: "一个栗子",
           });
           function changeProvide(t){
               testInfo.msg = t
           }
           provide('list',list)
           provide('test',testInfo)
           return {changeProvide};
       }
   
})
</script>

子组件

<template>
   <div>
       <h1>{{test.msg}}</h1>
       <h1>{{listData}}</h1>
   </div>
</template>

<script lang="ts">
import {provide, defineComponent,ref,reactive, inject} from 'vue'
export default defineComponent({
   setup () {
       const listData = inject('list')
       const test = inject('test')
       return {listData,test}
   }
})
</script>
  • 10.TypeScript使用
  1. 使用接口约束类型 interface
<template>
   <div>
       <ul>
           <li>
               {{ page }}
           </li>
       </ul>
   </div>
</template>

<script lang="ts">

interface queryParams{
   page: Number,
   size: Number,
   data: Object,
   total:  Number
}

export default defineComponent({
   data() {
       return{
           page:{
               page: 1,
               size: 10,
               data: {},
               total: 10,
           } as queryParams
       }
   }
})
</script>
  1. reactive使用
reactive()函数接收一个普通对象,返回一个响应式的数据对象
<template>
   <div>
       <ul>
           <li>
               {{ list }}
           </li>
       </ul>
   </div>
</template>

<script lang="ts">
interface Obj {
   name: String,
   id: String,
   address: String
}

import { defineComponent, reactive } from "vue"

export default defineComponent({
   setup(props) {
       const list = reactive({name:'一个栗子', id: 21, address:'192.168.1.110'}) as Obj

       return{
           list
       }
   }
})
</script>
  1. ref与reactive
ref只可以监听简单数据,reactive可以监听所有数据

ref修改数据需要使用这样count.value=xxx的形式,而reactive只需要ref修改数据需要使用这样count.属性名=值这样来使用

reactive在return时候需要toRefs来转换成响应式对象
reactive 使用
<template>
   <div>
       <ul>
           <li>
               {{ page }}
               {{ id }}
           </li>
       </ul>
   </div>
</template>

<script lang="ts">

import { defineComponent, reactive, toRefs } from "vue"

export default defineComponent({
   setup(props) {
       const list = reactive({name:'一个栗子', id: 21, address:'192.168.1.110'}) as Obj

       // 改变值
       list.id = 999
       return{
           ...toRefs(list),
       }
   }
})
</script>

### 关于interface用法

https://www.cnblogs.com/xch-j...


码厨
27 声望5 粉丝

学无止境...