Vue3 五天速成(上)

简介: Vue3 五天速成(上)

day 1

1. 创建vue3工程

相关代码如下:

## 创建vue工程
npm create vue@lastest
## 安装node_modules
npm install // npm i

创建工程完毕之后,进入文件夹可以发现有如下文件,下图是文件介绍:

入口文件介绍:

这里main.ts是与index.html建立联系的;

通过.mount('#app')这样 main.ts就与index.html建立起了联系;

其中main.ts的代码格式如下:

<template>
    <div>
        <h1>你好</h1>
    </div>
</template>
<script setup lang="ts">
    // js或者ts
</script>
<style scoped>
    /* 样式 */
</style>

App.vue的代码格式如下:

<template>
    <div class="app">
        <h1>你好</h1>
    </div>
</template>
<script setup lang="ts">
    // js或者ts
</script>
<style scoped>
    /* 样式 */
    .app {
        background-color: #ddd;
        box-shadow: 0 0 10px;
        border-radius: 10px;
        padding: 20px;
    }
</style>

网页调试vue可以在chrome应用商店search vue.js devtools下载安装就好;

你好

### 2. 选项式API和组合式API

感觉vue2和vue3的主要不同就在于vue文件中script部分;其中vue2是选项式OptionsAPI的,vue3是组合式Composition的;

选项式API相关代码如下

注意,这里并没有setup

<script lang="ts">
    export default {
      // 定义组件名字
        name: 'Person',
        // 定义数据
        data(){
            return {
                name: '张三',
                age: 18,
                tel: '138888888'
            }
        },
        //  定义方法
        methods:{
            changeName(){
                this.name = 'zhang-san'
            },
            changeAge(){
                this.age += 1
            },
            showTel(){
                alert(this.tel)
            }
        },
    }
</script>

组合式相关代码如下

注意,这里的setup比beforecreate执行得还要早,setup的返回值也可以是渲染函数,data,method,setup可以同时存在,setup不可以读取data中的数据,反之则可以,因为setup是执行得最早的;

<script lang="ts">
    export default {
        name: 'Person',
        setup(){
            // 数据
            let name = '张三' // 此时name,age,tel 不是响应式的    应该改为ref或者reactive
            let age = 18    // 此时name,age,tel 不是响应式的  应该改为ref或者reactive
            let tel = '138888888'   // 此时name,age,tel 不是响应式的  应该改为ref或者reactive
            
            // 方法
            function changeName(){
                name = 'zhang-san'
            }
            function changeAge(){
                age += 1
            }
            function showTel(){
                alert(tel)
            }
            // 把数据和方法交出去
            return {name, age, changeAge, changeName, showTel}
        }
    }
</script>

setup语法糖简化后代码如下:

<script lang="ts">
    export default {
        name: 'Person',
    }
</script>
<script setup lang="ts">
    // 数据
    let name = '张三' // 此时name,age,tel 不是响应式的    应该改为ref或者reactive
    let age = 18    // 此时name,age,tel 不是响应式的  应该改为ref或者reactive
    let tel = '138888888'   // 此时name,age,tel 不是响应式的  应该改为ref或者reactive
    // 方法
    function changeName(){
        name = 'zhang-san'
    }
    function changeAge(){
        age += 1
    }
    function showTel(){
        alert(tel)
    }
    // 此时不需要return 自动提交
</script>

3. 响应式数据

响应式数据创建有两种方法,一种是ref,一种是reactive

ref定义基本类型的数据

使用的相关代码如下:

<template>
    <div class="app">
        <h2>姓名:{{ name }}</h2> // 利用大括号包起来的是不需要.value的
        <h2>年龄:{{ age }}</h2> // 利用大括号包起来的是不需要.value的
        <button @click="changeName">修改名字</button>
        <button @click="changeAge">修改年龄</button>
        <button @click="showTel">查看联系方式</button>
    </div>
</template>
<script setup lang="ts">
    import {ref} from 'vue'
    let name = ref('张三')
    let age = ref(18)   
    let tel = ref('138888888')
  // 在ref包裹住后,需要操作值都需要.value
    function changeName(){
        name.value = 'zhang-san'
    }
    function changeAge(){
        age.value += 1
    }
    function showTel(){
        alert(tel.value)
    }

这里值用ref包裹起来之后,变量会变成一个RefImpl类的数据,这时要修改值直接对变量操作是无意义的,我们需要对.value进行操作;这里要注意的是,ref也可以定义对象类的响应式数据,实现原理是先用ref包裹,再用reactive包裹,即取值还是需要用value

reactive定义对象类型的数据

使用的相关代码如下:

