vue2与vue3的使用区别

1. 脚手架创建项目的区别:

  • vue2: vue init webpack “项目名称”
  • vue3: vue create “项目名称” 或者vue3一般与vite结合使用:
npm create vite@latest
yarn create vite

2. template中结构

  • vue2: template下只有一个元素节点
<template>
	<div>
		<div></div>
		<div></div>
	</div>
</template>
  • vue3:template下可以有多个元素节点
<template>
	<div></div>
	<div></div>
	<div></div>
</template>

3. main.js入口文件挂载App.vue文件

  • vue2:
new Vue({
   app: '#app',
   router,
   ...
})
  • vue3:使用createApp
import App from './App.vue'
import router from '../src/router/index.js'

createApp(App).use(router).mount('#app')
// const app = createApp(App)
// app.use(router) // 挂载路由
// app.mount('#app')

4. router的区别

  • vue2:
在这里插入代码片
  • vue3: 使用createRouter,使用createRouter必须要写history
import { createRouter, createWebHistory } from 'vue-router'

const router = createRouter({
    history: createWebHistory(),
    // history: createWebHistory(import.meta.env.BASE_URL),
    routes: [
        {
            path: '/',
            component: () => import('@/App.vue'),
        },
        {
            path: '/props_pre',
            component: () => import('@/components/props_test/PropsTest.vue'),
        },
    ]
})

export default router

5. setup的使用

  • vue2: 引入子组件需要使用compontents{}挂载
import xx from '..子组件...'
<script>
	export default {
		components: { xx }
	}
</script>
  • vue3:
    引入子组件:
<template>
	<xx />
</template>

<script setup>
	import xx from '..子组件...';  // 引入子组件不需要再compontents{}挂载,在template中直接使用即可
	// 使用setup就不能使用export default{}导出了
</script>

如果需要使用export default则:
<script>
	export default {
	  setup() {
	    ...
	  },
	}
</script>        

6. props的使用

  • vue2
子组件中:
	export default{
		props: {
			xx: {
				type: String/Number/Object/Array,
				default: ''/0/()=>{}/()=()=>{}
			}
		},
		// props:['xx1', 'xx2']
	}
  • vue3: 如果报错 ‘defineProps’ is not defined则在package.json文件eslintConfig{env: {‘vue/setup-compiler-macros’: true }}中添加’vue/setup-compiler-macros’: true
defineProps(['xx1', 'xx2'])不需要引入直接使用,返回一个对象,数组或者对象写法都可
	子组件中使用   let  props = defineProps(['xx1', 'xx2']), // 在template中props可以省略{{props.xx1}} => {{xx1}},props名字可以随便取

<template>
	<span>{{props.name}}</span> // 可以省略props,直接使用name {{name}}
</template>
<script setup>
	let props = defineProps(['name', 'age']);
</script>

7. ref的使用

  • vue2:
<template>
	<Child ref="child1" />
</template>
// 使用
<script>
	export default {
		mouted() {
			console.log(this.$refs.child1); // 获取child1的ref有关数据
		}
	}
</script>
  • vue3: 需要先从vue中引入 ref, vue3中不可使用this
<template>
	<Child :money = money /> // 子组件也是用defineProps(['money'])接收
</template>

<script setup>
	import { ref } from 'vue'
	let money = ref(10000)
</script>

8. 自定义事件

下面这个Event1组件上的@click:

  • 在vue2框架当中,这种写法是自定义事件,可以通过.native修饰符变为原生DOM事件
  • 在vue3框架当中,这种写法就是原生DOM事件,绑定自定义事件为
<template>
	<Event1 @click="" />
</template>

自定义事件父子组件传值:

  • vue2中子组件用this.$emit(‘updateList’, 参数1, 参数2)调用
  • vue3使用setup组合式APIZ没有实例不能用this.$emit,vue3中使用defineEmits方法返回函数触发自定义事件
<script setup>
	// 利用defineEmits方法返回函数触发自定义事件
	// defineEmits方法不需要引入直接使用
	let $emit = defineEmits(['updateList']);
	const handleUpdateList = () => {
		$emit('updateList', 参数1, 参数2);
	}
</script>

注意:

<template>
	<Event2 @updateList="handle1" @click="handle2" />
</template>

<script setup>
	const handle1 = (参数1, 参数2) => {
		...
	}

	// click原生dom事件,点击就会执行
	const handle2 = (参数1, 参数2) => { // 子组件调用了父组件的click类型的方法,需要接收参数, 没调用传参时不用接收参数
		// alert(123) // 这是之前DOM事件时,点击就会执行
		...
	}
</script>

Event2子组件中

<template>
	<button @click="$emit('click', 参数1, 参数2)">子组件调用父组件click自定义事件</button>
<template>

<script setup>
	let $emit = defineEmits(['updateList']); // 此时在父组件点击子组件会执行alert(123)
	let $emit = defineEmits(['updateList', 'click']); // 此时在父组件点击子组件不会执行alert(123),这里把click类型的DOM事件变成了自定义事件
	...
	$emit('updateList', 参数1, 参数2)
<script>

