信用渭南网站建设,津seo快速排名,wordpress新窗口,聚商网络营销公司服务内容在构建html元素时#xff0c;vue倾向于模板方式#xff0c;而react则完全使用javascript的编程能力#xff0c;但vue也具备完全编程的能力#xff08;与react一样使用JSX和createElement渲染函数#xff09;。所以#xff0c;当vue使用完全编程方式时#xff0c;与react…在构建html元素时vue倾向于模板方式而react则完全使用javascript的编程能力但vue也具备完全编程的能力与react一样使用JSX和createElement渲染函数。所以当vue使用完全编程方式时与react可以说是大同小异。
学习react的时候有一个核心思想组件就是函数元素就是值。这对于vue来说也是完全适用的唯一的区别在于两者的限制和使用条件不同。 目录JSX元素渲染组件定义组件传值内容分发数据响应事件处理JSX
JSX是JavaScript的一个扩展语法本质是createElement渲染函数的语法糖。react和vue在JSX语法上几乎一致区别在于属性值的传入上。
react的JSX语法更接近 JavaScript 而不是 HTML所以 React DOM 使用 camelCase小驼峰命名来定义属性的名称而不使用 HTML 属性名称的命名约定。 例如JSX 里的 class 变成了 className而 tabindex 则变为 tabIndex。
vue的JSX则使用了一个Babel 插件使其更贴近HTML模板语法vue对大小写不敏感实际上vue会将所有属性值转换为小写。 例如tabIndex会转化成tabindexclassName会转化为classname。
特例对于属性classreact应写成classNamevue应写成class
react引入了Fragments使得react可以有多个根元素vue没有此功能只能是单一根元素
元素渲染
react的文档中提到了 元素是构成 React 应用的最小砖块。 const element h1Hello, world/h1 // 定义元素...
render () {return div{element}/div // 使用元素
}react将元素当作值来对待你可以直接使用也可以先赋值给某个变量然后再使用。 这一点在vue的文档中虽然没有明确提到但依然适用vue也可以先将元素赋值给某个变量然后在适当的位置使用该变量。
两者在使用时的区别在于
react可以在任意位置组件内和组件外定义元素并使用vue只能在组件内定义元素只要是组件内任意位置都可以render函数内data数据或者其他位置在组件外定义则会报错h is not defined
报错原因网上找到的一个说法是vue中组件外没有上下文联系找不到渲染函数。 思来想去只能归结于两者的渲染机制不同没有依据瞎猜的react可能是先赋值后渲染vue可能是先渲染后赋值
组件定义
react定义组件有两种方式函数组件和class组件两者在一定条件下可以相互转换函数式组件是无状态组件没有state状态和生命周期
// 函数组件
cosnt MyComponent props {return div{props.title}/div
}// class组件
class MyComponent extends React.Component {static defaultProps {} // 设置默认传入值constructor(props) {super()this.state {} // 设置状态值}... // 其他组件函数自定义方法生命周期方法...render() {return div{this.props.title}/div}
}vue文档给出的组件定义只有一种方式如下函数式组件无状态是在普通组件的基础上添加functional标记
Vue.component(my-component, {props: {title:String},...render () {return div{this.title}/div}
})实际上上诉方式是官方给出的一种完整使用组件定义和全局注册在实际项目中通常组件定义和注册都是分开的即组件的局部注册。
而react没有组件注册这一说法只有定义和使用vue实际上也可以和react一样直接定义并使用前提是使用JSX语法如果使用createElement渲染函数和模板方式仍然需要进行组件注册。
vue定义组件方式如下
// 函数式组件
const MyComponent {functional: true, // 函数式组件标记props: {title:String}, // 设置传入值// 为了弥补缺少的实例提供第二个参数作为上下文render(h, context) {return div{this.props.title}/div}
}
// 函数式组件的变种写法 -- 函数方式对照了react的函数组件的写法
// vue官方文档中没有提到这种写法但这种写法依然生效
// 与react函数式组件的不同之处在于react函数式组件的传入值是propsvue函数组件传入值是context上下文
cosnt MyComponent context {return div{context.props.title}/div
}// 普通组件
const MyComponent {props: {title:String}, // 设置传入值data () { return { user: } }, // 数据computed: {}, // 计算属性watch: {}, // 监听属性methods: {}, // 自定义方法... // 其他生命周期方法钩子函数等...render() {return div{this.props.title}/div}
}从上面react和vue的代码片段中可以看出react定义组件用的是class对象vue定义组件用的是Object对象两者的区别在于
class对象方法之间不需要分隔符Object对象的属性之间需要逗号,分隔对于传入值两者都是使用的propsreact只能定义默认值vue则可以限制传入类型并进行数据验证react要实现类型验证需要引入prop-types对于状态值react将状态值放入class对象的属性值state里并在constructor构造函数中完成数据初始化vue则将状态值放入data方法的返回值中对于自定义方法react可直接书写在class对象下vue则必需放入methods字段中数据监听react在生命周期方法componentDidUpdate中监听数据变化vue则提供了更为方便的computed和watch
组件传值
react和vue的组件传值都是通过组件属性进行传递的。
react不管是函数式组件还是普通组件将组件的所有属性都当作prop传入vue对于函数式组件 版本2.3.0之前如果一个函数式组件想要接收 prop则 props 选项是必须的版本2.3.0或以上如果定义了props选项则只能接收定义的prop版本2.3.0或以上如果省略 props 选项组件上所有的 attribute 都会被自动隐式解析为 prop vue对于普通组件 特殊属性class、style直接挂载到组件根元素上与组件内的class和style叠加合并组件上的属性如果在props中的定义了则作为prop传入对于没有声明的属性默认自动挂载到组件根元素上并覆盖原来的属性值可通过设置inheritAttrs属性开关此功能默认开启
内容分发
说完组件传值那就不得不说组件的内容分发这是一种特殊的组件传值其本质还是组件传值。 在vue中内容分发使用的是插槽slotreact则称为组件组合并且react特意强调了 React 中没有“槽”这一概念的限制你可以将任何东西作为 props 进行传递 最常见的就是如下以子节点children方式
MyComponenthello world/MyComponentreact提供了一个特殊的children prop用来接收分发内容vue函数式组件即可以通过children来接收内容也可以通过slots().default方式vue普通组件只能通过$slots.default的方式分发
vue函数式组件和普通组件对插槽slot使用的区别主要式因为函数式组件没有实列this而是使用上下文context详见vue函数式组件 vue的插槽分为普通插槽slots和作用域插槽scopedSlots作用域插槽可以完全替代普通插槽建议使用使用scopedSlots
简单的示列如下
// react 函数式组件
const MyComponent props {return div{props.children}/div
}
// react class组件
class MyComponent extends React.Component {render() {return div{this.props.children}/div}
}// vue 函数式组件
const MyComponent context {// children方式分发const { children } contextreturn div{children}/div// 通过插槽方式分发// const { slots } context// return div{slots().default}/div
}
// vue 普通组件
const MyComponent {render () {return div{this.$scopedSlots.default()}/div}
}多内容分发
react只需要传入对应的prop即可vue使用slots或scopedSlots进行分发
// react
...render () {return (divheader{props.header}/headermain{props.children}/mainfooter{props.footer}/footer/div)}
...
// react使用
MyComponentheaderhello worldchilren{pLorem ipsum dolor sit amet/p}footerthis is footer
/// vue
...render () {return (divheader{this.$scopedSlots.header()}/headermain{this.$scopedSlots.default()}/mainfooter{this.$scopedSlots.footer()}/footer/div)}
...
// vue使用
MyComponentscopedSlots{{ header: props hello, world,default: props pLorem ipsum dolor sit amet/p,footer: props this is footer}}
/对于内容分发react显得十分灵活及简便vue在使用上相对有部分限制vue可以使用作用域插槽react只能通过其他方式实现类似功能。vue插槽的JSX使用方式
实际上如果vue不使用插槽方式改用props也可以和react一样实现内容分发
// vue 使用 props 实现了内容分发定义和使用方式和 react 几乎一样
const MyComponent {props: [header, children, footer],render () {return (divheader{this.header}/headermain{this.children}/mainfooter{this.footer}/footer/div)}
}export default {render () {return (MyComponentheaderhello, worldchildren{pLorem ipsum dolor sit amet/p}footer{this is footer}/)}
}数据响应
响应式数据更新方式是vue与react的一个重要区别之一
vue的数据加入到响应式系统中直接操作数据会同步更新视图react必需使用setState方法更新数据以便实现视图的同步更新
事件处理
react的事件处理为了在回调中使用 this必须为该方法绑定this在构造函数中绑定或在事件处理程序传递参数vue则不需要这个绑定过程。