Vue3.0新特性

初始化项目

  1. 安装 vue-cli3 (脚手架)
    在 cmd 窗口(注意了 这里得先下载node跟npm哦)

    npm install -g @vue/cli
    # OR
    yarn global add @vue/cli
    
  2. 创建项目

    vue create my-project
    # OR
    vue ui
    

    注意: 这里可能会有报错,大家可以尝试一下用管理者模式打开 powershell ,说不定能解决

  3. 在项目中安装 composition-api 体现vue3 新特性

    npm install @vue/composition-api --save
    # OR
    yarn add @vue/composition-api
    
  4. 在使用任何 @vue/composition-api 提供的能力前,必须先通过 Vue.use() 进行安装

    import Vue from 'vue'
    import App from './App.vue'
    import VueCompositionAPI from '@vue/composition-api'
    Vue.use(VueCompositionAPI)
    

去除console控制台等的报错

首先我们在创建脚手架的时候,可以选择不添加使用eslint 校验代码
不过嘛= =有些时候手贱也是在所难免的。看看这个文章
vue-cli3 取消关闭eslint 校验代码

setup() (重点)

setup() 是一个 新的生命周期函数
vue3专门给组件提供的新属性,它为我们使用vue3的 Composition API 新特性提供了统一的入口

  • 执行时机
    在beforeCreate之后,在create之前
  • 参数
    • 接收props数据
    • context是一个上下文对象,这个上下文对象包含了一些有用的属性,这些属性在 vue 2.x 中需要通过this才能访问到,在 vue3.x 中,只需要如下访问就可以了
import {} from '@vue/composition-api'
export default {
    setup(props,context) { // props 代表外界传入的属性
        window.console.log("setup"); // 如果我们没有去掉代码检测,我们就得在console前面加个window
        console.log(props.p1);
        console.log(context.attrs); 
    },
    props: {
        p1: String // 声明
    }
}

注意: setup() 里面无法获取this(其实是context代替了它)

reactive

reactive() 函数接收一个普通对象,返回一个响应对象,必须在 setup() 下面用

  • 基本语法

    • 按需导入reactive函数
    import {reactive} from '@vue/composition-api'
    
    • 创建 一个响应式数据对象
    setup() { 
            const state = reactive({count:0});
            console.log(state);
            state.count+=1; // 反手加个1
            console.log(state);
            return state
        },
    

    这一步类似于我们之前的data()函数
    然后我们就可以在 template中访问这个数据啦

    <template>
        <div>
            <p>count值为 {{count}}</p>
            <button @click="count+=1">+1</button>
        </div>
    </template>
    

ref(重点)

必须在 setup() 下面用

  1. 基本语法
    ref() 函数用来根据给定的值创建一个响应式数据对象,ref() 函数调用的返回值是一个对象,这个对象上只包含 .value 属性:

  2. 在template中访问ref创建的响应式数据

    <template>
        <div>
            <p>refCount的值为 {{refCount}}</p>
            <button @click="refCount+=1">+1</button>
        </div>
    </template>
    <script>
    import {ref} from '@vue/composition-api';
    export default {
        setup() {
            const refCount = ref(0);
            console.log(refCount.value);
            return {
                refCount
            }; 
        }
    }
    </script>
    

    注意:当我们创建出来的 响应式对象 在setup中要取出数据的话就得 取它的 value 属性,但当我们return出来的时候,我们就不需要取它的属性了

  3. 在reactive对象中访问ref创建的响应式数据
    当把 ref() 创建出来的响应式数据对象,挂载到 reactive() 上时,会自动把对象展开为原始的值,不需要 .value 就可以直接被访问到

const refCount = ref(0);
const state = reactive({
    refCount
})

console.log(state.refCount); //输出0
state.refCount++
console.log(refCount.value); // 输出1

注意: 如果ref重名了,那么新的ref会覆盖旧的ref

const c1 = ref(0);
const state = reactive({
    c1
})
// 再次创建 ref, 命名为 c2
const c2 = ref(9);
state.c1 = c2;
state.c1++;
console.log(state.c1);// 输出10
console.log(c2.value);// 输出10
console.log(c1.value);// 输出0