9. 组件通信方式之全局事件总线

  • vue2:兄弟组件通信 b u s ( bus( bus(on, $emit)
  • vue3:没有实例,没有this,所以不能使用$bus,使用插件mitt
1.安装mitt
npm i --save mitt
2.新建bus/index.js文件
mitt是一个方法(),方法执行会返回bus对象
import mitt from 'mitt'; // 引入mitt插件
const $bus = mitt(); // 名字随意取
export default $bus;
3.使用
在父组件中使用两个子组件
eventBus.vue中
<template>
    <div class="box">
        <h1>全局事件总线$bus</h1>
        <div class="dis-flex">
            <ChildBus1 />
            <ChildBus2 />
        </div>
    </div>
</template>

<script setup>
import ChildBus1 from "./ChildBus1.vue";
import ChildBus2 from "./ChildBus2.vue";
</script>



在ChildBus1子组件中监听接收
<template>
    <div class="child1">
        <h3>我是子组件1: 曹植</h3>
    </div>
</template>

<script setup>
import $bus from '../../bus/index.ts';
// 组合式API函数
import { onMounted } from "vue";
// 当组件挂载完毕时,当前组件绑定一个事件,接收将来兄弟组件传递的数据
onMounted(() => {
    // 第一个参数:即为事件类型,第二个参数:即为事件回调
    $bus.on('car', (car) => {
        console.log(car, '在回调函数内可以做这个组件相应的操作');
    })
})
</script>



在ChildBus2子组件中发送
<template>
    <div class="child2">
        <h2>我是子组件2:曹丕</h2>
        <button @click="handleClick">点击我给我的兄弟送火箭</button>
    </div>
</template>

<script setup>
    // 引入$bus对象
    import $bus from '../../bus/index.ts'; 
    // 点击按钮回调
    const handleClick = () => {
        $bus.emit('car', {car: '火箭'});
    }
</script>

10. 组件通信方式之v-model

  • vue2:
  • vue3: 使用v-model, v-model不仅可以用来收集表单数据,实现数据双向绑定还可以用来父子组件之间通信
<template>
	<input type="text" v-model="name" />
</template>

<script setup>
// v-model指令:收集表单数据,数据双向绑定
// v-model也可以实现组件之间的通信,实现父子组件数据同步的业务
import { ref } from 'vue';
let name = ref('');
</script>

在vue的3.3版本中新加了defineModel,但是跟ref一样需要引入
import { defineModel } from 'vue';
let xx = defineModel();

v-model组件身上使用

<Child :modelValue="money" @update:moneyModel="handleMoney" /> 等价与
/**
	v-model组件身上使用
	第一:相当于给子组件传递props['modelValue'], 名字一定要叫modelValue
	第二:相当于给子组件绑定自定义事件update:modelValue
*/
<Child v-model="money" />
// 如果是v-model:money="money"这样的话,子组件传递props['money'], 名字不一定要叫modelValue了
<Child v-model:money="money" /> // 跟多个v-model一样的,然后这样的不用再绑定自定义事件,$emit那边就能更改

父组件

<template>
    <!-- <ChildModel1 :modelValue="money" @update:modelValue="handleUpdate" /> -->
    <ChildModel1 v-model="money" /> // 这句就相当于上面那行代码,用了这行代码可能会有报错,handleUpdate声明了却没使用,页面上叉掉报错是能正常增加的
</template>

<script setup>

import ChildModel1 from './ChildModel1.vue';
let money = ref(100);

const handleUpdate = (num) => {
    money.value = num;
}
</script>

子组件

<template>
    <div>父组件的钱:{{modelValue}}</div>
    <button @click="handleClick">点击更改父组件钱</button>
</template>

<script setup>
const props = defineProps(['modelValue']);
const $emit = defineEmits(['update:modelValue']);
const handleClick = () => {
    $emit('update:modelValue', props.modelValue + 1);
}
</script>

设置多个v-model

<template>
	<Child v-model:pageNo="pageNo" v-model:pageSize="pageSize" />
</template>

<script setup>
	import { ref } from 'vue';
	let pageNo = ref(1);
	let pageSize = ref(10);
</script>

11. 组件通信方式之useAttrs方法

  • vue3框架提供一个方法useAttrs方法,它可以获取组件身上的属性与事件

父组件中调用子组件并传参:

<template>
	<HintButton type="primy" :size="small" :icon="edit" />
</template>

<script setup>
	import HintButton from './HintButton.vue';
</script>

在HintButton子组件中:

<template>
	// 使用$attrs
	<el-button :type="$attrs.type"></el-button>
	// 还可以使用语法
	<el-button :="$attrs"></el-button> // 这种写法相当于

=> 可以简写为

</template> <script setup> // 1.这样可以获取子组件上的参数 let props = defineProps(['type', 'size', 'icon']); // 2.引入useAttrs方法:获取组件标签身上的属性与事件, 此方法执行会返回一个对象 import { useAttrs } from 'vue'; let $attrs = useAttrs(); </script>

注意:使用defineProps接收过的参数,useAttrs()就接收不到了,defineProps(['xxx'])的优先级更高,useAttrs方法不仅能接收到父组件传过来的参数,还能接收事件(DOM原生click事件和自定义事件),比如

12. 组件通信方式之ref与$parent

你可能感兴趣的:(vue.js,前端,javascript)