react学习第五天笔记之项目实战

项目

项目架构

  • index.html为html模板文件;
  • app.js入口文件;用于引入路由和css文件等;
  • router.js为路由文件,里面设置了整个项目的路由设置;
  • component为所有的组件;
    • main.js为所有的组件的父级组件,里面设置子组件,作为整体布局;
    • logout,add,video组件都是main的子组件,通过在main中获取显示;
    • login组件与main是同级的;
  • public为静态文件
    • 此项目中需要与本地数据库连接,所以需要mongodb的静态封装文件;
  • 服务器与数据库
    • 数据库:分为两个;mongodb本地服务器,通过mongoose来与本地服务器连接,引入封装的db文件来进行数据库的增删改查;
      • "myvideo":存储本项目获取的数据内容;集合名为:"myimgdatas";
      • "video":模拟远程服务器的数据库,作为此项目获取数据的数据库;集合名为:"imgdata";
    • 服务器:分为两个;作用就是接受请求,操纵页面的显示和对数据库进行增删改查;
      • 一个是:模拟远程服务器,用于该项目获取数据的服务器;服务器地址:"http://localhost:4100";
      • 一个是:存储本项目的数据的服务器,连接本地数据库,服务器地址:"http://localhost:2100";
      • 注意:服务器中必须进行跨域设置,设置允许访问的域名为:"http://localhost:2871";
  • 发送请求的fetch方法封装文件:最重要文件,用于进行请求的设置;
    • 封装_request方法,用于发送请求;
    • 设置两个服务器api地址用于跨域请求;
    • 创建videoModel对象,对象中设置属性名,用于属性值为请求函数;用module.exports导出对象;通过解构赋值拿到videoModel对象,然后调用方法;
    • 使用时,只需引入dataFetch.js模块,然后调用方法,获取响应的数据;
    • 注意:发送请求也可以利用ajax发送请求,封装ajax方法,用于发送请求;

项目知识点

  • 页面渲染
    • 当获取后台数据后,需要对数组进行遍历,然后赋值组件,再插入到dom中;
    • 方法:封装一个函数,函数的返回值为数组,数组元素为赋值后的组件;再调用函数,放入到dom中;
    • 注意:返回值为数组,可以放入dom中显示,但必须对数组中每一项的组件设置key值;否则会报错;
    • 代码:
     toDom=()=>{
         if(this.state.allData.length>0){
             var aryList=[];
             aryList=$.map(this.state.allData,function (item,index) {
                 return (
                     
                         
                     
                 )
             });
             return aryList;//返回的数组,可以直接渲染到页面上,但必须给数组每一项设置key值
         }else{
             return 
    } }; render(){ const { classes } = this.props; return (
    {this.toDom()}
    ) }