<template>
    <div class="app">
        <h2>姓名:{{ student.name }}</h2>
        <h2>年龄:{{ student.age }}</h2>
        <button @click="changeName">修改名字</button>
        <button @click="changeAge">修改年龄</button>
    </div>
</template>
<script lang="ts">
    export default {
        name: 'Person',
    }
</script>
<script setup lang="ts">
    import {reactive} from 'vue'
    let student = reactive({name:'张三', age:18})
    function changeName(){
        student.name = 'zhang-san'
    }
    function changeAge(){
        student.age += 1
    }
</script>
<style scoped>
    /* 样式 */
    .app {
        background-color: #ddd;
        box-shadow: 0 0 10px;
        border-radius: 10px;
        padding: 20px;
    }
    
    button {
        margin: 10px;
    }
</style>

reactive包起来后,对象变成了一个Proxy的对象,原对象在Proxy里面的target中;这里的reactive是深层次的,只能定义对象类型的响应式数据;

refreactive的对比

这里要注意的是,重新分配reactive的对象时,使用Object.assign,但是如果是利用ref定义的对象类数据,我们是可以直接进行替换的;

对响应式数据进行解构,toReftoRefs

let person = reactive({
  name: '张三',
  age: 18
})
let {name, age} = person
// let name = person.name
// let age = person.age
let {name, age} = toRefs(person) //把reactive对象里面的每一组对象转化为ref
// let name = toRef(person, 'name')
// let age = toRef(person, 'age')

4. 计算属性

v-bind 是 单向绑定,数据流向页面;v-model 是 双向绑定,页面也可以流向数据;

计算属性 computed 是只要响应式变量出现了变化,就随之变化;

使用例子如下:

<template>
    <div class="app">
        姓名:<input type="text" v-model="name"> <br>
        年龄:<input type="text" v-model="age"> <br>
        information: {{ information }}
    </div>
</template>
<script lang="ts">
    export default {
        name: 'Person',
    }
</script>
<script setup lang="ts">
    import {ref, computed} from 'vue'
    let name = ref('zhangsan')
    let age = ref(18)
    let information = computed(()=>{
        return name.value + age.value
    })
</script>
<style scoped>
    /* 样式 */
    .app {
        background-color: #ddd;
        box-shadow: 0 0 10px;
        border-radius: 10px;
        padding: 20px;
    }
</style>

computed是用来区别于方法的,使用computed得到的属性是没有缓存的,而且computed得到的属性是不可修改的;如果需要修改,则需要使用以下方法:

<template>
    <div class="app">
        姓名:<input type="text" v-model="name"> <br>
        年龄:<input type="text" v-model="age"> <br>
        information: {{ information }} <br>
        <button @click="changeInformation">修改information为lisi</button>
        
    </div>
</template>
<script lang="ts">
    export default {
        name: 'Person',
    }
</script>
<script setup lang="ts">
    import {ref, computed} from 'vue'
    let name = ref('zhangsan')
    let age = ref(18)
    let information = computed({
        get(){
            return name.value + '-' + age.value
        },
        set(val){
            const [s1, s2] = val.split('-')
            name.value = s1
            age.value = parseInt(s2)
        }
    })
    function changeInformation(){
        information.value = 'lisi-18'
    }
</script>
<style scoped>
    /* 样式 */
    .app {
        background-color: #ddd;
        box-shadow: 0 0 10px;
        border-radius: 10px;
        padding: 20px;
    }
</style>

day 2

5. watch 监视

情况1:监视ref定义的基本类型数据

停止监视只需要调用watch函数的返回值就可以;

<template>
    <div>
        <h5>情况1:监视【ref】定义的值是【基本类型】的数据</h5>
        sum : {{ sum }} <br>
        <button @click="changeSum"> sum + 1</button> <br>
        <hr>
    </div>
</template>
<script lang="ts">
    export default {
        name: 'Person'
    }
</script>
<script setup lang="ts">
    import {ref, watch} from 'vue'
    let sum = ref(1)
    function changeSum(){
        sum.value += 1
    }
    // 这里的sum是不需要添加.value的,返回值就是停止监视的函数
    const stopwatch = watch(sum, (newVal, oldVal)=>{
        console.log('sum变化了', newVal, oldVal)
        // 如果sum的最新值大于等于10则停止监视
        if(newVal >= 10 ){
            stopwatch()
        }
    })
</script>
<style scoped>
</style>

情况2:监视ref定义的对象类型数据

这里要注意的是:若修改的是ref定义的对象中的属性,newVal和oldVal都是新值,因为是同一个对象;若修改的是ref定义的整个对象,newVal是新值,oldVal是旧值,因为不是同一个对象;

