摘要:中的方法調(diào)用了并傳入了最新的值。在前一次渲染中,已經(jīng)將的設(shè)置為,并將的設(shè)置為
本文采用 es6 語法,完全參考 https://reactjs.org/docs/安裝
本文完全參考 React 官方 Quick Start 部分,除了最后的 thinking-in-react 小節(jié)
首先你需要點擊安裝 nodejs(npm)。然后執(zhí)行:
npm install -g create-react-app
如果上述命令執(zhí)行失敗可以運行以下命令:
npm install -g create-react-app --registry=https://registry.npm.taobao.org
然后建立一個 react 并運行:
create-react-app myApp cd myApp npm start
這樣你就簡單的完成了一個 react app 建立,其目錄結(jié)構(gòu)如下( 圖中不包括 node_modules 目錄,下同 ):
Hello World我們刪除一些不必要的東西,然后修改目錄結(jié)構(gòu)如下(不能刪 node_modules 目錄,如果刪了就在項目目錄下運行 npm i 就好了):
其中 components 是個目錄。
修改 index.js 如下:
import React from "react"; import ReactDOM from "react-dom"; ReactDOM.render(hello world!
, document.getElementById("root") );
然后命令行運行:
npm start
你就可以看到熟悉的 "hello world" 了
JSXJSX 是 react 中允許 js 和 html 混寫的語法格式,需要依賴 babel 編譯。這里我就只研究它的語法:
const element =Hello, world!
;
可以通過花括號在其中插入表達(dá)式:
function formatName(user){ return user.firstName + " " + user.lastName; } const user = { firstName: "Harper", lastName: "Perez" }; const element = (Hello, {formatName(user)}!
); ReactDOM.render( element, document.getElementById("root") );
可以將 HTML 語句寫為多行以增加可讀性,用小括號括起來可以防止自動插入分號導(dǎo)致的錯誤。
JSX 也是個表達(dá)式,所以可以用在 for 和 if 中:
function getGreeting(user){ if (user){ returnHello, {formatName(user)}!
; } returnHello, Stranger.
; }
我們可以正常使用引號給 HTML 標(biāo)簽添加屬性,也可以使用 js 表達(dá)式
const element = ; const element = ; //注意空標(biāo)簽以 /> 結(jié)尾,像 XML 一樣
注意 html 屬性名請使用小駝峰(camelCase)寫法
React 會在渲染之前 escape 所有在 JSX 嵌入的值,可以有效的防止 XSS 攻擊。
babel 會編譯 JSX 成 React.createElement() 的參數(shù)調(diào)用:
const element = (Hello, world!
); // 編譯為以下形式 const element = React.createElement( "h1", {className: "greeting"}, "Hello, world!" );
而 React.createElement() 會生成這樣一個對象(React 元素):
const element = { type: "h1", props: { className: "greeting", children: "Hello, world" } };元素渲染
在 ./public/index.html 中有一個 id 為 root 的 div。我們將這個 div 作為 react 渲染的容器。
回看 hello world 程序,通過 ReactDOM.render() 方法很輕松的把內(nèi)容渲染到了目標(biāo)容器上:
ReactDOM.render(hello world!
, document.getElementById("root") );
當(dāng)然也可以這樣寫:
let content =hello world!
; ReactDOM.render( content, document.getElementById("root") );
下面我們寫一個復(fù)雜的,這是個實時更新的時鐘,通過 setInerval 每隔 1s 調(diào)用 ReactDOM.render:
function Tick(){ const element = (); ReactDOM.render( element, document.getElementById("root") ); } setInterval(Tick, 1000);Hello, world!
It is {new Date().toLocaleTimeString()}.
重寫上面時鐘組件的代碼如下,使其組件化程度更高:
function Clock(props){ return (組件); } function Tick(){ ReactDOM.render( //這個地方不得不傳入一個參數(shù), 但理論上獲取一個時鐘直接獲取就可以了,這個問題我們后面再解決Hello, world!
It is {props.date.toLocaleTimeString()}.
, document.getElementById("root") ); } setInterval(Tick, 1000);
React 給我們提供了更好的管理我的代碼——組件。這里我們還是首先我們先了解一下自定義標(biāo)簽:
const element =;
對這個標(biāo)簽的理解也不難,它實際上調(diào)用了 Welcome 函數(shù),并且將所有的屬性(這里只有name)打包為一個對象傳給 Welcome 函數(shù)。所以下面這個代碼輸出 ”Hello Sara"
function Welcome(props){ returnHello, {props.name}
; } const element =; ReactDOM.render( element, document.getElementById("root") );
組件幫助我事先一些重復(fù)的工作,比如這樣:
function Welcome(props){ returnHello, {props.name}
; } function App(){ return (); } ReactDOM.render(, document.getElementById("root") );
我們可以通過傳遞參數(shù)得到同一個組件構(gòu)建的不同模塊。
這里我們需要補充一個重要的概念:__純函數(shù)!!!__
如果一個函數(shù)執(zhí)行過程中不改變其參數(shù),也不改變其外部作用于參數(shù),當(dāng)相同的輸入總能得到相同的值時,我們稱之這樣的函數(shù)為純函數(shù)。__React 要求所有組件函數(shù)都必須是純函數(shù)。__
其實之前的一段代碼中 Tick, Welcome 函數(shù)就可以看做是一個組件,同時 React 建議組件名的首字母大寫。但是更多情況下我們會用到 es6 的語法構(gòu)建組件。以之前時鐘代碼為例,轉(zhuǎn)換過程分為五個步:
新建一個類,類名同組件函數(shù)名Clock,并繼承自 React.Component;
給該類添加一個方法 render(/無參數(shù)/);
將 Clock 的函數(shù)體作為該函數(shù)的函數(shù)體;
將 render 方法中的 props 換為 this.props;
刪除原有的 Clock 函數(shù)
結(jié)果如下:
class Clock extends React.Component { render(){ return (); } }Hello, world!
It is {this.props.date.toLocaleTimeString()}.
但這樣計時的功能就不能用了,我們繼續(xù)往下看……
State 和 Lifecycle解決上面這個問題,就需要用到 State 和 Lifecycle 的知識了
我們給 Clock 類添加一個構(gòu)造函數(shù),并且刪除 Clock 標(biāo)簽中的參數(shù):
class Clock extends React.Component { constructor(props){ super(props); this.state = {date: new Date()}; //state 用來記錄狀態(tài) } render(){ return (); } } ReactDOM.render(Hello, world!
It is {this.state.date.toLocaleTimeString()}.
, //刪除參數(shù) document.getElementById("root") );
為了控制計時的生命周期,我們需要引入 2 個方法 componentDidMount() 和 componentWillUnmount(),前者在渲染(render方法)完成時立即執(zhí)行,后者在該 render 的內(nèi)容即將被移除前執(zhí)行。
很明顯,前者適合注冊計時器,后者可以用來清除計時器(防止內(nèi)存泄露)
componentDidMount(){ this.timerID = setInterval( () => this.tick(), 1000 ); } componentWillUnmount(){ clearInterval(this.timerID); }
下一步我們重寫 tick 函數(shù),此時的 tick 函數(shù)只需要修改 this.state 就行了。注意 React 要求不能直接修改該屬性,而是使用 setState() 方法,所以 tick 函數(shù)如下:
tick(){ this.setState({ date: new Date() }); }
這里需要注意的是,當(dāng) state 中有很多屬性的時候,比如:
this.state = {name:"Lily", age: 12};執(zhí)行 setState 方法修改其中的內(nèi)容時并不會影響未修改的屬性:
this.setState({name: "Bob"}); //此后 this.state 為 {name:"Bob", age: 12};此外 setState 可能是異步的,所以不要在更新狀態(tài)時依賴前值:
// 這是個反例 this.setState({ counter: this.state.counter + this.props.increment, });為例解決這個問題,你可以傳入函數(shù)參數(shù):
// Correct
this.setState((prevState, props) => ({ //這里 prevState 更新前的 state 對象,props 為新值構(gòu)成的對象
counter: prevState.counter + props.increment
}));
此時,完整的代碼為:
class Clock extends React.Component { constructor(props){ super(props); this.state = {date: new Date()}; } componentDidMount(){ this.timerID = setInterval( () => this.tick(), 1000 ); } componentWillUnmount(){ clearInterval(this.timerID); } tick(){ this.setState({ date: new Date() }); } render(){ return (事件); } } ReactDOM.render(Hello, world!
It is {this.state.date.toLocaleTimeString()}.
, document.getElementById("root") );
React 事件注冊和原生 DOM 事件類似的,這里需要理解一些不同點即可:
事件名使用小駝峰寫法,而不是全小寫,例如:onclick 寫作 onClick
注冊事件使用花括號表達(dá)式替代原有函數(shù)寫法
無法通過事件函數(shù) return false 的方式阻止默認(rèn)事件,必須顯式的調(diào)用 preventDefault(),并且在使用時不用糾結(jié)瀏覽器兼容問題,React 已經(jīng)幫你處理好了
React 建議通常不需要通過 addEventListener 添加事件,只需要像上方代碼那樣在 render 時綁定事件即可
在 es6 語法的組件中注冊事件只需要將事件函數(shù)定義為該類的一個方法,然后在 render 時綁定即可:
render(){ return ( ); }
在 class 中,除了箭頭函數(shù)定義的方法中 this 符合預(yù)期,其余方法中的 this 都是 undefined,應(yīng)該手動綁定。因此以下三個按鈕中 click2 會報錯。
class Button extends React.Component { constructor(){ super(); this.name = "Bob"; this.click3 = this.click2.bind(this); this.click1 = () => { console.log(`hello ${this.name}`); } } click2(){ console.log(`hello ${this.name}`); } render(){ return (); } }
以上幾種方法,React 推薦使用 click3 的實現(xiàn)方法,重寫如下:
class Button extends React.Component { constructor(){ super(); this.name = "Bob"; this.click = this.click.bind(this); } click(){ console.log(`hello ${this.name}`); } render(){ return (); } }
傳遞參數(shù)給事件的時候,第一個參數(shù)為 id, 第二個參數(shù)為 event。實際調(diào)用可以去以下兩種方式:
以上兩種方法等效,后一個方法的參數(shù) e 可以省略。
條件渲染根據(jù)不同的條件(通常指state)渲染不同的內(nèi)容, 比如下面段代碼可以根據(jù) isLoggenIn 渲染不同的問候語:
function UserGreeting(props) { returnWelcome back!
; } function GuestGreeting(props) { returnPlease sign up.
; } function Greeting(props) { const isLoggedIn = props.isLoggedIn; if (isLoggedIn) { // 根據(jù) isLoggenIn 渲染不同的問候語 return; } return ; } ReactDOM.render( // 你可以嘗試設(shè)置 isLoggedIn={true}: , document.getElementById("root") );
下面用 class 實現(xiàn)一個復(fù)雜一點的,帶有登錄/注銷按鈕的:
function LoginButton(props) { return ( ); } function LogoutButton(props) { return ( ); } class LoginControl extends React.Component { constructor(props) { super(props); this.state = { isLoggedIn: false }; // 修正 this 綁定 this.handleLoginClick = this.handleLoginClick.bind(this); this.handleLogoutClick = this.handleLogoutClick.bind(this); } handleLoginClick() { this.setState({isLoggedIn: true}); } handleLogoutClick() { this.setState({isLoggedIn: false}); } render() { const { isLoggedIn } = this.state; let button = null; if (isLoggedIn) { button =; } else { button = ; } return ( {/* Greeting 取自上一個示例 (注意這里的注釋寫法)*/}); } } ReactDOM.render({button} , document.getElementById("root") );
當(dāng)然,對于這樣一個簡單的示例,使用 if 可能你會覺的太復(fù)雜了,我們也可以使用 && ?: 這些運算符來代替 if 語句,就像寫 javascript 代碼一樣。我們極力的化簡一下上面的代碼:
class LoginControl extends React.Component { constructor(props) { super(props); this.state = { isLoggedIn: false }; } render() { const { isLoggedIn } = this.state; const button = isLoggedIn ? : ; return (); } } ReactDOM.render({ isLoggedIn ? "Welcome back!" : "Please sign up." }
{button}, document.getElementById("root") );
當(dāng)然,如果你需要在某個條件下不進(jìn)行渲染,那么直接輸出 null 即可,比如下面這個組件,在 props.warn 為 false 時不渲染任何內(nèi)容:
function WarningBanner(props) { if (!props.warn) { return null; } return (Warning!); }
需要注意的是,即便你輸出了 null, react 也會再渲染一次。同理,componentWillUpdate 和 componentDidUpdate 也會被調(diào)用。
列表在 React 中我們可以使用 map() 方法渲染列表,比如如下這個例子,將一組數(shù)據(jù)映射(map)為一組 dom:
const data = [1, 2, 3, 4, 5]; const listItems = data.map((item) =>
我們注意到這里我們給 li (即列表的每個元素)標(biāo)簽加了一個 key 屬性,這個 key 用來幫助 React 判斷哪個元素發(fā)生了改變、添加或移除。關(guān)于這個 key 我們需要明白以下幾點:
最好保證 key 是一個字符串,并且在該列表中唯一,如果你的數(shù)據(jù)中實在沒有唯一的 key 可以選擇,那么就使用數(shù)組的索引(index)吧(不推薦這樣)
值得注意的是,如果你不給每個元素指定一個 key, react 會默認(rèn)使用索引(index)作為 key
key 的值只是給 React 起到類似暗示的作用,不會真正的傳遞給 dom, 所以如果你需要使用 key 的值,應(yīng)使用一個其它變量傳遞該值。
當(dāng)然,上面代碼我們也可以寫成 inline 的形式:
const data = [1, 2, 3, 4, 5]; ReactDOM.render(
表單的處理會和原生的 html 有一些區(qū)別,因為 React 可以很好的幫助你使用 js 控制你的表單,這里我們需要引入一個新的概念:受控組件。
受控組件說白了就是其值受 react 控制的組件。其中,表單的元素通常都會具有其自己的 state,該值會隨著用戶的輸入改變。比如下面這個例子,會在用戶提交時輸出用戶的名字:
class NameForm extends React.Component { constructor(props) { super(props); this.state = {value: ""}; this.handleChange = this.handleChange.bind(this); this.handleSubmit = this.handleSubmit.bind(this); } handleChange(event) { this.setState({value: event.target.value}); } handleSubmit(event) { alert("A name was submitted: " + this.state.value); event.preventDefault(); } render() { return (); } }
不難發(fā)現(xiàn),這里使用了,onchange 事件不斷的將用戶的輸入綁定到 this.state.value 上,然后通過和用戶輸入同步的重繪實現(xiàn)數(shù)據(jù)的顯示。這樣可以很好的控制用戶輸入,比如同步的將用戶輸入轉(zhuǎn)化為大寫:
handleChange(event) { this.setState({value: event.target.value.toUpperCase()}); }
理解了上面的內(nèi)容我們可以知道,單純給一個 input 賦值一個值用戶是不能修改的,比如下面這行代碼:
ReactDOM.render(, mountNode);
但如果你不小心他的值設(shè)為 null 或 undefined(等同于沒有 value 屬性),這個 input 就可以被更改了:
ReactDOM.render(, mountNode); setTimeout(function() { ReactDOM.render(, mountNode); }, 1000);
在 React 中 textarea 也是通過 value 屬性實現(xiàn)其內(nèi)容變化的,而非其子節(jié)點:
class EssayForm extends React.Component { constructor(props) { super(props); this.state = { value: "Please write an essay about your favorite DOM element." }; this.handleChange = this.handleChange.bind(this); this.handleSubmit = this.handleSubmit.bind(this); } handleChange(event) { this.setState({value: event.target.value}); } handleSubmit(event) { alert("An essay was submitted: " + this.state.value); event.preventDefault(); } render() { return (); } }
在 React 中,對于 select 也會顯得很方便,你不需要在 option 中通過 selected 改變其值了,而是在 select 標(biāo)簽上通過 value 屬性實現(xiàn):
class FlavorForm extends React.Component { constructor(props) { super(props); this.state = {value: "coconut"}; this.handleChange = this.handleChange.bind(this); this.handleSubmit = this.handleSubmit.bind(this); } handleChange(event) { this.setState({value: event.target.value}); } handleSubmit(event) { alert("Your favorite flavor is: " + this.state.value); event.preventDefault(); } render() { return (); } }
上面代碼默認(rèn)選中 Coconut。 這里值得注意的是,對于多選框,你可以傳入一個數(shù)組作為值:
當(dāng)你控制很多個表單組件的時候要是為每個組件寫一個 handler 方法作為 onChange 事件那就太麻煩了。所以 React 可以通過表單元素的 name 配合 event.target.name 來控制表單:
class Reservation extends React.Component { constructor(props) { super(props); this.state = { isGoing: true, numberOfGuests: 2 }; this.handleInputChange = this.handleInputChange.bind(this); } handleInputChange(event) { const { target } = event; const value = target.type === "checkbox" ? target.checked : target.value; const { name } = target; this.setState({ [name]: value }); } render() { return (); } } state 提升
這個部分,想說的不是個語法問題,而是代碼結(jié)構(gòu)問題。我們重點理解一個例子:計算溫度的功能。
我們實現(xiàn)2個輸入框(攝氏溫度和華氏溫度)的同步數(shù)據(jù)顯示,和對數(shù)據(jù)的簡單操作(判斷是否達(dá)到標(biāo)況下水的沸點100攝氏度)
我們先做點準(zhǔn)備工作,比如溫度轉(zhuǎn)換函數(shù):
function toCelsius(fahrenheit) { return (fahrenheit - 32) * 5 / 9; } function toFahrenheit(celsius) { return (celsius * 9 / 5) + 32; }
別忘了,一個好的程序員要能夠很好的控制數(shù)據(jù)輸入,所以我們再寫一個函數(shù)用來處理溫度,參數(shù)是溫度和溫度轉(zhuǎn)換函數(shù):
function tryConvert(temperature, convert) { const input = parseFloat(temperature); if (Number.isNaN(input) || typeof convert !== "function") { return ""; } const output = convert(input); const rounded = Math.round(output * 1000) / 1000; return String(rounded); }
我們先簡單實現(xiàn)這個功能:
function BoilingVerdict(props) { if (props.celsius >= 100) { returnThe water would boil.
; } returnThe water would not boil.
; }
然后我們寫一個組件用來讓用戶輸入溫度
class Calculator extends React.Component { constructor(props) { super(props); this.handleChange = this.handleChange.bind(this); this.state = {temperature: ""}; } handleChange(e) { this.setState({temperature: e.target.value}); } render() { const { temperature } = this.state; return (); } }
此時我們可以輸入攝氏溫度了,再添加一個數(shù)據(jù)華氏溫度的地方。這里我們從上面的 Calculator 中提出來輸入組件:
const scaleNames = { c: "Celsius", f: "Fahrenheit" }; class TemperatureInput extends React.Component { constructor(props) { super(props); this.handleChange = this.handleChange.bind(this); this.state = {temperature: ""}; } handleChange(e) { this.setState({temperature: e.target.value}); } render() { const { temperature } = this.state; const { scale } = this.props; return (); } }
這樣 Calculator 就簡單了:
class Calculator extends React.Component { render() { return (); } }
這樣2個輸入框就有了,但是它們還不能同步變化。而且 Calculator 組件不知道水溫是多少了,沒法判斷溫度了。這是我們應(yīng)該吧溫度狀態(tài)放在他們最近的公共祖先元素上,這里就是 Calculator 組件啦。
很明顯,首先要改的就是 TemperatureInput, 它不需要 state 了,我們應(yīng)該從參數(shù)獲取溫度了:
class TemperatureInput extends React.Component { constructor(props) { super(props); this.handleChange = this.handleChange.bind(this); } handleChange(e) { this.props.onTemperatureChange(e.target.value); } render() { const { temperature, scale } = this.props; return (); } }
之后我們修改 Calculator 的 state, 將 temperature 和 scale 放入其中, 并添加狀態(tài)轉(zhuǎn)換函數(shù):
class Calculator extends React.Component { constructor(props) { super(props); this.handleCelsiusChange = this.handleCelsiusChange.bind(this); this.handleFahrenheitChange = this.handleFahrenheitChange.bind(this); this.state = {temperature: "", scale: "c"}; } handleCelsiusChange(temperature) { this.setState({scale: "c", temperature}); } handleFahrenheitChange(temperature) { this.setState({scale: "f", temperature}); } render() { const { temperature, scale } = this.state; const celsius = scale === "f" ? tryConvert(temperature, toCelsius) : temperature; const fahrenheit = scale === "c" ? tryConvert(temperature, toFahrenheit) : temperature; return (); } }
到此所有的工作就完成了。我們總結(jié)一下,輸入數(shù)據(jù)時都發(fā)生了什么
當(dāng)用戶輸入時,react 調(diào)用了已經(jīng)申明的函數(shù)作為 onChange 事件。在這個例子中,就是 TemperatureInput 中的 handleChange 方法。
TemperatureInput 中的 handleChange 方法調(diào)用了 this.props.onTemperatureChange(), 并傳入了最新的值。而這個方法由父組件 Calculator 提供。
在前一次渲染中,Calculator 已經(jīng)將 Celsius TemperatureInput 的 onTemperatureChange 設(shè)置為 handleCelsiusChange,并將 Fahrenheit TemperatureInput 的 onTemperatureChange 設(shè)置為 handleFahrenheitChange。所以這兩個計算方法的調(diào)用取決于我們編輯哪一個 input。
在這兩個方法中,Calculator 組件通過調(diào)用 this.setState() 方法讓 react 以最新的輸入和當(dāng)前 scale 重繪該組件。
React 調(diào)用 Calculator 組件的 render 方法渲染頁面,兩個 input 中的值會基于當(dāng)前值和 scale 重新計算, 溫度轉(zhuǎn)換函數(shù)就是在這里被調(diào)用的。
React 通過 props 使用 Calculator 新傳入的數(shù)據(jù),分別調(diào)用每個 TemperatureInput 模塊中的 render 方法渲染 input 組件。
React DOM 更新 DOM 樹匹配新的數(shù)據(jù),我們編輯的 input 得到我們剛剛輸入的值,而另一個 input 得到轉(zhuǎn)換后的值。
我們看看官方給出的效果:
組合與繼承React 建議用組件組合的方式代替組件繼承。所以我們需要學(xué)習(xí)如何用組合代替繼承。
很多組件在事先是不知道自己的孩子(內(nèi)部的元素)的。比如對話框這樣的盒子型元素。我們需要使用 children 屬性來解決這個問題
function FancyBorder(props) { return ({props.children}); }
props.children 表示通過其他組件調(diào)用 FancyBorder 時的全部孩子元素,對應(yīng)下面例子,children 就是 h1 和 p 的 react 對象數(shù)組
function WelcomeDialog() { return (); } Welcome
Thank you for visiting our spacecraft!
但是當(dāng)組件缺乏共同點的時候,我們需要在組件中開很多孔,就像下面這個例子,這些孔可以很好的幫我們組合使用很多組件,而且 react 并不限制我我們傳遞參數(shù)的類型
function SplitPane(props) { return (); } function App() { return ({props.left}{props.right}} right={ } /> ); }
有時候我們想對組件做具體化分類的時候,邏輯上會很像繼承,比如 WelcomeDialog 是 Dialog 的一個具體化分類。但在 React 中我們依然用組合的方式實現(xiàn)這個功能:
function Dialog(props) { return (); } function WelcomeDialog() { return ( ); } {props.title}
{props.message}
當(dāng)然我們也可以用 class 的定義方式:
function Dialog(props) { return (); } class SignUpDialog extends React.Component { constructor(props) { super(props); this.handleChange = this.handleChange.bind(this); this.handleSignUp = this.handleSignUp.bind(this); this.state = {login: ""}; } render() { return ( ); } handleChange(e) { this.setState({login: e.target.value}); } handleSignUp() { alert(`Welcome aboard, ${this.state.login}!`); } } {props.title}
{props.message}
{props.children}
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/97630.html
摘要:考慮到是快速入門,于是乎我們就記住一點,當(dāng)修改值需要重新渲染的時候,的機制是不會讓他全部重新渲染的,它只會把你修改值所在的重新更新。這一生命周期返回的任何值將會作為參數(shù)被傳遞給。 安裝react npm install creat-react-app -gshowImg(https://segmentfault.com/img/remote/1460000015639868); 這里直...
摘要:一份開發(fā)者必備的技能清單,請查收。入門查漏補缺深入學(xué)習(xí)查看原圖下載源文件使用快速上手,并了解其中的概念。官方教程入門教程小書文章精讀,問題解答。 一份react開發(fā)者必備的技能清單,請查收。入門、查漏補缺、深入學(xué)習(xí)... showImg(https://segmentfault.com/img/remote/1460000018000950?w=1965&h=3332); 查看原圖 ...
摘要:本篇解釋中類的控制指令,與指令式界面設(shè)計相關(guān)。本專欄歷史文章介紹一項讓可以與抗衡的技術(shù)可視化開發(fā)工具非正經(jīng)入門之一三宗罪可視化開發(fā)工具非正經(jīng)入門之二分離界面設(shè)計可視化開發(fā)工具非正經(jīng)入門之三雙源屬性與數(shù)據(jù)驅(qū)動可視化開發(fā)工具非正經(jīng)入門之四 本系列博文從 Shadow Widget 作者的視角,解釋該框架的設(shè)計要點。本篇解釋 Shadow Widget 中類 Vue 的控制指令,與指令式界面...
摘要:今年以來,的文檔更新很快完善社區(qū)也日漸狀大,再加上于某廠你懂的大力的推廣,的前景十分光明。一般情況下,中小型的系統(tǒng)從遷移到版本大概只需要天的時間。快去動手嘗試吧原創(chuàng)新書移動前端高效開發(fā)實戰(zhàn)已在亞馬遜京東當(dāng)當(dāng)開售。 作者:曉飛(滬江Web前端開發(fā)工程師)本文原創(chuàng),轉(zhuǎn)載請注明作者及出處 Vue.js框架已經(jīng)火了好長一段時間了,早在2015年的雙11中,淘寶的部分導(dǎo)購業(yè)務(wù)——如:雙十一晚會搖...
摘要:一團隊組織網(wǎng)站說明騰訊團隊騰訊前端團隊,代表作品,致力于前端技術(shù)的研究騰訊社交用戶體驗設(shè)計,簡稱,騰訊設(shè)計團隊網(wǎng)站騰訊用戶研究與體驗設(shè)計部百度前端研發(fā)部出品淘寶前端團隊用技術(shù)為體驗提供無限可能凹凸實驗室京東用戶體驗設(shè)計部出品奇舞團奇虎旗下前 一、團隊組織 網(wǎng)站 說明 騰訊 AlloyTeam 團隊 騰訊Web前端團隊,代表作品WebQQ,致力于前端技術(shù)的研究 ISUX 騰...
閱讀 2161·2021-09-04 16:40
閱讀 1452·2021-08-13 15:07
閱讀 3605·2019-08-30 15:53
閱讀 3194·2019-08-30 13:11
閱讀 1069·2019-08-29 17:22
閱讀 1811·2019-08-29 12:47
閱讀 1469·2019-08-29 11:27
閱讀 2221·2019-08-26 18:42