前端可以做到读写数据、切换视图、用户交互,这意味着,网页其实是一个应用程序,而不是信息的纯展示。这种单张网页的应用程序称为 SPA(single-page-application)。
2010年后,前端工程师从开发页面(切模板),逐渐变成了开发“前端应用”(跑在浏览器里面的应用程序)。目前,最流行的前端框架 Vue、Angular、React 等等,都属于 SPA 开发框架。
npm install create-react-app -g
create-react-app react-demo (react-demo项目名)
cd react-demo
npm install or cnpm install or yarn install
yarn start
引入模块
//第一步 导入react
import React,{Component} from 'react';
import '../assets/css/index.css'
import logo from '../assets/images/logo.svg';
import '../assets/css/App.css';
/**
* 绑定原生属性注意:
* class 要换成className
* for 要换成htmlFor
* style 要用{}包裹成对象
*/
//第二步,编写组件类并继承React.Component
class Home extends Component{
constructor(){
super();
//定义数据
this.state={
msg:'你好,世界!'
}
}
//第三步,重写render()方法,用于渲染页面
render(){
return (
{this.state.msg}
);
}
}
//第四步,导出该类
export default Home;
然后启动工程即可完成一个简单的demo
yarn start
react是面向组件的,通过JSX语法来操作虚拟dom节点,如果state的数据发生了变化则会触发对应的dom的刷新。JSX语法就是,可以在js文件中插入html片段,是React自创的一种语法。JSX语法会被Babel等转码工具进行转码,得到正常的js代码再执行。所有标签必须闭合
注意在本地引用img等资源时,需要通过{xx}对象形式引用。如果是网络图片,直接用url引用即可。
JSX语法就是,可以在js文件中插入html片段,是React自创的一种语法。JSX语法会被Babel等转码工具进行转码,得到正常的js代码再执行。所有标签必须闭合
react 通过state来定义和绑定数据,但这种绑定并不是MVVM那种双向数据绑定,在JSX中要使用时通过 this.state.xxx
来使用
用脚手架创建的工程的目录是有些不完整的,需要补全(为了方便归档)
component文件主要放组件,model放数据模型,App.js是默认的根组件,index.js是入口文件,相当于main,yarn.lock是项目生成的临时文件,package.json是依赖管理文件(类似maven的pom文件),nodel_modules是存放依赖包的文件夹
第一步 导入react
第二步,编写组件类并继承React.Component
第三步,重写render()方法,用于渲染页面
第四步,导出该类
如果要在模板中嵌套多个HTML标签,需要使用一个父元素对其进行包裹
{this.state.msg}
js中定义对象用{},其实就是restful风格的东东。
类似于
{
title:"xxx",
content:"xxxx"
}
数据的定义用[ ],一对方括号即可。
在react中绑定对象只需要在state中定义即可
this.state={
msg:'你好,世界!'
}
import React from 'react'
class Demo1 extends React.Component{
constructor(props){
super(props);
this.state={
msg:"demo1组件",
text:"",
keydown:"",
}
}
run=(e)=>{
alert(e.target.getAttribute('id')) //获取当前执行事件的dom节点
e.target.style.background='red';
}
inputChange=(e)=>{
//获取表单的值
//console.log(e.target.value);
this.setState({
text: e.target.value
})
}
inputChange1=()=>{
let value = this.refs.input.value;
this.setState({
text: value
})
}
getInputValue=()=>{
alert(this.state.text)
}
inputOnKeydown = (e)=>{
console.log(e.keyCode);
this.setState({
keydown:e.keyCode
})
}
inputChange2 = (e)=>{
this.setState({
text:e.target.value
})
}
changeTextMode = (e)=>{
this.setState({
text:"改变后的model值,可以看到下面这个输入框的数据已经改变,而上面两个输入框未发生变化"
})
}
render(){
return (
事件对象演示
{this.state.msg}
{/* 事件对象 */}
表单事件演示
{this.state.text}
ref获取dom节点,获得表单值
{this.state.text}
键盘事件
{this.state.keydown}
react实现双向数据绑定
model改变影响view(通过value属性),view改变影响model
model值:{this.state.text}
)
}
}
export default Demo1 ;
如果你用箭头函数写响应方法,则this指向的就是react的当前组件
run=(e)=>{
alert(e.target.getAttribute('id')) //获取当前执行事件的dom节点
e.target.style.background='red';
}
如果你用的是普通写法写的函数响应
funtion run(e){
alert(e.target.getAttribute('id')) //获取当前执行事件的dom节点
e.target.style.background='red';
}
需要使用下面这种写法传递对象指向
{this.state.text}
inputChange=(e)=>{
//获取表单的值,设置model的数据
//console.log(e.target.value);
this.setState({
text: e.target.value
})
}
getInputValue=()=>{
alert(this.state.text) //获取model中的数据
}
react实现双向数据绑定
model改变影响view(通过value属性),view改变影响model
model值:{this.state.text}
value 通过属性绑定model 完成 m->v的绑定
通过监听onChange完成v->m的绑定 ,和上面那个View->Model的绑定是一样的。
该练习的旨在熟悉双向数据绑定和react的基础用法,另外扩展了localStorage缓冲处理方案,实现刷新不会丢失数据状态。
import React, {Component}from 'react';
import Storage from '../model/storage'
class Demo3 extends Component {
constructor(props) {
super(props);
this.state = {
todo:'',
todolist:[],
};
}
//生命周期函数,页面加载触发
componentDidMount=()=>{
let list = Storage.get('todolist');
if(list){
console.log("get:"+list)
this.setState({
todolist:list
})
}
}
addTodoText=(e)=>{
this.setState({
todo: e.target.value
})
}
onAddBtnClick=()=>{
let todolist = this.state.todolist;
todolist.push({
todo:this.state.todo,
checked:false
})
this.setState({
todolist:todolist,
todo:""
})
//缓存数据
Storage.set("todolist",todolist);
}
onPressEnter=(e)=>{
if(e.keyCode==13){
this.onAddBtnClick();
}
}
ondelBtnClick=(index)=>{
let todolist = this.state.todolist;
todolist.splice(index,1);
this.setState({
todolist:todolist
})
//缓存数据
Storage.set("todolist",todolist);
}
checkChange = (index)=>{
let todolist = this.state.todolist;
todolist[index].checked=!todolist[index].checked;
this.setState({
todolist:todolist
})
//缓存数据
Storage.set("todolist",todolist);
}
render() {
return (
todoList 演示
未完成事项
{
this.state.todolist.map((value,index)=>{
if(!value.checked){
return (
-----{value.todo}
)
}
})
}
已完成事项
{
this.state.todolist.map((value,index)=>{
if(value.checked){
return (
-----{value.todo}
)
}
})
}
);
}
}
export default Demo3;
通过axios向服务端请求数据,我这里没有通过配置代理解决跨域问题,而是在后端配置了取消CROS请求来解决跨域问题
import React from 'react'
import axios from 'axios'
import request from '../model/server'
import jsonp from 'fetch-jsonp'
class Demo4 extends React.Component {
constructor(props) {
super(props);
this.state = {
list:[],
};
}
getData = ()=>{
let api = 'http://localhost:18080/house/resources/findAll'
axios.get(api)
.then((response)=>{
console.log(response)
this.setState({
list:response.data
})
})
.catch((error)=>{
console.log(error)
})
// let data =await request.get(api)
// console.log(data)
}
render() {
return (
axios获取服务器数据,未处理跨域,取消cros
url:http://localhost:18080/house/resources/findAll
{
this.state.list.map((value,index)=>{
return (
- {value.created}
)
})
}
jsonp获取服务器数据,跨域请求
怎么看,看你的地址加入callback=xxx之后是否能访问就知道是否支持jsonp了
);
}
}
export default Demo4;
所谓跨域问题就是 协议,域名,端口三者有其一不一致则出现跨域,一般情况下跨域是不被浏览器支持的。
Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。
使用
npm install --save axios
cnpm install react-router-dom --save
import {BrowserRouter as Router,Route,Link} from 'react-router-dom'
首页
新闻
{
this.state.list1.map((value,key)=>{
return (
//ES6模板字符串写法
{value.title}
)
})
}
aid:this.props.match.params.aid,
在prps.match.params中获取传参即可
无需定义路由格式,直接使用,在路由后面像get方法一样传参
类似"?name=zhong"这种
{value.title}
其中
?content=${value.content} 就是使用了get传参
componentDidMount(){
//通过npm带的url模块解析get参数 cnpm install url --save 安装即可
console.log(url.parse(this.props.location.search,true))
let news = {
aid:this.props.match.params.aid, //通过动态路由传值
content:url.parse(this.props.location.search,true).query.content, //通过get传值
}
this.setState({
news:news
})
}