简述 vue3.0与2.0区别

1.Template  fragments碎片

    组件可以拥有多个根节点,解决多个div嵌套问题

2.数据获取

Vue3的数据获取在反应数据(Reactive Data)中,通常包含在一个反应状态(Reactive State)变量中。(reactive的作用是将对象包装成响应式对象,通过Proxy代理后的对象。)

 响应式原理: Proxy代理拦截:reactive函数执行,会将传入的target对象通过Proxy包装,拦截它的get,set等,并将代理的target缓存。(组件在render阶段,视图会读取数据对象上的值进行渲染,此时便触发了Proxy的get,由此触发对应的track函数,记录下了对应的ReactiveEffect,也就是常说的依赖收集。)

     1).Ref与reactive区别:

        reactive 和 ref 都是用来定义响应式数据的, reactive更推荐去定义复杂的数据类型, ref 更推荐定义基本类型,ref 和 reactive 本质我们可以简单的理解为ref是对reactive的二次包装, ref定义的数据访问的时候要多一个.value。(ref定义基本数据类型,ref也可以定义数组和对象)

   2).判断数据到底是ref还是reactive?

        通过isRef / isReactive 方法,对当前数据的__v_ref来判断的,如果有这个私有的属性, 并且取值为true, 那么就代表是一个ref类型的数据

 3.响应式数据

       在Vue3.0,我们就需要使用一个新的setup()方法,此方法在组件初始化构造的时候触发。

使用以下三步来建立反应性数据:

1)从vue引入reactive

2)使用reactive()方法来声名我们的数据为反应性数据

3)使用setup()方法来返回我们的反应性数据,从而template可以获取这些反应性数据

import { reactive } from 'vue'
export default {
  props: {
    title: String
  },
  setup () {
    const state = reactive({
      username: '',
      password: ''
    })

    return { state }
  }}

这里构造的反应性数据就可以被template使用,可以通过state.username和state.password获得数据的值,需要先声名一个方法然后在setup()方法中返回(return), 在组件内就可以调用这个方法了。

4.methods方法

       Vue3 的合成型API里面的setup()方法也是可以用来操控methods的。创建声名方法其实和声名数据状态是一样的。需要先声名一个方法然后在setup()方法中返回(return), 这样组件内就可以调用这个方法了。