<template>
    <div>
        <h5>情况2:监视【ref】定义的值是【对象类型】的数据</h5>
        姓名: {{ person.name }} <br>
        年龄: {{ person.age }} <br>
        <button @click="changeName">修改名字</button>
        <button @click="changeAge">修改年龄</button>
        <button @click="changeFull">修改整个人</button>
    </div>
</template>
<script lang="ts">
    export default {
        name: 'Person'
    }
</script>
<script setup lang="ts">
    import {ref, watch} from 'vue'
    let person = ref({
        name: '张三',
        age: 18
    })
    function changeName (){
        person.value.name = '李四'
    }
    function changeAge (){
        person.value.age = 19
    }
    function changeFull (){
        person.value = {name: '王五', age: 20}
    }
    // 监视【ref】定义的【对象类型数据】,监视的是对象的地址值,若想要监视
    // 对象的内部属性的变化,需要手动开启深度监视deep
    // 若修改的是ref定义的对象中的属性,newVal和oldVal都是新值,因为是同一个对象
    // 若修改的是ref定义的整个对象,newVal是新值,oldVal是旧值,因为不是同一个对象
    // watch的第一个参数是:被监视的数据
    // watch的第二个参数是:监视的回调
    // watch的第三个参数是:配置对象(deep, immediate ... )
    watch(person, (newVal, oldVal)=>{
        console.log('person变化了', newVal, oldVal)
    }, {deep: true})
</script>
<style scoped>
    button {
        margin: 10px;
    }
</style>

情况3:监视reactive定义的对象类型数据

很简单,只需要把ref定义的对象改为reactive定义的对象,然后在修改整个对象的时候使用Object.assign替换就可以;

<template>
    <div>
        <h5>情况3:监视【reactive】定义的值是【对象类型】的数据</h5>
        姓名: {{ person.name }} <br>
        年龄: {{ person.age }} <br>
        <button @click="changeName">修改名字</button>
        <button @click="changeAge">修改年龄</button>
        <button @click="changeFull">修改人</button>
    </div>
</template>
<script lang="ts">
    export default {
        name: 'Person'
    }
</script>
<script setup lang="ts">
    import {reactive, watch} from 'vue'
    let person = reactive({
        name: '张三',
        age: 18
    })
    function changeName (){
        person.name = '李四'
    }
    function changeAge (){
        person.age = 19
    }
    function changeFull (){
        // 并没有修改地址值;
        Object.assign(person, {name: '王五', age: 20})
    }
    // 监视【reactive】定义的对象类型数据,默认是开启深度监视的,而且深度是关不掉的
    watch(person, (newVal, oldVal)=>{
        console.log('person变化了', newVal, oldVal)
    })
    
</script>
<style scoped>
    button {
        margin: 10px;
    }
</style>

情况4:监视ref或者reactive定义的对象类型中的某个属性

<template>
    <div>
        <h5>情况4:监视【ref或reactive】定义的【对象类型】某个属性</h5>
        姓名: {{ person.name }} <br>
        年龄: {{ person.age }} <br>
        车辆:{{ person.car.c1 }}, {{ person.car.c2 }} <br>
        <button @click="changeName">修改名字</button>
        <button @click="changeAge">修改年龄</button>
        <button @click="changeC1">修改c1</button>
        <button @click="changeC2">修改c2</button>
        <button @click="changeCar">修改car</button>
    </div>
</template>
<script lang="ts">
    export default {
        name: 'Person'
    }
</script>
<script setup lang="ts">
    import {reactive, watch} from 'vue'
    let person = reactive({
        name: '张三',
        age: 18,
        car:{
            c1: 'asd',
            c2: 'das'
        }
    })
    function changeName (){
        person.name = '李四'
    }
    function changeAge (){
        person.age = 19
    }
    function changeC1(){
        person.car.c1 = 'qqq'
    }
    function changeC2(){
        person.car.c2 = 'www'
    }
    function changeCar(){
        person.car = {c1:'yyy', c2:'jjj'}
    }
    // 监视响应式对象中的某个属性,且该变量是基本类型的,要写成函数式
    /* watch(()=>person.name, (newVal, oldVal)=>{
        console.log('person.name变化了', newVal, oldVal)
    }) */
    // 监视响应式对象中的某个属性,且该属性是对象类型的,可以直接写,也能写函数,推荐写函数
    watch(()=>person.car, (newVal, oldVal)=>{
        console.log('person.car变化了', newVal, oldVal)
    }, {deep:true})
    
</script>
<style scoped>
    button {
        margin: 10px;
    }
</style>

情况5:监视多个数据

