-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
从 v-语法 到 jsx:给 vue 用户的 react 小例子 #7
Comments
声明式渲染// vue
<div id="app">
{{ message }}
</div> var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
}
}) // react component
class App extends Component {
constructor() {
super()
this.state = {
message: 'Hello React!'
}
}
render() {
return (
<div id="app">
{ this.state.message }
</div>
)
}
} // react stateless component
function App() {
const [message, _] = useState('Hello React!')
return (
<div id="app">
{message}
</div>
)
} |
声明式渲染// vue
<div id="app-2">
<span v-bind:title="message">
鼠标悬停几秒钟查看此处动态绑定的提示信息!
</span>
</div> var app2 = new Vue({
el: '#app-2',
data: {
message: '页面加载于 ' + new Date().toLocaleString()
}
}) // react component
class App extends Component {
constructor() {
super()
this.state = {
message: '页面加载于 ' + new Date().toLocaleString()
}
}
render() {
return (
<div id="app-2">
<span title={ this.state.message }>
鼠标悬停几秒钟查看此处动态绑定的提示信息!
</span>
</div>
)
}
} // react stateless comp
function App() {
const [message, _] = useState('页面加载于 ' + new Date().toLocaleString())
return <div id="app-2">
<span title={message}>
鼠标悬停几秒钟查看此处动态绑定的提示信息!
</span>
</div>
} |
条件渲染// vue
<div id="app-3">
<p v-if="seen">现在你看到我了</p>
</div> var app3 = new Vue({
el: '#app-3',
data: {
seen: true
}
}) // react comp
class App extends Component {
constructor() {
super()
this.state = {
seen: false
}
}
render() {
return (
<div id="app-3">
{
this.state.seen && // this.state.seen ?
<p> // <p>
现在你看到我了 // 现在你看到我了
</p> // </p> : null
}
</div>
)
}
} // react stateless comp
function App() {
const [seen, _] = useState(false)
return <div id="app-3">
{seen && <p>现在你看到我了</p>}
</div>
} |
循环渲染// vue
<div id="app-4">
<ol>
<li v-for="todo in todos">
{{ todo.text }}
</li>
</ol>
</div> var app4 = new Vue({
el: '#app-4',
data: {
todos: [
{ text: '学习 JavaScript' },
{ text: '学习 Vue' },
{ text: '整个牛项目' }
]
}
}) // react comp
class App extends Component {
constructor() {
super()
this.state = {
todos: [
{ text: '学习 JavaScript' },
{ text: '学习 React' },
{ text: '整个牛项目' }
]
}
}
render() {
return (
<div id="app-4">
{
this.state.todos.map(todo =>
<li>{ todo.text }</li>
)
}
</div>
)
}
} // react stateless comp
function App() {
const [todos, _] = useState([
{ text: '学习 JavaScript' },
{ text: '学习 React' },
{ text: '整个牛项目' }
])
return <div id="app-4">
{todos.map(todo =>
<li>{todo.text}</li>
)}
</div>
} |
处理用户输入// vue
<div id="app-5">
<p>{{ message }}</p>
<button v-on:click="reverseMessage">逆转消息</button>
</div> var app5 = new Vue({
el: '#app-5',
data: {
message: 'Hello Vue.js!'
},
methods: {
reverseMessage: function () {
this.message = this.message.split('').reverse().join('')
}
}
}) // react comp
class App extends Component {
constructor() {
super()
this.state = {
message: 'Hello React.js!'
}
}
reversMessage() {
this.setState(state => ({
message: state.message.split('').reverse().join('')
}))
}
render() {
return (
<div id="app-5">
<p>{ this.state.message }</p>
<button onClick={ () => this.reversMessage() }>逆转消息</button>
</div>
)
}
} // react stateless comp
function App() {
const [message, setMessage] = useState('Hello React.js!')
return <div id="app-5">
<p>{message}</p>
<button onClick={_ => setMessage(message.split('').reverse().join(''))}>
逆转消息
</button>
</div>
} |
处理用户输入// vue
<div id="app-6">
<p>{{ message }}</p>
<input v-model="message">
</div> var app6 = new Vue({
el: '#app-6',
data: {
message: 'Hello Vue!'
}
}) // react comp
class App extends Component {
constructor() {
super()
this.state = {
message: 'Hello React!'
}
}
handleChange(e) {
this.setState({message: e.target.value})
}
render() {
return (
<div id="app-6">
<p>{ this.state.message }</p>
<input
value={ this.state.message }
onChange={ e => this.handleChange(e) }
/>
</div>
)
}
} // react stateless comp
function App() {
const [message, setMessage] = useState('Hello React!')
return <div id="app-6">
<p>{ message }</p>
<input
value={ message }
onChange={ e => setMessage(e.target.value) }
/>
</div>
} |
组件化应用构建<div id="app-7">
<ol>
<todo-item
v-for="item in groceryList"
v-bind:todo="item"
v-bind:key="item.id">
</todo-item>
</ol>
</div> Vue.component('todo-item', {
props: ['todo'],
template: '<li>{{ todo.text }}</li>'
})
var app7 = new Vue({
el: '#app-7',
data: {
groceryList: [
{ id: 0, text: '蔬菜' },
{ id: 1, text: '奶酪' },
{ id: 2, text: '随便其它什么人吃的东西' }
]
}
}) const TodoItem = ({text}) =>
<li>{ text }</li>
class App extends Component {
constructor() {
super()
this.state = {
groceryList: [
{ id: 0, text: '蔬菜' },
{ id: 1, text: '奶酪' },
{ id: 2, text: '随便其它什么人吃的东西' }
]
}
}
render() {
return (
<div id="app-7">
<ol>
{
this.state.groceryList.map(({ id, text })=>
<TodoItem key={ id } text={ text }></TodoItem>
)
}
</ol>
</div>
)
}
} |
顶一个! 不太会Vue, @gaoryrt 还请补充Vue实现类似功能的对比。(不知道是不是主题之外了,全当增加活跃度来了,有错地方还请补充 = =! )
class App extends Component {
constructor () {
super()
this.inputRef = React.createRef()
}
componentDidMount () {
this.inputRef.current.focus()
}
render () {
return (
<form>
<input ref={this.inputRef} />
</form>
)
}
} const Sub1= React.lazy(() => import('./Sub1'))
const Sub2 = React.lazy(() => import('./Sub2'))
class App extends Component {
render () {
return (
<div>
<React.Suspense fallback={<div>Loading</div>}>
<Router>
<Switch>
<Route path='/sub1' component={Sub1} />
<Route path='/sub2' component={Sub2} />
</Switch>
</Router>
</React.Suspense>
</div>
)
}
} function withHOC(WrappedComponent) {
return calss extends Component {
// do anything you want
render () {
const { extra, ...otherProps } = this.props
const newProp = fromStateOrMethod
return (
<WrappedComponent
newProp={newProp}
{...otherProps}
/>
)
}
}
} class App extends Component {
constructor() {
// 初始化,设置state等
}
componentWillMount() {
// 第一次render之前调用
}
componentDidMount () {
// 第一次render之后调用, 在这里进行异步操作
}
componentWillReceiveProps (nextProps) {
// 父组件的状态发生变化会子组件会调用该方法,nextProps是传递过来新props
}
shouldComponentUpdate () {
// 决定是否更新,建议使用:PureComponent
}
componentWillUpdate () {
// 更新前调用
}
componentDidUpdate () {
// 更新render之后调用, 不要在这里进行setState, 会导致死循环
}
componentDidCatch () {
// 子组件的异常会倍这个方法捕获,但不能捕获自己组件产生的异常。
// 可以定义一个ErrorBoundary组件在最外层,将捕获的错误统一处理(例如可以:sentry到服务器)
}
componentWillUnmount () {
// 组件unmount之前会调用
}
render () {
// 渲染
}
} |
子组件引用<div id="ref-demo">
<input ref="inputRef">
</div> var refdemo = new Vue({
el: '#ref-demo',
mounted() {
this.$nextTick( // mounted + $nextTick 对应 componentDidMount
() => this.$refs.inputRef.focus()
)
}
}) callback ref class App extends Component {
componentDidMount () {
this._inputRef.focus()
}
render () {
return (
<input ref={ n => this._inputRef = n } />
)
}
} createRef class App extends Component {
constructor () {
super()
this.inputRef = React.createRef()
}
componentDidMount () {
this.inputRef.current.focus()
}
render () {
return (
<input ref={ this.inputRef } />
)
}
} |
插一句本篇主题是 下面的几个就相当于用 vue 实现 react 了 |
路由 + 异步 loading路由有 vue-router,异步组件 loading 有 高级异步组件的工厂函数 const Sub1= React.lazy(() => import('./Sub1'))
const Sub2 = React.lazy(() => import('./Sub2'))
class App extends Component {
render () {
return (
<div>
<React.Suspense fallback={<div>Loading</div>}>
<Router>
<Switch>
<Route path='/sub1' component={Sub1} />
<Route path='/sub2' component={Sub2} />
</Switch>
</Router>
</React.Suspense>
</div>
)
}
} Vue.use(vueRouter)
const router = new vueRouter({
routes: [
{ path: '/sub1', component: () => import('./sub1') },
{ path: '/sub2', component: () => import('./sub2') }
]
})
const app = new Vue({
data: { loading: false },
template: `<div>
<div v-if="loading">loading</div>
<router-view v-else />
</div>`,
router
}).$mount('#app')
router.beforeEach((to, from, next) => {
app.loading = true
next()
})
router.afterEach(() => {
app.loading = false
}) |
高阶组件vue 里面最接近的语法应该是 mixin function withHOC(WrappedComponent) {
return calss extends Component {
// do anything you want
render () {
const { extra, ...otherProps } = this.props
const newProp = fromStateOrMethod
return (
<WrappedComponent
newProp={newProp}
{...otherProps}
/>
)
}
}
} function withHOC(WrappedComponent) {
const { extra, ...otherProps } = WrappedComponent.props
const newProp = fromStateOrMethod
return {
props: otherProps.concat(newProp),
render (h) {
return h(WrappedComponent, {
on: this.$listeners,
attrs: this.$attrs,
props: this.$props
})
}
}
} 更多讨论:Discussion: Best way to create a HOC |
生命周期
|
点错关闭了。。。 |
期待更深入的分析 |
话说 hook 出来了有些地方可以好好改改 |
这篇只记录了几个 vue 语法糖在 react jsx 中的实现,可以稍微直观对比一下二者的异同
(越发感觉 react 的定位和 vue 不同,react 比 vue 还要 view 一点
(当然 react 的写法很自由,我这里就不列举了
(我也是渣渣,有不对的地方麻烦指出来,共同学习
The text was updated successfully, but these errors were encountered: