vue3新语法

Vue2与Vue3 最大的区别 — Vue2使用选项类型API(Options API)对比Vue3合成型API(Composition API)
作用: 聚合代码 & 逻辑重用

项目目录

node_modules       	// 所有的项目依赖包都放在这个目录下
public             	// 公共文件夹
favicon.ico			// 网站的显示图标
index.html       	// 入口的html文件
src                	// 源文件目录,编写的代码基本都在这个目录下
assets          	// 放置静态文件的目录,比如logo.pn就放在这里
components      	// Vue的组件文件,自定义的组件都会放到这
App.vue         	// 根组件,这个在Vue2中也有
main.ts         	// 入口文件,因为采用了TypeScript所以是ts结尾
shims-vue.d.ts   	// 类文件(也叫定义文件),因为.vue结尾的文件在ts中不认可,所以要有定义文件
.gitignore         	// 用来配置那些文件不归git管理
package.json       	// 命令配置和包管理文件
README.md          	// 项目的说明文件,使用markdown语法进行编写
tsconfig.json     	// 关于TypoScript的配置文件
yarn.lock          	// 使用yarn后自动生成的文件,由Yarn管理,安装yarn包时的重要信息存储到yarn.lock文件中

1. 使用 reactive 绑定数据

<template>
  <div>
    <h1>使用 reactive 绑定数据</h1>
    <p>{{state.msg}}</p>
    <p>{{info}}</p>
    <p>
      <button @click="changeMsg">changeMsg</button>
    </p>
  </div>
</template>
<script>

// Hooks 编程,在 vue 中导入对应的函数方法,面向函数式进行编程
// Vue-composition-API 这里就是Vue2与Vue3 最大的区别 — Vue2使用选项类型API(Options API)对比Vue3合成型API(Composition API)

import { defineComponent, reactive } from "vue";
export default defineComponent({
  name: 'test1',
  setup() {  // setup钩子函数
    // 使用响应式函数reactive构建proxy响应式对象state
    const state = reactive({
      msg: '时光'
    })
    console.log(state); // state对象是一个proxy拦截对象
    let info = 'hello'; // info是一个普通对象,修改后不会被proxy拦截,进而页面也不会动态更新
    const changeMsg = () => { // 在外边定义methods
      state.msg = '时光,你好'
      info = 'hello,你好'
    }
    return {  // 使用时,要把对象return出去,才能在template中使用
      state,
      info,
      changeMsg
    }
  }
})
</script>

2. setup()函数 完成父子通信

1. setup(props)第一个参数props

setup函数接收props作为其第一个参数,props对象是响应式的(单向的父—>子),watchEffect或watch会观察和响应props的更新。不要对props对象进行解构,那样会失去响应性。在开发过程中,props对象对用户空间代码时不可变的,用户尝试修改props时会触发警告

案例1:props作为setup的第一个参数

// 父组件 Home.vue
<template>
  <div class="home">
    <About :name="sendData"/>
  </div>
</template>
<script>
  import {ref} from 'vue'; 
  import About from './About'
  export default{
    components:{
      About,
    },
    setup(){
      const sendData = ref('这世界很酷');
      return {
        sendData
      }
    }
  }
</script>

// 子组件About.vue
<template>
  <div class="about">
  {{propContent}}
  </div>
</template>
<script>
  import {watchEffect} from 'vue';
  export default{
    props:{
      name:String
    },
    setup(props){
      let propContent= props.name;
     // watchEffect(()=>{
     //   propContent = props.name
     //})
      return {
        propContent
      }
    }
  }
</script>
2. setup(props,context)第二个参数Context上下文对象
// 父组件 Home.vue
<template>
  <div class="home">
    <About :name="sendData.val" @name-changed=changeName>
      世界变化不停,人潮川流不息
    </About>
  </div>
</template>
<script>
  import {reactive} from 'vue';
  import About from './About';
  export default{
    components:{
      About,
    },
    setup(){
      const sendData = reactive({
        val:'sendData'
      })

      setTimeout(()=>{
        sendData.val+=1;
      },1000)

      function changeName(msg){
        console.log(`子组件传递了${msg}过来`)
      }
      return {
        sendData,
        changeName,
      }
    }
  }
</script>

//子组件 About.vue
<template>
  <div class="about">
    <button @click="fn">子改父</button>
  </div>
</template>
<script>
  import {watch} from 'vue';
  export default {
    props:{
      name:String
    },
    setup(props, context) {
      console.log(context,"上下文");
      let num=100;
      let fn=()=>{
        content.emit('name-changed',num)//相当于this.$emit()
       }
      return {
          fn
        }
    );
    },
  }
</script>

3. 使用 ref、toRefs 绑定数据

<template>
  <div>
    <p>使用v-model双向数据绑定的数据内容是:{{ msg }}</p>
    <p>
      <!-- 自己实现双向数据绑定,监听input事件,动态修改nmsg的值 -->
      <input type="text" ref="myInput" @input="input" :value="nmsg" />
    </p>
    <p>使用@input事件动态实现双向数据绑定的数据内容是:{{ nmsg }}</p>
    <p>
      <!-- 使用ref方法动态定义并双向绑定hmsg -->
      <input type="text" v-model="hmsg" @input="hmagInpu" />
    </p>
    <p>使用ref方法动态定义并双向数据绑定的数据hmsg是:{{ hmsg }}</p>
    <p>toRefs 来实现在模板中不需要追加 state 调用数据:{{ msg }}</p>
  </div>
</template>
<script>
import {
  defineComponent,
  reactive,
  getCurrentInstance,
  toRefs,
  ref,
  computed,
} from "vue";