注意啦,这里有指针的概念,就是 原本 c1的地址 指向了 c2

isRef

用来判断某个值是否 ref() 创建出来的对象; 应用场景: 当需要展开某个可能为 ref() 创建出来的值的时候用到

import {isRef} from '@vue/composition-api'
const unwrapped = isRef(foo)? foo.value:foo;

toRefs

toRefs 函数可以将 reactive() 创建出来的响应式对象,转换为ref()类型的响应式数据。
我们先来说说reactive 函数的缺点

<template>
    <div>
        <p>count值为{{count}}</p>
        <button @click="add">+1</button>
    </div>
</template>
<script>
import {reactive} from "@vue/composition-api";
export default {
    setup() {
        const state = reactive({count:0,name: 'zs'});

        // 定义自增+1的函数
        // 函数最好也写进setup中
        const add = () => {
            state.count+=1;
        }

        return {
            ...state, // 通过这种方式return出去里面的值就固定了
            add
        };
    }
}
</script>

此时我们改一改return部分的state 即可

return {
    ...toRefs(state), // 这样会把state里面的每一个属性都转化为ref
    add
};

computed

computed() 用来创建计算属性,computed() 函数的返回值是一个 ref 的实例。使用 computed 之前需要导入

import {reactive, toRefs} from "@vue/composition-api";

创建只读的计算属性

注意,时刻记住 在setup函数里面 要去ref()对象的值需要用 .value 的方式取

const refCount = ref(0);
const computedCount =  computed( ()=> refCount.value +1 );
return {
    refCount,
    computedCount  // 此时 computedCount的值永远比上一个大1
};

创建可读可写的计算属性

在我们读数的时候,得到的结果会比原来的大 1 ,此时调用了get
在我们写数据的时候, 调用了set函数将 我们传入的数据-1 再赋值给count.value

const count = ref(1);
const plusOne = computed({
	get: () => count.value + 1,
	set: val => {
		count.value = val-1
	}
})
plusOne.value = 9
console.log(count.value) //输出8

watch

watch() 函数用来监听某些数据项的
当然,咱先得导入

基本用法

 const refCount = ref(0);
// watch默认情况下 组件在第一次创建的时候就执行了一次 如果不想它执行 就得传一个参数 {lazy:false}
watch(()=>console.log(refCount.value));
setTimeout(()=>{
    refCount.value += 1;
},1500);

监听指定的数据源

监视 reactive类型的数据源:

const state = reactive({
            count: 0
        })
watch(()=>state.count,
    (newVal,oldVal)=>{
        console.log(newVal,oldVal)
    },
    {lazy:true}// 这里让组件刚创建的时候不要运行
);

监视 ref 类型的数据源:

const count = ref(0);
watch(count,(newVal,oldVal) => {
	/*.....*/
})

监听多个数据源

监视 reactive类型的数据源:

const state = reactive({
            count: 0,
            name: 'zs'
        })
watch([()=>state.count,()=>state.name],
    ([newCount,newName],[oldCount,oldName])=>{
        console.log(newCount,newName)
        console.log(oldCount,oldName)
    },
    {lazy:true}
);
setTimeout(()=>{
    state.count += 1;
},1500);
setTimeout(()=>{
    state.name += "帅气";
},3000);

监视 ref 类型的数据源:
参照单个的用法修改上面的代码就好了。

清除监试

在setup() 内创建watch监视,会在组件销毁的时候自动销毁。如果明确地停止某个参数,可以调用watch() 函数的返回值即可

const stop = watch(()=>{
	/*...*/
})
stop()

在watch中清除无效的异步任务

有些时候,当贝watch监视的值发生改变时,或watch本身被stop之后,我们期望能够清除那些无效的异步任务,此时,watch回调函数中提供一个 cleanup registrator function 来执行清除的工作,这个清除函数会在如下情况下被调用:

  • watch被重复调用
  • watch 被强制stop了
    例子
<template>
    <div>
        <input type="text" v-model="kw">
    </div>
</template>