知识点

  • ajax进行跨域请求
    • ajax请求中只有jsonp请求,才能进行跨域请求,而get,post等不能进行跨域请求;如果想要进行跨域请求,必须在服务器中进行相应的设置;
    • 如果服务器不跨域设置,只能使用ajax中的jsonp请求,来跨域请求,需要设置dataType为jsonp,设置jsonp参数为全局函数名称;
    • 注意:使用jsonp跨域请求,在服务器中必须设置相对应的跨域设置,而且必须设置像百度服务器一样,用wd来搜索数据,用jsonp来设置全局函数名,然后将数据作为实参传给此函数;
    • ajax请求百度服务器的封装代码:
     //此方法暂时不用,与fetch方法相同;
     import "jQuery/tmp/jquery";
     //封装ajax请求方法,通过jsonp进行跨域请求,请求百度服务器上的数据
     function _ajax(_method,_url,_data,_dataType,_jsonp,success,error) {
         $.ajax({
             type:_method,
             url:_url,
             data:_data,
             dataType:_dataType,//jsonp是跨域的
             jsonp:_jsonp,//回调函数名称
             success:function(val){//数据请求成功
                 success(val);
             },
             error:function (err) {//数据请求失败
                 error(err);
             }
         })
     }
     
     let url="https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su";
     
     let DataModel={
         getData:(param,success,error)=>{
             _ajax("get",url,{wd:param},"jsonp","cb",success,error);
         }
     };
     
     module.exports={
         DataModel
     };
    
  • 服务器的跨域设置
    • 第一种:设置中间件,进行跨域设置
      • 设置Access-Control-Allow-Origin的值为特定的域名地址,代表只能此域名能够访问,其他的域名不能访问,如果设置为"*",则所有的域名都能访问到此服务器;
     设置中间件:
     app.all('*', function(req, res, next) {
         res.header("Access-Control-Allow-Origin", "http://localhost:2871");
         res.header("Access-Control-Allow-Headers", "X-Requested-With");
         res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
         res.header("X-Powered-By",' 3.2.1');
         res.header("Content-Type", "application/json;charset=utf-8");
         next();
     })
    
    • 第二种:下载cors第三方模块,设置参数
      • 设置origin为特定的访问域名地址;
     //设置跨域请求代码
     const cors=require("cors");
     app.use(cors({
         origin:["http://localhost:2871"],
         methods:['GET','POST'],
         allowedHeaders:['Content-Type', 'Authorization']
     }));
    
  • fetch方法请求
    • method: get post
    • get方法:参数通过问号拼接在url后面,data设置为null;
    • post方法:参数通过data传入,为对象;
     //方法使用:如果为get请求,请求的参数通过问号拼接到url后面,data设置为null;
     function _request(_method,_url,_data,_success,_error) {
         let options={
             method:_method,
             body:(_method==="get")? null:JSON.stringify(_data),
             headers:{
                 'Content-Type': 'application/json'
             },
         };
         fetch(_url,options)
             .then(checkStatues)
             .then(res => res.json())
             .then(res => _success(res))
             .catch(error => _error(error));
     }
     //状态码判断
     function checkStatues(response) {
         if(response.ok){
             return response;
         }else{
             let error=new Error(response.statusText);
             error.status=response.status;
             error.response=response;
             throw error;
         }
     }
    
  • localStorage的设置
    • 设置本地存储:localStorage.setItem('myCat', 'Tom');
    • 获取本地存储:let cat = localStorage.getItem('myCat');
    • 删除本地存储:localStorage.removeItem('myCat');
    • 移除所有的本地存储:localStorage.clear();
    • 用途:可以用于判断是否已经登录的判断条件;当登录后,设置localStorage,退出登录,清除本地存储,通过本地存储是否存在,作为页码显示的判断条件,与cookie和session作用相同;
  • 设置一个div模块相对于父级元素水平垂直居中
    • 父级元素:设置绝对定位;
    • 子级元素:
      • 设置相对定位,其中方位top,bottom,left,right均设置为0;
      • 设置margin为auto;此时实现水平垂直居中;
      • 分析:由于块状元素默认水平方向上占满所有位置,设置auto就会使左右填满,达到居中的效果,而垂直方向上,块状元素是不会默认占满所有位置的,所以需要利用定位的top,bottom来拉开位置,此时就占据所有位置,使用auto就会上下居中;
  • 自动打开网页地址插件:"open-browser-webpack-plugin"
    • 下载模块:open-browser-webpack-plugin;
    • webpack.config.js配置:
     plugins:[
         new OpenBrowserPlugin({ url:"http://localhost:2871/login"})
     ]
    
  • webpack.config.js中设置favicon图标
    • 代码:
     plugins:[
         new HtmlWebpackPlugin({
             template:path.resolve(__dirname,"src/www/index.html"),
             favicon:path.resolve(__dirname,"src/www/img/piao.jpg")
         }),
     ]
    
  • 对象的深度克隆:JSON方法
    • 代码:JSON.parse(JSON.stringify(obj));
    • 含义:将对象obj转化为字符串,基本数据类型,然后再转化为对象,引用数据类型;就实现了深度克隆;
  • 对象的深度克隆:assign方法
    • 将两个对象整合到一个新的对象中;
    • 代码:
     var obj={
          a:1,
          b:2
       }
     var newobj=Object.assign({},obj,{a:3});//将后面的两个对象整合到空对象中;
    

