Loading... > @author: 郭瑞峰 > @createTime: 2023/6/26 > @updateTime: 2023/7/13 如果说可以的话,建议大家学的第一个前端框架为 React ,这样就不用看我这篇文章了 如果你在看,说明你跟我一样,都是先学的vue框架,~~那么有必要看一看我的文章了~~ 废话到此,开始吹牛 ( ̄y▽, ̄)╭ ## 温故旧识 vue开发无外乎涉及到一下几个方面: - 数据读写 - 数据监听 - 函数方法使用 - dom事件绑定 - 获取dom节点 - 生命周期使用 - 父子组件通信 - 插槽 当然还有其他的,欢迎评论区补充 至于其他方面的什么 **路由router**、**全局状态管理store**、**UI组件库** 啥的,都不是Vue自带的,~~不是因为我懒才忽略的~~(就是因为我懒才不写的)。 ## 数据读写 vue提供了两种读写方法 react就直接简单了,只有一个读写方法 * vue 数据读写 ```typescript // vue3 + setup + ts import { ref, reactive, computed } from 'vue' // 方法一,通过 ref, reactive 实现数据双向绑定 const str = ref<string>('hello, this is Vue.js') const obj = reactive<Record<string, string>>({ name: 'vue', version: '3.3.4' }) str.value = '123456789' console.log(obj.name) // 方法二,通过 computed 间接实现其他地方(如store)数据读写 const aaa = ref<string>('Hello world') // 这个就当作从其他地方获取的数据吧 ㄟ( ▔, ▔ )ㄏ const msg = computed<string>({ get () { return aaa.value }, set (newVal) { aaa.value = newVal } }) msg = '333333333333' console.log(aaa.value) ``` ```javascript // vue2 + js export default { data () { return { str: '123456', aaa: 'hello world' // 这个也当作从其他地方获取的数据吧 ( ̄_, ̄ ) } }, computed: { msg: { get () { return this.aaa }, set (newVal) { aaa.value = newVal } } }, created () { this.str = '333' this.msg = '444' console.log(this.aaa) } } ``` * react 数据读写 ```typescript import React, { useState } from 'react' const Component: React.FC = function () { const [getCount, setCount] = useState<number>(0) return ( <> <div>{ getCount }</div> <button onClick={() => setCount(count => count + 1)} /> </> ) } ``` 不过这里注意一下,vue2中一些配置代码(如列表)必须经过`data`或`computed`注册,而vue3和react可以外部导入后直接调用 ## 数据监听 vue提供了 `watch` 帮忙监听数据变化 react提供了 `useEffect` 帮忙监听数据变化,但请注意,`useEffect`还有其他用途,并不局限于此 **注意**:vue中的数据监听`watch`可以直接获取新旧值,而react中数据监听`useEffect`不支持直接获取新旧值 * vue数据监听 ```typescript // vue3 + setup + ts import { watch, ref, reactive } from 'vue' const aaa = ref<string>('123456') const bbb = reactive<Record<string, string>>({ name: 'vue', version: '3.3.4' }) // 单个监听 watch(aaa, (val, oldVal) => { console.log(val) console.log(oldVal) }) // 多个监听 watch([aaa, bbb], (val, oldVal) => { console.log(val) console.log(oldVal) }, { deep: true, immediate: true }) ``` ```javascript // vue2 + js export default { data () { return { aaa: '333', bbb: { name: 'vue', version: '3.3.4' } } }, watch () { // 只支持单一监听 aaa (val) { // ...... }, bbb: { deep: true, immediate: true, hand } } } ``` * react 数据监听 ```typescript import React, { useState, useEffect } from 'react' function app () { const [count, setCount] = useState<number>(0) const [aaa, setAaa] = useState<string>('123') useEffect(() => { // 监听count // 注意:这个初始化时会执行一次,类似于 watch 的 immediate = true }, [count]) useEffect(() => { // 支持多个监听 }, [count, aaa]) } export default app ``` * react 获取新旧值方法示例 ```typescript import React, { useState, useEffect } from 'react' function app () { const [aaa, setAaa] = useState<string>('') useEffect(() => { // 获取新值 console.log(aaa) // 注意:这里面不要写 setAaa 方法,不然会陷入死循环! }, [aaa]) useEffect(() => { setAaa(aaa => { // 获取旧值 console.log(aaa) }) }, []) return (<></>) } export default app ``` ## 函数方法处理 vue3和react一样,都是直接**写函数**或**引用函数**就行,vue2不管怎样,都要注册到 `methods` 中 * vue 函数方法处理 ```typescript // vue3 + setup + ts import moment from 'moment' import { computed } from 'vue' const time = computed<string>(() => { return moment(new Date()).format('YYYY-MM-DD hh:mm:ss') }) function fn () { console.log(time) } fn() ``` ```javascript // vue2 + js import moment from 'moment' export default { methods: { // 这里注册 moment, hello () { console.log('hello') } }, computed: { time () { this.hello() return this.moment(new Date()).format('YYYY-MM-DD hh:mm:ss') } } } ``` * react 函数方法处理 ```typescript import moment from 'moment' import React from 'react' function app () { return (<> { moment(new Date()).format('YYYY-MM-DD hh:mm:ss') } </>) } export default app ``` ## dom事件绑定 vue和react都是dom直接绑,但是有区别。区别见下方代码注释 * vue dom事件绑定 ```html <!-- vue3 --> <template> <div> {{ count }} <!-- vue dom事件绑定时候必须传 运行函数 --> <button @click="setCount()"> +1 </button> <button @click="setCount(3)"> +3 </button> <button @click="() => { setCount(5) }"> +5 </button> <button @click="count += 7"> +7 </button> </div> </template> <script lang="ts" setup> import { ref } from 'vue' const count = ref<number>(0) function setCount (addNum: number = 1) { count.value += addNum } </script> ``` ~~vue2我就偷个懒不写了~~ * react dom事件绑定 ```typescript import React, { useState } from 'react' function app () { const [count, setCount] = useState<number>(0) const addNum = (num: number = 1) => { setCount(count => count + num) } return (<> { count } { /* react dom事件绑定时候必须传函数类型 */ } <button onClick={ addNum }> +1 </button> <button onClick={ () => { setCount(count => count + 3) } }> +3 </button> <button onClick={ () => { addNum(5) } }> +5 </button> </>) } export default app ``` ## 获取dom节点 除去原生的DOM操作外,vue和react都有自己的获取dom节点方式 * vue 获取dom节点 ```html <!-- vue3 --> <template> <div> <!-- 加标识 --> <button ref="btn" @click="showButton()" >show button dom<button> </div> </template> <script lang="ts" setup> import { ref } from 'vue' // 名称与标识保持一致 const btn = ref<HTMLInputElement>() function showButton () { console.log(btn.value) } </script> ``` ```html <!-- vue2 --> <template> <div> <!-- 加标识 --> <button ref="btn" @click="showButton()" >show button dom<button> </div> </template> <script> export default { methods: { showButton () { // 名称可以不用与标识一致 const button = this.$refs.btn } } } </script> ``` * react 获取dom节点 ```typescript import React, { useRef } from 'react' function app () { const btn = useRef<HTMLInputElement>(null) function showButton () { console.log(btn) } return (<> <button ref={btn}>show button dom</button> </>) } export default app ``` ## 生命周期使用 先看看 `vue3 setup` 与 `react` 生命周期(不完整)比对  相对于现在 react hooks 来说 ```typescript import React, { useEffect } from 'react' function app () { useEffect(function () { console.log('组件装载') return function () { console.log('组件卸载') } }, []) return ( <h1>this is testRoute component</h1> ) } export default app ``` ## 父子组件通信 父 => 子:vue和react都一样,通过 props传递 ```html <!-- vue3 --> <template> <childComponent title="data1" :value="23" /> </template> <script lang="ts" setup> import childComponent from 'xxxxxx' </script> ``` ~~咱懒了,就不写vue2了~~ ```typescript import React from 'react' import childComponent from 'xxxxxx' export default function () { return (<childComponent title="data1" :value="23" />) } ``` 子 => 父:vue可以通过`emits`向父传递回调事件,react可以通过向子组件传递回调函数实现 ```html <!-- vue3 --> <template> <button @click="sendMsg()">向父传消息</button> </template> <script lang="ts" setup> import { defineEmits } from 'vue' const $emits = defineEmits(['send']) function sendMsg () { $emits('send', 'this is ChildComponent') } </script> ``` ```typescript import React, { useCallback } from 'react' function Child ({ cb }) { return (<button onClick={cb}>向父传消息</button>) } function Parent () { const getChildEvent = useCallback(function () { console.log('Child component run click event') }, []) return (<Child cb={getChildEvent}>) } ``` ## 插槽 简单来说,就是向子组件传递 dom/其他组件 要求子组件能渲染出来 vue通过插槽方式实现,react通过获取`props.children`,加载到对应位置实现 * vue 实现方法 ```html <!-- vue3 parent --> <template> <ChildComponent> <h1>默认位置</h1> <h2 slot="place2">第二位置</h2> </ChildComponent> </template> ``` ```html <!-- vue3 parent --> <template> <div> <!-- 默认位置 --> <slot></slot> <hr/> <!-- 第二位置 --> <slot name="place2"></slot> </div> </template> ``` * react 实现方法 ```typescript import React from 'react' function Child ({ children }) { return ( <> { children[0] /* 默认位置 */} <hr/> { children[1] /* 第二位置 */} </> ) } function Parent () { return ( <Child> <h1>默认位置</h1> <h2>第二位置</h2> </Child> ) } ``` ## 结束 根据自己开发经验,咱就只有大致分层这几个 若是涉及其他的,请在评论区留言,不胜感激 若是有出入,欢迎大佬教我做人  最后修改:2024 年 11 月 27 日 © 允许规范转载 赞 0 如果觉得我的文章对你有用,请随意赞赏
1 条评论
建议增加田野调查素材,提升真实性。