<template>
    <div>
        <h5>情况4:监视【ref】定义的值是【对象类型】的数据</h5>
        姓名: {{ person.name }} <br>
        年龄: {{ person.age }} <br>
        车辆:{{ person.car.c1 }}, {{ person.car.c2 }} <br>
        <button @click="changeName">修改名字</button>
        <button @click="changeAge">修改年龄</button>
        <button @click="changeC1">修改c1</button>
        <button @click="changeC2">修改c2</button>
        <button @click="changeCar">修改car</button>
    </div>
</template>
<script lang="ts">
    export default {
        name: 'Person'
    }
</script>
<script setup lang="ts">
    import {reactive, watch} from 'vue'
    let person = reactive({
        name: '张三',
        age: 18,
        car:{
            c1: 'asd',
            c2: 'das'
        }
    })
    function changeName (){
        person.name = '李四'
    }
    function changeAge (){
        person.age = 19
    }
    function changeC1(){
        person.car.c1 = 'qqq'
    }
    function changeC2(){
        person.car.c2 = 'www'
    }
    function changeCar(){
        person.car = {c1:'yyy', c2:'jjj'}
    }
    // 此时newVal和oldVal是数组与前面的对应
    watch([()=>person.name, ()=>person.age], (newVal, oldVal)=>{
        console.log('变化了', newVal, oldVal)
    })
    
</script>
<style scoped>
    button {
        margin: 10px;
    }
</style>

Vue3 五天速成(中)https://developer.aliyun.com/article/1504166?spm=a2c6h.13148508.setting.28.36834f0eJwPRIa

目录
相关文章
|
6天前
|
缓存 JavaScript UED
Vue3中v-model在处理自定义组件双向数据绑定时有哪些注意事项?
在使用`v-model`处理自定义组件双向数据绑定时,要仔细考虑各种因素,确保数据的准确传递和更新,同时提供良好的用户体验和代码可维护性。通过合理的设计和注意事项的遵循,能够更好地发挥`v-model`的优势,实现高效的双向数据绑定效果。
109 64
|
6天前
|
JavaScript 前端开发 API
Vue 3 中 v-model 与 Vue 2 中 v-model 的区别是什么?
总的来说,Vue 3 中的 `v-model` 在灵活性、与组合式 API 的结合、对自定义组件的支持等方面都有了明显的提升和改进,使其更适应现代前端开发的需求和趋势。但需要注意的是,在迁移过程中可能需要对一些代码进行调整和适配。
|
1月前
|
存储 JavaScript 前端开发
vue3的脚手架模板你真的了解吗?里面有很多值得我们学习的地方!
【10月更文挑战第21天】 vue3的脚手架模板你真的了解吗?里面有很多值得我们学习的地方!
vue3的脚手架模板你真的了解吗?里面有很多值得我们学习的地方!
|
2月前
|
API
vue3知识点:provide 与 inject
vue3知识点:provide 与 inject
35 4
vue3知识点:provide 与 inject
|
2月前
|
API
vue3知识点:readonly 与 shallowReadonly
vue3知识点:readonly 与 shallowReadonly
26 1
vue3知识点:readonly 与 shallowReadonly
|
28天前
|
JavaScript 前端开发 开发者
Vue 3中的Proxy
【10月更文挑战第23天】Vue 3中的`Proxy`为响应式系统带来了更强大、更灵活的功能,解决了Vue 2中响应式系统的一些局限性,同时在性能方面也有一定的提升,为开发者提供了更好的开发体验和性能保障。
57 7
|
29天前
|
前端开发 数据库
芋道框架审批流如何实现(Cloud+Vue3)
芋道框架审批流如何实现(Cloud+Vue3)
47 3
|
28天前
|
JavaScript 数据管理 Java
在 Vue 3 中使用 Proxy 实现数据双向绑定的性能如何?
【10月更文挑战第23天】Vue 3中使用Proxy实现数据双向绑定在多个方面都带来了性能的提升,从更高效的响应式追踪、更好的初始化性能、对数组操作的优化到更优的内存管理等,使得Vue 3在处理复杂的应用场景和大量数据时能够更加高效和稳定地运行。
46 1
|
28天前
|
JavaScript 开发者
在 Vue 3 中使用 Proxy 实现数据的双向绑定
【10月更文挑战第23天】Vue 3利用 `Proxy` 实现了数据的双向绑定,无论是使用内置的指令如 `v-model`,还是通过自定义事件或自定义指令,都能够方便地实现数据与视图之间的双向交互,满足不同场景下的开发需求。
49 1
|
1月前
|
前端开发 JavaScript
简记 Vue3(一)—— setup、ref、reactive、toRefs、toRef
简记 Vue3(一)—— setup、ref、reactive、toRefs、toRef