1、数据渲染更新
vue
使用ref, reactive两个api创建的数据,修改后会页面会自动渲染更新。
<template>
<div> {{count}} </div>
<div> {{user.name}} 今年 {{user.age}}了</div>
</template>
import { ref, reactive} from 'vue'
const count = ref(1)
const user = reactive({name:'cat', age:3})
setTimeout(function() {
conut.value ++ //页面自动渲染更新
user.age = 4 //页面自动渲染更新
}, 1000)
React
使用useState这个api构建数据,返回一个数组,第一项是初始的数据,第二项是个渲染函数,调用它会触发组件的重新渲染。
const App = () => {
const [count, setCount] = useState(1)
const [user, setUser] = useState({name:'cat', age:3})
const add = () => {
// setCount(count + 1 )
setCount((count) => count + 1)
setUser({...user, {age:user.age + 1}})
}
return <div>
<button onClick={add}>加1</button>
{count}
<div> {user.name} 今年 {user.age}了</div>
</div>
}
如上述例子,使用setCount钩子用于组件重新渲染(自己命名,一般都是set+变量),两种方式,一种是直接传修改后的值,setCount(count+1); 值得注意的是,setCount是一个异步重新渲染的过程,当add函数里面的代码足够多的时候,会出现这么一种情况:当连续两次快速的点击的时候,此时页面count应该是3,但是显示为2; React针对这种情况,给setCount出了一种输入函数的的方式,可以这么写: setCount((preCount) => preCount + 1), return出去的值就是最新的值,然后参数preCount始终是最新的值。
2、操作Dom
Vue
使用ref,访问其返回值的.value属性即可获取相应dom。
<template>
<div ref="wrapRef" class="wrap"></div>
</template>
import { ref, onMounted } from 'vue'
const wrapRef = ref(null)
onMounted(() => {
console.log(wrapRef.value); // 打印出该dom
})
React
使用useRef钩子,访问其返回的.current属性即可获取相应dom,注意只能在函数组件中使用钩子。
import ReactDom from 'react-dom/client'
import { useRef } from 'react'
const App = () => {
const wrapRef = useRef()
const getRef = () => {
console.log(wrapRef.current) // 打印出该dom
}
return <div ref={wrapRef}>
<button onClick={getRef}>获得ref</button>
</div>
}
const root = ReactDom.createRoot(document.querySelector('#root'))
root.render(<App />)
在类组件中可以使用 React.createRef() api去创建存储dom属性的对象。
3、渲染一个列表
Vue
使用v-for在dom上渲染。
<tempalte>
<ul>
<li v-for="user in dataSource" :key=user.id > {{ user.name }}</li>
</ul>
</template>
const dataSource = [
{
id:1,
name:'小白',
age: 23
},
{
id:2,
name:'小红',
age: 24
},
]
React
使用map进行循环渲染。
const App = () => {
const dataSource = [
{
id:1,
name:'小白',
age: 23
},
{
id:2,
name:'小红',
age: 24
}
]
return <ul>
{dataSource.map((user) => {return <li key={user.id}>{ user.name }</li>})}
</ul>
}
4、父传子
Vue
通过属性传递和defineProps
接收父组件的数据,例如:
// 父组件
<template>
<Child data="[1,2,3]" />
</template>
// 子组件
const props = defineProps({
data: {
type: Object,
default: () => []
}
})
console.log(props.data) // [1,2,3]
React
通过属性传递和函数组件的传参接收父组件的数据,例如:
// 函数组件
function Calendar() {
const data = {name:'cat', age:18}
return <CalendarItem data={data} />
}
function CalendarItem(props) {
console.log(props.data) // {name:'cat', age:18}
}
// 类组件
class App extends React.Component {
data = {
name: 'cat',
age: 18
};
render() {
return (
<div>
<Child data={this.data} />
Hello, World !
</div>
)
}
}
class Child extends React.Component {
render() {
return <div>{this.props.data.name}</div> // cat
}
}
5、子传父
Vue
子组件使用defineEmits定义事件抛出。
// 子组件 Child.vue
<tepmlate>
<button @click="submit">点击</button>
</template>
<script setup>
const emit = defineEmits(['onSubmit'])
const submit = () => {
emit('onSubmit', 'something')
}
</script>
// 父组件
<tempalte>
<Child @onSubmit="onSubmit" />
</template>
<script setup>
const onSubmit = (value) => {
console.log(value) // 'something'
}
</script>
React
父组件上定义属性传递方法,子组件通过函数传参的方式传递数据。
const Child = (props) => {
const submit = () => {
props.onSubmit('something')
}
return <button onClick={submit}></button>
}
const App = () => {
const onSubmit = (value) => {
console.log(value) // 'something'
}
return <div>
<Child onSubmit={onSubmit} />
</div>
}
6、将DOM传递到指定位置
例如将弹出组件放置到根目录上。
Vue
使用Teleport组件,<Teleport>
接收一个 to
prop 来指定传送的目标。to
的值可以是一个 CSS 选择器字符串,也可以是一个 DOM 元素对象。
// 这段代码的作用就是告诉Vue“把以下模板片段传送到body标签下”。
<Teleport to="body">
<div v-if="open" class="modal">
<p>Hello from the modal!</p>
<button @click="open = false">Close</button>
</div>
</Teleport>
React
使用ReactDOM.createPortalapi, 语法ReactDOM.createPortal(jsx, dom)
, 例如:
import ReactDOM from "react-dom";
const root = document.querySelector('#root')
const Backdrop = (props) => {
return ReactDOM.createPortal(<div className="backdrop">
{props.children}
</div>, root);
};
周末了,不干了,下周边学边再更新吧