代码:

  • package.json代码:
 {
   "name": "day5",
   "version": "1.0.0",
   "description": "",
   "main": "index.js",
   "scripts": {
     "test": "echo \"Error: no test specified\" && exit 1",
     "start": "webpack-dev-server --progress --colors --content-base dist --history-api-fallback",
     "build": "webpack --progress --colors"
   },
   "keywords": [],
   "author": "guomushan",
   "license": "ISC",
   "devDependencies": {
     "babel-cli": "^6.26.0",
     "babel-core": "^6.26.3",
     "babel-loader": "^7.1.5",
     "babel-preset-es2015": "^6.24.1",
     "babel-preset-react": "^6.24.1",
     "babel-preset-stage-0": "^6.24.1",
     "body-parser": "^1.18.3",
     "bootstrap": "^3.4.0",
     "classnames": "^2.2.6",
     "cors": "^2.8.5",
     "css-loader": "^2.1.0",
     "express": "^4.16.4",
     "extract-text-webpack-plugin": "^4.0.0-beta.0",
     "fg-loadcss": "^2.1.0",
     "file-loader": "^3.0.1",
     "html-webpack-plugin": "^3.2.0",
     "jQuery": "^1.7.4",
     "less": "^3.9.0",
     "less-loader": "^4.1.0",
     "md5": "^2.2.1",
     "mongoose": "^5.4.4",
     "open-browser-webpack-plugin": "0.0.5",
     "prop-types": "^15.6.2",
     "style-loader": "^0.23.1",
     "url-loader": "^1.1.2",
     "webpack": "^4.28.4",
     "webpack-cli": "^3.2.1",
     "webpack-dev-server": "^3.1.14"
   },
   "dependencies": {
     "@material-ui/core": "^3.8.3",
     "@material-ui/icons": "^3.0.2",
     "react": "^16.7.0",
     "react-dom": "^16.7.0",
     "react-router": "^3.0.5",
     "react-tap-event-plugin": "^3.0.3"
   }
 }

  • webpack.config.js代码:
 const webpack=require("webpack");
 const path=require("path");
 const HtmlWebpackPlugin=require("html-webpack-plugin");
 const ExtractTextPlugin=require("extract-text-webpack-plugin");
 const OpenBrowserPlugin=require("open-browser-webpack-plugin");
 
 
 module.exports={
     entry:path.resolve(__dirname,"src/app/app.js"),
     output:{
         filename:"my-bundle.js",
         path:path.resolve(__dirname,"dist")
     },
     module:{
         rules:[
             {
                 test:/\.js(x)?$/,
                 use:"babel-loader",
                 exclude:/node_modules/
             },
             {
                 test:/\.css$/,
                 use:ExtractTextPlugin.extract({
                     fallback:"style-loader",
                     use:"css-loader"
                 })
             },
             {
                 test:/\.(eot|svg|ttf|woff)(\?\w*)?$/,
                 use:"url-loader"
             },
             {
                 test:/\.(png|git|jpg|jepg)$/,
                 use:"url-loader"
             },
         ]
     },
     devServer:{
         port:"2871",
         host:"0.0.0.0",
         disableHostCheck: true
     },
     plugins:[
         new HtmlWebpackPlugin({
             template:path.resolve(__dirname,"src/www/index.html"),
             favicon:path.resolve(__dirname,"src/www/img/piao.jpg")
         }),
         new ExtractTextPlugin({
             filename:"style.css"
         }),
         new OpenBrowserPlugin({ url:"http://localhost:2871/login"})
     ],
     mode:"development"
 };
  • dataFetch.js代码:
 //方法使用:如果为get请求,请求的参数通过问号拼接到url后面,data设置为null;
 function _request(_method,_url,_data,_success,_error) {
     let options={
         method:_method,
         body:(_method==="get")? null:JSON.stringify(_data),
         headers:{
             'Content-Type': 'application/json'
         },
     };
     fetch(_url,options)
         .then(checkStatues)
         .then(res => res.json())
         .then(res => _success(res))
         .catch(error => _error(error));
 }
 //状态码判断
 function checkStatues(response) {
     if(response.ok){
         return response;
     }else{
         let error=new Error(response.statusText);
         error.status=response.status;
         error.response=response;
         throw error;
     }
 }
 //远程服务器,用于跨域获取数据
 let remoteApi="http://localhost:4100";
 //本地服务器,用于存储项目数据
 let localApi="http://localhost:2100";
 
 
 let videoModel={
     //1.跨域获取服务器中的数据:get=>"/getvideo"
     getVideoData:(_val,_success,_error)=>{
         _request("get",`${remoteApi}/getvideo?title=${_val}`,null,_success,_error);
     },
     //2.跨域将数据存储到本地服务器上: post=>"/addvideo"
     addVideoData:(data,_success,_error)=>{
         _request("post",`${localApi}/addvideo`,data,_success,_error);
     },
     //3.跨域获取本地服务器中的所有数据 get=> "/alldata"
     getAllData:(_success,_error)=>{
         _request("get",`${localApi}/getvideo`,null,_success,_error);
     },
     //4. 跨域获取详情页数据
     getDetailData:(_id,_success,_error)=>{
         _request("get",`${localApi}/getvideo?id=${_id}`,null,_success,_error);
     },
     //5. 修改详情页中的数据
     updateDetail:(data,_success,_error)=>{
         _request("post",`${localApi}/updatedata`,data,_success,_error);
     },
     //6. 删除数据
     deleteDetail:(data,_success,_error)=>{
         _request("post",`${localApi}/deletedata`,data,_success,_error);
     },
     //7. 登录数据提交
     loginData:(data,_success,_error)=>{
         _request("post",`${localApi}/logindata`,data,_success,_error);
     }
 };
 
 module.exports={
     videoModel,
 };
  • app.js代码:
 import React,{Component} from "react";
 import {render} from "react-dom";
 
 import Config from "./routerConfig/router";
 
 let root=document.getElementById("app");
 render(,root);
  • router.js代码:
 import {Router,Route,IndexRoute,browserHistory} from "react-router";
 import React from "react";
 
 import Login from "../component/login/login";
 import Logout from "../component/login/logout";
 import Add from "../component/add/add";
 import Video from "../component/video/video";
 import Videodetail from "../component/video/videodetail";
 import Main from "../component/main";
 
 class Config extends React.Component{
     render(){
         return(
             
                 
                 
                     
                     
                     
                     
                     
                 
             
         )
     }
 }
 export default Config;
  • 本地服务器myServer.js代码:
 //服务器与本地服务器进行连接,用于存储数据
 //创建express服务器,三步走
 const express=require("express");
 const app=express();
 app.listen(2100,function(){
     console.log("2100 is Listening");
 });
 
 //引入mongoose模块,用于与本地数据库连接
 const db=require("../public/db");
 //引入body-parser获取post请求的数据
 const bodyParser=require("body-parser");
 //设置body-parser的中间件
 // 1) parse application/x-www-form-urlencoded
 app.use(bodyParser.urlencoded({ extended: false }));
 // 2) parse application/json
 app.use(bodyParser.json());
 
 //设置跨域请求代码
 const cors=require("cors");
 app.use(cors({
     origin:["http://localhost:2871"],
     methods:['GET','POST'],
     allowedHeaders:['Content-Type', 'Authorization']
 }));
 
 //路由设置
 //1.post=>"/addvideo" 提交数据到本地数据库
 app.post("/addvideo",function (req, res) {
     var json=req.body;
     db.insertMany(json,function (err, result) {
         if(err){
             res.send({ok:false,dist:err});
             return;
         }
         res.send({ok:true,dist:"提交成功"});
     });
 });
 
 //2.获取数据
 app.get("/getvideo",function (req, res) {
     var json=req.query;
     db.find(json,function (err, result) {
         if(err){
             res.send({ok:false,dist:err});
             return;
         }
         res.send({ok:true,dist:result});
     })
 });
 //3.修改数据
 app.post("/updatedata",function (req, res) {
     var json=req.body;
     var {id}=json;
     db.updateOne({id},json,function (err, result) {
         if(err){
             res.send({ok:false,dist:"服务器错误"});
             return;
         }
         res.send({ok:true,dist:"修改成功"});
     })
 });
 //4.删除数据
 app.post("/deletedata",function (req, res) {
     var json=req.body;
     db.deleteOne(json,function (err, result) {
         if(err){
             res.send({ok:false,dist:"服务器错误"});
             return;
         }
         res.send({ok:true,dist:"删除成功"});
     })
 });
 //5. 获取登录的数据
 app.post("/logindata",function (req, res) {
     var json=req.body;
     if(json.name==="admin" && json.pass==="670da91be64127c92faac35c8300e814"){
         res.send({ok:true,dist:"登录成功"});
     }else{
         res.send({ok:false,dist:"登录失败,用户名或密码错误"});
     }
 });
 
  • 远程服务器代码:
 const express=require("express");
 const app=express();
 //引入body-parser来接收post请求提交的参数数据
 const bodyParser=require("body-parser");
 //引入mongoose方法
 const db=require("./db");
 //利用cors插件进行跨域设置
 const cors=require("cors");
 
 //通过cors设置特定的域名访问服务器
 app.use(cors({
     origin:["http://localhost:2871"],
     methods:['GET','POST'],
     allowedHeaders:['Content-Type', 'Authorization']
 }));
 
 //跨域请求设置中间件
 /*app.all('*', function(req, res, next) {
     res.header("Access-Control-Allow-Origin", "http://localhost:63342");
     res.header("Access-Control-Allow-Headers", "X-Requested-With");
     res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
     res.header("X-Powered-By",' 3.2.1');
     res.header("Content-Type", "application/json;charset=utf-8");
     next();
 });*/
 //设置bodyParser中间件
 // parse application/x-www-form-urlencoded
 app.use(bodyParser.urlencoded({ extended: false }));
 // parse application/json
 app.use(bodyParser.json());
 
 //1.get =>"/getvideo" 获取指定参数的数据
 app.get("/getvideo",function (req, res) {
     var json=req.query;
     //根据json获取指定数据
     db.find(json,function (err, result) {
         if(err){
             res.send({ok:false,dist:"获取数据失败"});
             return;
         }
         res.send({ok:true,dist:result});
     })
 });
 
 
 //监听端口号4100
 app.listen(4100,function () {
     console.log("4100 is Listening")
 });
  • main.js代码:
 import React from "react";
 import {Link,IndexLink} from "react-router";
 
 
 import PropTypes from 'prop-types';
 import { withStyles } from '@material-ui/core/styles';
 import AppBar from '@material-ui/core/AppBar';
 import Toolbar from '@material-ui/core/Toolbar';
 import Typography from '@material-ui/core/Typography';
 import Button from '@material-ui/core/Button';
 import IconButton from '@material-ui/core/IconButton';
 import MenuIcon from '@material-ui/icons/Menu';
 import MenuItem from '@material-ui/core/MenuItem';
 import MenuList from '@material-ui/core/MenuList';
 import Paper from '@material-ui/core/Paper';
 import Divider from '@material-ui/core/Divider';
 
 import "./main.css";
 const styles =theme=>({
     root: {
         flexGrow: 1,
         height:"100%"
     },
     grow: {
         flexGrow: 1,
     },
     menuButton: {
         marginLeft: -12,
         marginRight: 20,
     },
     navPaper: {
         margin:2,
         height:"100%"
     },
     mainPaper: {
         margin:2,
         height:"100%"
     },
     divider:{
         height:1,
         backgroundColor:"blue"
     }
 });
 class Main extends React.Component{
     render() {
         const { classes } = this.props;
         return (
             
果木山
{this.props.children}
); } } Main.propTypes = { classes: PropTypes.object.isRequired, }; export default withStyles(styles)(Main);
  • add.js代码:
 import React from "react";
 import PropTypes from 'prop-types';
 import { withStyles } from '@material-ui/core/styles';
 import TextField from '@material-ui/core/TextField';
 import Button from '@material-ui/core/Button';
 import Card from '@material-ui/core/Card';
 import CardActionArea from '@material-ui/core/CardActionArea';
 import CardActions from '@material-ui/core/CardActions';
 import CardContent from '@material-ui/core/CardContent';
 import CardMedia from '@material-ui/core/CardMedia';
 import Typography from '@material-ui/core/Typography';
 
 //引入fetch方法
 import {videoModel} from "../../dataFetch";
 
 
 
 const styles = theme => ({
     addcon:{
         height: "520px"
     },
     container: {
         marginBottom:20
     },
     textField: {
         marginLeft: theme.spacing.unit,
         marginRight: theme.spacing.unit,
         width: 200,
         color:"red"
     },
     button: {
         width: 100,
         margin: theme.spacing.unit,
         marginTop:28,
         color:"blue",
         fontWeight:900,
         lineHeight: "24px",
         backgroundColor:"lightsalmon"
     },
     input: {
         display: 'none',
     },
     card: {
         maxWidth: 345,
     },
     media: {
         height: 140,
     },
     cardbtn:{
         marginLeft:250,
         color:"red",
         border:"1px solid blue"
     }
 });
 
 class Add extends React.Component{
     constructor(){
         super();
         this.state={
             msg1:"",
             ary:[],
         }
     }
     //回车键搜索
     onEnter=(e)=>{
         if(e.keyCode===13){
             e.preventDefault();
             this.getData();
         }
     };
     //通过onChange事件,拿到事件源,实时获取文本框中的内容
     onChange=(e)=>{
         this.setState({
             msg1:e.target.value
         });
     };
     //搜索,获取数据
     doSearch=()=>{
         this.getData();
     };
     //fetch方法发送请求,获取数据
     getData=()=>{
         //参数为this.state.msg
         videoModel.getVideoData(this.state.msg1,(res)=> {
             //保证this指向
             this.setState({
                 ary:res.dist
             });
         },function (err) {
             console.log(err)
         })
     };
     //添加到本地数据库数据
     addlocalData=()=>{
         let {id,msg,imgsrc,title}=this.state.ary[0];
         videoModel.addVideoData({id,msg,imgsrc,title},function (res) {
             if(res.ok){
                 alert(res.dist);
             }else{
                 alert(res.dist);
             }
         },function (err) {
             console.log(err);//通过fetch方法发送请求时的错误;
         })
     };
     cardOn=()=>{
         //判断state中ary的长度是否不为0,若不为0,则代表有数据,然后渲染页面
         if(this.state.ary.length>0){
             const { classes } = this.props;
             const {id,imgsrc,title,msg}=this.state.ary[0];
             return (
                 
                     
                         
                         
                             
                                 {title}
                             
                             
                                 {msg}
                             
                         
                     
                     
                         
                     
                 
             )
         }else{
             return(
) } }; render(){ //判断是否已经登录 let loginState= localStorage.getItem("loginstate"); if(!loginState){ alert("请先登录"); location.href="/login"; return (
); } const { classes } = this.props; return(
{this.cardOn()}
) } } Add.propTypes = { classes: PropTypes.object.isRequired, }; export default withStyles(styles)(Add);
  • login.js代码:
 import React from "react";
 import PropTypes from 'prop-types';
 import { withStyles } from '@material-ui/core/styles';
 import TextField from '@material-ui/core/TextField';
 import Button from '@material-ui/core/Button';
 import md5 from "md5/md5";
 
 import "./login.css";
 import {videoModel} from "../../dataFetch";
 
 const styles = theme => ({
     container: {
         display: 'flex',
         flexWrap: 'wrap',
     },
     textField: {
         width: 200,
         margin:"20px auto",
         display:"block",
     },
     con:{
         width: "100%",
     },
     button: {
         margin:"50px auto"
     },
 });
 
 
 class Login extends React.Component{
     constructor(){
         super();
         this.state={
             admin:"111",
             pass:"111",
         }
     }
     componentDidMount(){
         let loginState= localStorage.getItem("loginstate");
         if(loginState){
             location.href="/";
             alert("已经登录");
         }
     }
     changeAdmin=(e)=>{
         this.setState({
             admin:e.target.value,
         })
     };
     changePass=(e)=>{
         this.setState({
             pass:e.target.value,
         })
     };
     postLogindata=()=>{
         var data={
             name:this.state.admin,
             pass:md5(this.state.pass),
         };
         videoModel.loginData(data,function (res) {
             if(res.ok){
                 alert(res.dist);
                 localStorage.setItem("loginstate",true);
                 window.location.href="/video";
             }else{
                 alert(res.dist);
             }
         },function (err) {
             console.log(err);
         })
     };
     render(){
         const { classes } = this.props;
         return(
             

share管理系统

) } } Login.propTypes = { classes: PropTypes.object.isRequired, }; export default withStyles(styles)(Login);
  • logout.js代码:
 import React from "react";
 
 class Logout extends React.Component{
     componentDidMount(){
         if(confirm("确定要退出么?")){
             localStorage.removeItem("loginstate");
             location.href="/login";
         }else{
             location.href="/video";
         }
     }
     render(){
         return(
             
) } } export default Logout;
  • video.js代码:
 import React from "react";
 import {Link} from "react-router";
 
 import PropTypes from 'prop-types';
 import { withStyles } from '@material-ui/core/styles';
 import Card from '@material-ui/core/Card';
 import CardActionArea from '@material-ui/core/CardActionArea';
 import CardActions from '@material-ui/core/CardActions';
 import CardContent from '@material-ui/core/CardContent';
 import CardMedia from '@material-ui/core/CardMedia';
 import Button from '@material-ui/core/Button';
 import Typography from '@material-ui/core/Typography';
 
 //引入fetch方法,发送请求,获取数据
 import {videoModel} from "../../dataFetch";
 //样式
 const styles = () => (
     {
         head:{
             fontSize:30,
             fontWeight:"bold",
             color:"blue",
             margin:"20px",
         },
         cont:{
             padding:"20px",
             paddingTop: 0
         },
         card: {
             display:"inline-block",
             width:326,
             marginRight:30,
             marginTop:30,
         },
         media: {
             height: 140,
         },
         cardbtn:{
             marginLeft:250,
             color:"red",
             border:"1px solid blue",
             padding:0,
         },
         link:{
             display:"block",
             width: "100%",
             padding:"4px 8px",
             color: "red",
         },
         omsg:{
             lineHeight:"30px",
             height:30,
             overflow: "hidden",
             textOverflow:"ellipsis",
             whiteSpace: "nowrap"
         }
     }
 );
 
 class Video extends React.Component{
     constructor(){
         super();
         this.state={
             allData:[]
         }
     }
     componentDidMount(){
         let loginState= localStorage.getItem("loginstate");
         if(!loginState){
             alert("请先登录");
             location.href="/login";
             return;
         }
         this.getAllData();
     }
     //获取所有数据
     getAllData=()=>{
         videoModel.getAllData((res)=> {
             if(res.ok){
                 this.setState({
                     allData:res.dist
                 })
             }else{
                 console.log(res.dist)
             }
         },function (err) {
             console.log(err);
         })
 
     };
     //视频元素
     renderHtml=()=>{
         var ary=this.state.allData;
         const { classes } = this.props;
         if(ary.length >0){
             var aryList=[];
             aryList=ary.map(function (item,index) {
                 let {id,msg,imgsrc,title}=item;
                 return (
                     
                         
                             
                             
                                 
                                     {title}
                                 
                                 
                                     {msg}
                                 
                             
                         
                         
                             
                         
                     
                 )
             });
             return aryList;
         }else{
             return (
                 
) } }; render(){ const { classes } = this.props; return(

视频列表

{this.renderHtml()}
) } } Video.propTypes = { classes: PropTypes.object.isRequired, }; export default withStyles(styles)(Video);
  • videodetail.js代码:
 import React from "react";
 
 import PropTypes from 'prop-types';
 import { withStyles } from '@material-ui/core/styles';
 import TextField from '@material-ui/core/TextField';
 import Button from '@material-ui/core/Button';
 import Divider from '@material-ui/core/Divider';
 
 import {videoModel} from "../../dataFetch";
 import "./detail.css";
 const styles = theme => ({
     container: {
         display:"block",
         float:"left",
         width:300,
         margin:20,
     },
     oImg:{
         width:300,
         float:"left",
         padding:"50px 0"
     },
     button: {
         marginLeft:20,
     },
     input: {
         display: 'none',
     },
 });
 
 class Videodetail extends React.Component{
     constructor(){
         super();
         this.state={
             video_title:" ",
             video_msg:" ",
             detailObj:null,
         }
     }
     componentDidMount(){
         this.getDetailData();
     }
     getDetailData(){
         //获取详情页的数据
         videoModel.getDetailData(this.props.params.id,(res)=> {
             const {id,imgsrc,msg,title}=res.dist[0];
             this.setState({
                 video_title:title,
                 video_msg:msg,
                 detailObj:{id,imgsrc,msg,title},//重新存一个对象堆地址
             })
         },function (err) {
             console.log(err)
         });
     }
     //修改title
     changeTitle=(e)=>{
         this.setState({
             video_title:e.target.value
         })
     };
     //修改msg
     changeMsg=(e)=>{
         this.setState({
             video_msg:e.target.value
         })
     };
     //修改按钮的disabled的设置
     checkHide(){
         if(this.state.detailObj.title===this.state.video_title && this.state.detailObj.msg===this.state.video_msg){
             return true;
         }else{
             return false;
         }
     }
     //修改数据
     updateData=()=>{
         var data=Object.assign({},this.state.detailObj,{title:this.state.video_title, msg:this.state.video_msg});
         videoModel.updateDetail(data,(res)=>{
             if(res.ok){
                 alert(res.dist);
                 //修改成功后,重新调用获取数据方法,是修改按钮变灰色
                 this.getDetailData();
             }else{
                 alert(res.dist);
             }
         },(err)=>{
             console.log(err)
         })
     };
     //删除数据
     deleteData=()=>{
         var id=this.state.detailObj.id;
         videoModel.deleteDetail({id},(res)=>{
             if(res.ok){
                 alert(res.dist);
                 //跳转页面
                 window.location.href="/video";
             }else{
                 alert(res.dist);
             }
         },(err)=>{
             console.log(err);
         })
     };
     render(){
         const { classes } = this.props;
         if(!this.state.detailObj){
             return 
} return(
图片
) } } Videodetail.propTypes = { classes: PropTypes.object.isRequired, }; export default withStyles(styles)(Videodetail);

你可能感兴趣的:(react学习第五天笔记之项目实战)