export default {
  props: {
    title: String
  },
  setup () {
    const state = reactive({
      username: '',
      password: ''
    })

    const login = () => {
      // 登陆方法    }
    return { 
      login,
      state
    }
  }}

5.生命周期钩子

       现在 Vue3 的合成型API里面的setup()方法可以包含了基本所有东西。生命周期的钩子就是其中之一!但是在 Vue3 生周期钩子不是全局可调用的了,需要另外从vue中引入,生命周期的挂载钩子叫onMounted,引入后我们就可以在setup()方法里面使用onMounted挂载的钩子了。(与2.0生命周期相似,在前面加了on,setup这个生命周期发生在beforeCreate和created之前,此时无法访问data、computed、methods、refs )

6.计算属性 - Computed Properties

       Vue3 的设计模式给予开发者们按需引入需要使用的依赖包,在 Vue3 使用计算属性,需要在组件内引入computed。使用方式就和反应性数据(reactive data)一样,在state中加入一个计算属性。(计算属性可以写在声明的响应式变量内,也可单独声明使用)

 setup () {
    const state = reactive({
      username: '',
      password: '',
      lowerCaseUsername: computed(() => state.username.toLowerCase())
    })

 const twiceTheCounter = computed(() => counter.value * 2)

7.接收 Props

       接收组件props参数传递这一块为我们带来了Vue2和Vue3之间最大的区别。在 Vue2,this代表的是当前组件,不是某一个特定的属性。所以我们可以直接使用this访问prop属性值。就比如下面的例子在挂载完成后打印处当前传入组件的参数title。在 Vue3 中,this无法直接拿到props属性,emit events(触发事件)和组件内的其他属性。不过全新的setup()方法可以接收两个参数:           1.props - 不可变的组件参数

        2.context - Vue3 暴露出来的属性(emit,slots,attrs)

setup (props,context) {
   //Context的使用(// attrs (非响应式对象,等同于 $attrs用于简介传参,slots  插槽 非响应式对象,等同于 $slots,emit触发事件方法,等同于 $emit,expose 暴露公共property 函数,将setup里的内容暴露到外部)
    onMounted(() => {
      console.log('title: ' + props.title)
    })

  一个项目使用
 <Header title="Cnode客户端" color="red" /> //父组件里的子组件
//子组件的内容
<template>
  <header :style="{
    backgroundColor: color?color:defaultColor
  }">{{title}}</header>
</template>
<script>
import { reactive } from "@vue/composition-api";
export default {
  // 父组件传递进来更改该头部组件的属性值
  props: {
    // 标题
    title: String,
    // 颜色
    color: String
  },
  setup() {
    const state = reactive({
      defaultColor: "red"
    });
    return {
      ...state
    };
  }
};
</script>

8.模板引用

为了获得对模板内元素或组件实例的引用,一样声明 ref 并从 setup() 返回:

<template> 
  <div ref="root">This is a root element</div></template>
<script>
  import { ref, onMounted } from 'vue'
  export default {
    setup() {
      const root = ref(null)
      onMounted(() => {
        // DOM 元素将在初始渲染后分配给 ref
        console.log(root.value) // <div>This is a root element</div>
      })
      return {
        root }
}}
</script>

       这里在渲染上下文中暴露root,并通过ref=root,将其绑定到div作为其ref。(在虚拟dom补丁算法中,若Vnode的ref键对应于渲染上下文中的 ref,则 VNode 的相应元素或组件实例将被分配给该 ref 的值。这是在虚拟 DOM 挂载/打补丁过程中执行的,因此模板引用只会在初始渲染之后获得赋值,即在onMounted生命周期中)

9.watch监听

   使用从 Vue 导入的 watch 函数执行相同的操作。它接受 3 个参数:

  1. 一个想要侦听的响应式引用或 getter 函数
  2. 一个回调
  3. 可选的配置选项
import {  watch } from 'vue'
//一个变量
const counter = ref(0)
//监听函数 watch(监听的值,回调,可选的配置选项)
watch(counter, (newValue, oldValue) => {
  console.log('The new counter value is: ' + counter.value)
})

注意:侦听模板引用的变更可以替代前面例子中演示使用的生命周期钩子。

但与生命周期钩子的一个关键区别是watch() 和 watchEffect()在 DOM 挂载或更新之前运行副作用,所以当侦听器运行时,模板引用还未被更新。因此,使用模板引用的侦听器应该用 flush: 'post' 选项来定义,这将在 DOM 更新后运行,确保模板引用与 DOM 保持同步。

watchEffect(() => {
        console.log(root.value) // => <div>This is a root element</div>
      }, 
      {
        flush: 'post'
      })

 10.Mixin

        简述:Mixin 提供了一种非常灵活的方式,来分发 Vue 组件中的可复用功能。一个 mixin 对象可以包含任意组件选项。当组件使用 mixin 对象时,所有 mixin 对象的选项将被“混合”进入该组件本身的选项。

       局部mixins的配置:

  export const mixin1 = {
	methods: {
		showName(){
			alert('第一个mixin')
		}
	},
	mounted() {
		console.log('你好啊!')
	},}
export const mixin2 = {
	data() {
		return {
			sum:100
		}
	},
   methods: {
		showName(){
			alert('第二个mixin')
		}
	},
}
<script>
	import {mixin1,mixin2} from '../mixin'

	export default {
		name:'Student',
		data() {
			return {
				name:'张三',
				
			}
		},
		mixins:[mixin1,mixin2]
	}
</script>

 全局注册:全局mixins 对vm,和所有vm均进行mixins

//引入Vue
import Vue from 'vue'
//引入App
import App from './App.vue'
import {mixin1,mixin2} from '../mixin'
//关闭Vue的生产提示
Vue.config.productionTip = false
Vue.mixin(mixin1)
Vue.mixin(mixin2)
//创建vm
new Vue({
	el:'#app',
	render: h => h(App)
})

 11.自定义组件

       除了核心功能默认内置的指令 (例如 v-model 和 v-show),Vue 也允许注册自定义指令。注意,在 Vue 中,代码复用和抽象的主要形式是组件。然而,有的情况下,你仍然需要对普通 DOM 元素进行底层操作,这时候就会用到自定义指令。

       举个聚焦输入框的例子,如下:

//全局注册
const app = Vue.createApp({})// 注册一个全局自定义指令 `v-focus`
app.directive('focus', {
  // 当被绑定的元素挂载到 DOM 中时……
  mounted(el) {
    // 聚焦元素
    el.focus()
  }})
注册局部指令:
directives: {
  focus: {
    // 指令的定义
    mounted(el) {
      el.focus()
    }
  }}

注册局部指令:
directives: {
  focus: {
    // 指令的定义
    mounted(el) {
      el.focus()
    }
  }}
  使用方式:<input v-focus />
使用方式 <input v-focus />

12. 路由变化

 传参和原来一样,取参发生改变:

Params传参:
<router-link to="/home/111">点击跳转到home页面并传参</router-link>
 vue3.0中import { useRoute } from 'vue-router'
    const route = useRoute()
console.log(route.params.id);//111
query传参:
 <router-link to="/test?id=999">test</router-link>
    //接受的时候
  import { useRoute } from 'vue-router'
    const route = useRoute()
    console.log(route.query.id);//999
Js传参方式:
import { useRouter } from 'vue-router'
    const route = useRouter()
            route.push({
                path:"/lianxi",
                query:{
                    id:666
                }
            });
             route.push({
                name:'lianxi',
                params:{
                    id:666
                }
            });
   import { useRoute } from 'vue-router'
    const route = useRoute()
    console.log(route.query.id);//999

13.总结

       现在基本都看到vue2与vue3其实概念与理念都是一样的。只是有一些属性获取方式和声名和定义方式稍微变了。总结一下,我觉得 Vue3 给我们前端开发者带来了全新的开发体验,更好的使用弹性,可控度也得到了大大的提升。全新的合成式API(Composition API)可以提升代码的解耦程度 —— 特别是大型的前端应用,效果会更加明显。还有就是按需引用的有了更细微的可控性,让项目的性能和打包大小有更好的控制。

案例项目代码整理:

<template>
  <div class='form-element'>
    <h2> {{ state.title }} </h2>
    <input type='text' v-model='state.username' placeholder='Username' />
    
    <input type='password' v-model='state.password' placeholder='Password' />

    <button @click='login'>
      Submit
    </button>
    <p> 
      Values: {{ state.username + ' ' + state.password }}
    </p>
  </div></template>
<script>
import { reactive, onMounted, computed } from 'vue'
export default {
  props: {
    title: String
  },
//方法在组件初始化构造的时候触发,可以直接使用vue3的反应api,返回我们的反应性数据,从而template可以获取这些反应性数据
 //setup()方法可以接收两个参数:
   //props - 不可变的组件参数
//context - Vue3 暴露出来的属性(emit,slots,attrs)

 //props接收传的参数,emit是事件触发
   setup(props, { emit }) {
//reactive是反应数据是包含在一个反应状态(reactive state)变量中
    const state = reactive({
      username: '',
      password: '',
     //计算属性:在state中加入一个计算属性:
      lowerCaseUsername: computed(() => state.username.toLowerCase())
    })

    onMounted(() => {
      console.log('title: ' + props.title)
    })
//先声名一个方法然后在setup()方法中返回(return)
    const login = () => {
      emit('login', {
        username: state.username,
        password: state.password
      })
    }

    return { 
      login,
      state
    }
  }}</script>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值