<script>
import {ref,watch} from "@vue/composition-api"
export default {
    setup() {
        const kw = ref("");
        const asyncPrint = val => {
            return setTimeout(()=>{
                console.log(val);
            },500);
        };
        watch(kw, (newVal,oldVal,clean)=> {
            const timerId = asyncPrint(newVal); 
            clean(()=>clearTimeout(timerId)) //清除之前没问完成的异步任务
        },{lazy:true});
        return {
            kw
        };
    }
}
</script>

解释一下:因为有些时候用户会按着键盘连续输入一些东西,如果我们对每个输入都进行ajax请求性能会很差,所以咱做个防抖,上面就是例子。

生命周期函数

先从黑马那边弄张图
在这里插入图片描述
当然使用之前我们还是要导入
说个题外话,在组件渲染的时候,我们尽量在mounted进行ajax请求
当我们定义生命周期函数的时候,有两种写法

  1. 像之前那样
setup() {
    console.log("setup") 
},
beforeMount() {
    console.log("onBeforeMount");
},
mounted() {
    console.log("onMounted");
}
  1. 写在setup函数里面
setup() {
    onBeforeMount(()=>{
        console.log("onBeforeMount");
    })

    onMounted(()=>{
        console.log("onMounted");
    })
 }

只是写在setup函数里面前边要加一个on(官方推荐)

provide&inject

provide() 和 inject() 可以实现嵌套组件之间的数据传递。这两个函数只能在 setup() 函数中使用。父级组件中使用 provide() 函数向下传递数据; 子组件中使用 inject() 获取上层传递下来的数据(无论多少级)

共享普通数据

父组件

import ComSonSon from './09.sonson';
export default {
    components: {
        'com-sonson': ComSonSon
    }
}

子组件

import {inject} from '@vue/composition-api'
export default {
    setup() {
        const color = inject('themeColor');
        return {
            color
        };
    }
}

共享 ref 响应式数据

传个ref数据就是了!!

template refs

通过 ref() 引用页面上的元素或组件
操作DOM

<template>
    <div>
        <h3 ref="h3Ref">h3ref</h3>
    </div>
</template>

<script>
import { ref,onMounted } from '@vue/composition-api'
export default {
    setup() {
    	//创建一个新的ref
        const h3Ref =  ref(null);

        onMounted(() => {
            console.log(h3Ref.value);
            h3Ref.value.style.color = 'red';
        })

        return{
            h3Ref
        }
    }
}
</script>

甚至还能操作组件的DOM
父组件

<template>
  <div>
    <com-son ref="comRef"/> // 在这里用ref指令绑定DOM
    <button @click="showCom">打印 comRef的值</button>
  </div>
</template>

<script>
import ComSon from './components/08.son'
import { provide ,ref } from '@vue/composition-api'
export default {
  name: 'app',
  components: {
    'com-son': ComSon,
    'com-refdom': ComRefDOM
  },
  setup() {
    const comRef = ref(null)
    const showCom = () => {
      console.log(comRef);
      console.log('str1的值是  ' + comRef.value.str1);
      comRef.value.setStr();
    }
    return{
      comRef,
      showCom
    }
  }
}
</script>

<style>

</style>

子组件

<template>
    <div>
        <h2>子组件</h2>
        <p>{{str1}}</p>
        <hr>
    </div>
</template>

<script>
import {ref} from '@vue/composition-api'
export default {
    setup() {
        const str1 = ref('this is 子组件')
        const setStr = ()=> {
            str1.value = '被赋值啦~~~'
        }
        return {
            str1,
            setStr
        }
    }
}
</script>

简单点说就是 setup 返回的ref响应式数据通过ref指令绑定DOM

createComponent

该函数不是必须的,除非你想完美结合TypeScript 提供的类型判断来进行项目的开发
这个函数仅仅提供了类型判断,能为setup() 中的props提供完整的类型判断

小结

vue3.0 相比之前更小更快更简便,数据绑定,对dom的操作也更加简单明了,按需导入,setup函数的出现对性能的提高十分明显。还有快速生成脚手架的优化,大大减轻了我们程序员的压力

以上内容综合了刘老师直播课的课程笔记所写

十分感谢尤雨溪给我们的惊喜

十分感谢黑马刘老师的教导

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值