export default defineComponent({
  setup() {
    const state = reactive({
      msg: "",
      nmsg: "",
      cmsg: computed(() => {
        // 1.计算属性
        return state.msg.length;
      }),
    });

    // 2.可以使用getCurrentInstance hook 来拿到当前实例化对象上下文信息,但是除非极其特殊的情况,否则不建议这样使用
    const { ctx } = getCurrentInstance();
    const input = () => {
      // 在vue3中,因为是面向hooks函数编程,所以,无法通过this拿到当前vue实例化对象
      console.log(ctx.$refs.myInput.value); // 像使用vue2中的this一样,使用ctx(上下文内容信息)
      state.nmsg = ctx.$refs.myInput.value;
    };

    // 3.使用ref方法来定义一个响应式监听的对象,在实际开发中我们都是用这种方法来构建响应式对象
    const hmsg = ref("abc");
    const hmagInpu = () => {
      // 在内部使用hmsg的值,需要使用value来获取对应的值
      console.log("获取到的hmsg值是:" + hmsg.value);
    };

    return {
      // 4.使用toRefs hook方法方便,访问msg不需要使用state.msg,直接msg就可以获取到
      ...toRefs(state),
      hmsg,
      input,
      hmagInpu,
    };
  },
});
</script>

4. watch、watchEffect 数据监听

<template>
  <div>
    <h1>watch、watchEffect 数据监听</h1>
    <p>{{ msg }}</p>
    <p>{{ msg2 }}</p>
    <p>{{ info }}</p>
    <p>
      <button @click="changeMsg">changeMsg</button>
    </p>
    <p>
      <button @click="changeMsg2">changeMsg2</button>
    </p>
  </div>
</template>
<script>
import { defineComponent, reactive, watchEffect, watch, toRefs } from "vue";

export default defineComponent({
  name: "watch",
  // setup钩子函数
  setup() {
    // 使用响应式函数reactive构建proxy响应式对象state
    const state = reactive({
      msg: "时光",
      msg2: "kity",
      changeMsg2: () => {
        state.msg2 = "kity,你好";
      },
    });
    const changeMsg = () => {
      // 在外边定义methods
      state.msg = "时光,改变";
      info = "hello,改变";
    };
    let info = "hello";
    // watch监听只能是 getter/effect 函数、ref、reactive对象或数组
    // 简单监听
    watch(state, () => {
      console.log("观察整个state中属性变化", state.msg); // 只要state中的值有变化,就会打印
    });
    // 监听指定的信息
    watch(
      () => state.msg,
      (newVal, oldVal) => {
        console.log("01-msg的新值是:" + newVal + "-------旧值是:" + oldVal);
      }
    );
    // 监听多个属性(数组形式)
    watch([() => state.msg, () => state.msg2], (newVal, oldVal) => {
      console.log("02-msg的新值是:" + newVal + "-------旧值是:" + oldVal); // 02-msg的新值是:时光,你好,俞亮-------旧值是:时光,俞亮
    });
    // 不需要指定监听的属性
    watchEffect(() => {
      // 程序运行时,初始化就会执行一次,完成监听准备工作
      console.log("03-watchEffect监听 state 中数据变化:", state.msg); // 有点像computed计算属性,用到的数据发生改变才会执行
    });

    // 使用时,要把对象return出去,才能在template中使用
    return {
      ...toRefs(state),
      info,
      changeMsg,
    };
  },
});
</script>

5. 生命周期

setup中没有this ,使用生命周期时需要导入

setup() :开始创建组件之前,在beforeCreate和created之前执行。创建的是data和method
onBeforeMount() : 组件挂载到节点上之前执行的函数。
onMounted() : 组件挂载完成后执行的函数。
onBeforeUpdate(): 组件更新之前执行的函数。
onUpdated(): 组件更新完成之后执行的函数。
onBeforeUnmount(): 组件卸载之前执行的函数。
onUnmounted(): 组件卸载完成后执行的函数
// 若组件被<keep-alive>包含,则多出下面两个钩子函数。
onActivated(): 被包含在中的组件,会多出两个生命周期钩子函数。被激活时执行 。
onDeactivated(): 比如从 A组件,切换到 B 组件,A 组件消失时执行。

vue2与vue3生命周期的区别

Vue2--------------vue3
beforeCreate  -> setup()
created       -> setup()
beforeMount   -> onBeforeMount
mounted       -> onMounted
beforeUpdate  -> onBeforeUpdate
updated       -> onUpdated
beforeDestroy -> onBeforeUnmount
destroyed     -> onUnmounted
activated     -> onActivated
deactivated   -> onDeactivated

除了这些钩子函数外,Vue3.x还增加了onRenderTracked和onRenderTriggered函数

这两个钩子函数是Vue3.x版本新加的两个钩子函数,官方说是用来调试使用的,但是目前还没有给出具体的调试案例

onRenderTracked

// onRenderTracked,
// 它会跟踪页面上所有响应式变量和方法的状态,也就是我们用return返回去的值,他都会跟踪
import { .... ,onRenderTracked,} from "vue";
onRenderTracked((event) => {
  console.log("状态跟踪组件----------->");
  console.log(event);
});

onRenderTriggered

// onRenderTriggered,它不会跟踪每一个值,而是给你变化值的信息,并且新值和旧值都会给你明确的展示出来。
import { .... ,onRenderTriggered,} from "vue";
onRenderTriggered((event) => {
  console.log("状态触发组件--------------->");
  console.log(event);
});
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值