我最一開始是先學的react
,而後也就前段時間開始學習vue
,一開始給個人感覺是二者很類似,react
給個人感受是靈活,vue
是一種死板的感受。爲何有這種感受呢,react
有一種很強烈的慾望,all in js只要可以用夠js
寫的,就全用js
寫,因此一切都很靈活,jsx
很酷,高階組件牛逼,es7
的裝飾器也是能夠玩的飛起。反觀vue
,搞的.vue單文件
仍是儘可能保留原來前端開發的模式,留下了template
、script
、style
三個最基本的東西,其實內部運做應該仍是和react
相似。html
react
看的各類道聽途說的文章,這玩意大概是怎麼玩的呢?簡單的說jsx
被解析成createElement
的方法,裏面傳到參數啊什麼的就是告訴react
怎麼渲染之類,而後方法返回一個虛擬dom
,大概是這麼搞的,具體細節我也不是太懂。前端
vue
一開始讓我挺暈的,官網的學習教程和通常寫的項目不太同樣,官網教程的例子沒有單文件,全是在選項對象中加入一個template
屬性,通常的項目開發的都是用的.vue
的單文件。一開始我是沒太理解.vue
這文件究竟是怎麼玩,只是按着這樣寫,不理解原理好像也可以基本完成本身想要的效果。vue
最近看了一些文章以及看了好幾遍官網的api
,官網的api仍是頗有必要每個都看一遍的,以前大體看一遍感受好多東西都沒有見到過,別人代碼看多了,發現不少沒用的api
仍是很強的。下面講講我對vue
的一些理解。node
vue
是怎麼玩的呢?每個vue
組件都是一個Vue
實例,這樣說也不是很準確,應該每個本身寫的組件都是經過調用Vue.extend
繼承Vue
後擴展出來的新的類的實例,想想怎麼定義一個vue
組件,就是調用了Vue.component
方法,react
// 註冊組件,傳入一個擴展過的構造器 Vue.component('my-component', Vue.extend({ /* ... */ })) // 註冊組件,傳入一個選項對象 (自動調用 Vue.extend) Vue.component('my-component', { /* ... */ }) // 獲取註冊的組件 (始終返回構造器) var MyComponent = Vue.component('my-component')
通常狀況下咱們寫的.vue單文件
暴露出來的就是一個選項對象,這個方法的內部自動調用了Vue.extend
。因此.vue單文件
本質上是vue-loader
去把<template></template>
裏的內容轉成字符串形式,塞到<scirpt></script>
裏面的export default {}
的對象裏面的template
去,固然了,這尚未完,template
屬性裏面的字符串也能夠說是一種糖,vue
內部是要調用Vue.compile
去作一次轉換,最終把template
的值轉換成render
,這個屬性的值是一個方法,這裏就和react
統一了,用是有個同名的函數createElement
去生成Vnode
。因此在選項對象中,能夠不給出template
屬性而是給出render
屬性,同時存在template
和render
的時候會忽視template
。git
看看官網render
用法:github
var getChildrenTextContent = function (children) { return children.map(function (node) { return node.children ? getChildrenTextContent(node.children) : node.text }).join('') } Vue.component('anchored-heading', { render: function (createElement) { // create kebabCase id var headingId = getChildrenTextContent(this.$slots.default) .toLowerCase() .replace(/\W+/g, '-') .replace(/(^\-|\-$)/g, '') return createElement( 'h' + this.level, [ createElement('a', { attrs: { name: headingId, href: '#' + headingId } }, this.$slots.default) ] ) }, props: { level: { type: Number, required: true } } })
看的出來這種直接寫render
比起template
要麻煩的多,因此爲了簡化這種寫法就搞出來了一個jsx
寫法,這裏又和react
又統一了。api
jsx
用法:iview
import AnchoredHeading from './AnchoredHeading.vue' new Vue({ el: '#demo', render: function (h) { return ( <AnchoredHeading level={1}> <span>Hello</span> world! </AnchoredHeading> ) } })
一般咱們寫react
和vue
都是一個寫一個組件customComp
,而後在別的組件要用的時候都是直接<customComp/>
寫進去的,可是有的組件就不能這麼作了,好比一個提醒的message
組件,我但願在react
中是這樣調用,像是一個工具類函數通常使用:dom
import message from 'message.js' import React from 'react' class XXXcomponent extends React.Component{ ... componentDidMount(){ message.info({ type:'success', text:'hello react!' }) } }
在vue
中我但願是這樣的調用的:
{ mounted(){ this.$message({ type:'success', text:"hello vue!" }) } }
在看了一些三方庫的這種組件的實現方式,來回折騰了一段時間,對react
和vue
理解的更深了一些。
先拿vue
說,先寫一個message.vue
的組件文件,而後在index.js
文件中把這個message.vue
文件import
進來,你能夠試着打印下這個vue
文件長得什麼樣,其實前面也分析過了,其實引進來的就是一個選項對象,並且<template></template>
標籤的內容也被弄成了render屬性了,前面也鋪墊過了vue.extend
,這裏把引入的選項對象傳入vue.extend
中就返回了一個擴展過的Vue
類了,而後咱們手動去new
一個message
的組件實例出來,能夠傳入一個propsData
就能把數據傳給到組件內部的prop
中去,打印下實例就會發現定義在.vue
文件中的data
、prop
之類的都有,這個時候咱們只是實例化了一個實例,其實在document
上是找不到這個節點的,只須要最後在實例上調用$mount(el)
,就能把實例掛載到document
上去了。直接修改實例上data
裏面定義的值,會發現也是響應的,至此這個message
組件咱們可以手動去控制這個組件了,具體細節該怎麼暴露出api
來個外部調用就不說了。
//僞代碼 import message from 'message.vue' import Vue from 'vue' const Constructor = Vue.extend(message) //擴展出一個新的類 const options = { innerProps:"inner props" } const instance = new Constructor({propsData:options}) //建立一個實例,也能夠傳給一個props instance.$mount(document.body) //組件掛在body下 //若是組件內部methods有方法,實例就能直接調用 // instance.innerFunction()
大致上是和vue
相似,有幾個地方有變化,引進來的組件,由於是用class extends React.Component
的形式寫的,看的出來已是擴展過react
後組件類了,直接去new
就能拿到實例了,或者是用React.createElement
傳入組件拿到虛擬dom
。和vue
不一樣的事,vue
有個$mount
方法幫助掛載組件到指定的位置,在react
中要用到react-dom
裏面的render
方法,傳入前面拿到的虛擬dom
以及要掛載的位置,這個方法會返回這個組件實例,這個時候就能夠調用組件實例的setState
方法去作一些事情了。
react
、vue
隨便用用帶仍是挺簡單的,個人觀點是api文檔
只能教會你70%的東西,可是你有了這70%的功力,大部分的東西基本都沒什麼問題,可是文檔以外的30%,每每是最難學的,可能須要剝開vue
、react
簡單易用的外表,來回看官方文檔,每次都能有新的體會,翻看第三方優秀的組件庫是最佳學習的方案,深刻地去理解內部原理才能真正的掌握。
這種組件函數式用法在個人fantastic-carnival(一個博客系統)中有體現:
其中有一個loadingBar
組件是一個加載條的組件,參考的是iview
組件庫中的vue
實現,同時我用react
也實現了一遍。