React复制组件的使用

import React, {
  Component
} from 'react';
import copy from 'copy-to-clipboard';

class App extends Component {

  handleClick = (e) => {
    copy(e.target.value)
  }

  render() {
    return (
      <div className="App">
        <p>
          <input placeholder='请输入' onClick={this.handleClick}/>          
        </p>
        <textarea></textarea>
      </div>
    );
  }
}

张宇童 发布于 2019-11-17 05:12

react配置proxy代理

首先我们需要安装http-proxy-middleware中间件

然后在src目录下创建setupProxy.js文件

里面填写代理规则即可

const proxy = require('http-proxy-middleware')
module.exports = function (app) {
    app.use(proxy('/api',{
        target: 'http://localhost:8083',
        changeOrigin: true,
        // pathRewrite: {
        //     "^/api": "/"
        // }
    }))
}
可以根据自己的需求更改

保存后此时并不能生效

要想生效必须重新启动npm


张宇童 发布于 2019-11-17 04:08

使用canvas画闪闪星光

突发奇想写了一写

效果图  点击查看效果

2019-11-16 14.15.05.gif

第一步创建html结构


<!DOCTYPE html>
<html>
<head>
    <title></title>
</head>
<body>
<div>
    <canvas id="canvas" height="600" width="800"></canvas>
    <script type="text/javascript" src="./js/main.js"></script>
    <script type="text/javascript" src="./js/star.js"></script>
</div>
</body>
</html>

第二部写js文件


main.js


let can;
let ctx;
let w;
let h;
let img = new Image();
let jpgimage = new Image();
let num = 5;
let starArr = []
document.body.onload = () => {
    can = document.getElementById('canvas')
    ctx = can.getContext('2d');
    w = can.width;
    h = can.height;
    jpgimage.src = 'src/IMG_2727 0.jpg'
    img.src = 'src/star.png'
    for (let i = 0 ; i < num; i++ ) {
        starArr.push(new StarObj)
        starArr[i].draw()
    }
    gameloop()
}

function drawBackground() {
    ctx.fillStyle = '#303550';
    ctx.fillRect(0,0, w, h)

    console.log('1')
}

function gameloop() {
    window.requestAnimFrame(gameloop)
    drawBackground();
    drawJpg()
    for (let i of starArr) {
        i.draw()
    }
}

window.requestAnimFrame = (function(){
    return window.requestAnimationFrame ||
        window.webkitRequestAnimationFrame ||
        window.mozRequestAnimationFrame ||
        window.oRequestAnimationFrame ||
        window.msRequestAnimationFrame ||
        function( callback ){
            window.setTimeout(callback, 1000 / 60);//定义每秒执行60次动画
        };
})();

const drawJpg = () => {
    // console.log(this)
    ctx.drawImage(jpgimage, 100, 100, 600, 350)
}

start.js



class StarObj{
    constructor() {
        this.x = Math.floor(Math.random() * can.width);
        this.y = Math.floor(Math.random() * can.height);
        this.lastTime = Date.now();
        this.timer = 0;
        this.n = Math.floor(Math.random() * 7);
    }
    update() {
        let space = Date.now() - this.lastTime;
        this.lastTime = Date.now();
        this.timer = space + this.timer;
        if (this.timer > 50) {
            this.n++;
            this.timer = 0;
            if (this.n > 7) {
                this.n = 0;
            }
        }
    }
    draw() {
        this.update()
        ctx.drawImage(img, this.n * 7, 0, 7, 7, this.x, this.y, 7, 7)
    }
}



张宇童 发布于 2019-11-16 06:12

兼容封装requestAnimFrame

没有啥好解释的直接复制用就可以了

window.requestAnimFrame = (function(){
    return window.requestAnimationFrame ||
        window.webkitRequestAnimationFrame ||
        window.mozRequestAnimationFrame ||
        window.oRequestAnimationFrame ||
        window.msRequestAnimationFrame ||
        function( callback ){
            window.setTimeout(callback, 1000 / 60);//定义每秒执行60次动画
        };
})();


张宇童 发布于 2019-11-16 04:27

关于inline-block的间隙问题

屏幕快照 2019-11-14 下午10.01.06.png

如图所示这样的遐思你受的了吗?


<!DOCTYPE html>
<html>
<head>
    <title></title>
    <style type="text/css">
        .container {
            width: 1000px;
            height: 400px;
            background: #ddd;
            /*font-size: 0px;*/
        }
        .left {
            width: 300px;
            height: 100px;
            background: #7ac;
            display: inline-block;
        }
        .right {
            width: 500px;
            height: 100px;
            background: #678;
            display: inline-block;
        }
    </style>
</head>
<body>
<div class="container">
    <div class="left"></div>
    <div class="right"></div>
</div>
</body>
</html>

为什么呢?

最终我们找到div和div之间有一个换行符

屏幕快照 2019-11-14 下午10.09.03.png

我们去掉试试

屏幕快照 2019-11-14 下午10.12.15.png

屏幕快照 2019-11-14 下午10.12.10.png

最后就好了。

当然我们也可以使用font-size:0来做。


张宇童 发布于 2019-11-14 14:00

float元素详解

很多同学可能对于float不太理解这里的float有几点特性

第一点是float脱离文档流 当不脱离文本流

这里说的是什么意思呢?

就是空间与文字的概念。

你可以理解成为一个float:left的元素它脱离了文档是指的在一个容器内不受容器内其他的块级元素影响。

而容器内容文本呢?则会绕开它。

第二点呢就是会尽量靠上

第三就是对于父级元素的影响,怎么理解呢?

就是一个容器我们没有给它设置高度。因为我们的设想是让内容撑开父级元素

而如果我们给内容元素设置了float则会导致父级元素高度塌陷


以下是一张动图。请点击后观看

2019-11-14 20.58.13.gif


<!DOCTYPE html>
<html>
<head>
    <title></title>
    <style type="text/css">
        .container {
            width: 800px;
            height: 300px;
            background: linear-gradient(0deg, red 0%, green 100%)
        }
        .p1 {
            width: 100px;
            height: 100px;
            background: #ddd;
            float:left;
        }
    </style>
</head>
<body>
    <div class="container">
        <span class="p1"></span>
    </div>
    <div class="container">
        <span>我是文字</span>
        <span class="p1">float1</span>
        <span class="p1">float2</span>

    </div>
</body>
</html>



下面大家来看一个float三栏布局

屏幕快照 2019-11-14 下午9.44.11.png

<!DOCTYPE html>
<html>
<head>
    <title>float三栏布局</title>
    <style type="text/css">
        .left {
            float: left;
            height: 200px;
            width: 200px;
            background: red;
        }
        .right {
            float: right;
            height: 200px;
            width: 200px;
            background: green;
        }
        .middle {
            height: 200px;
            background: blue;
            margin-left: 200px;
        }
    </style>
</head>
<body>
<div class="left"></div>
<div class="right"></div>
<div class="middle">经典三栏布局</div>
</body>
</html>


张宇童 发布于 2019-11-14 12:58

flex弹性盒子布局

flex是css专门为布局而诞生的一个属性

用法:

1、首先在外层元素定义一个display:flex

2、在内层元素使用flex: 1

是不是很简单呢?

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <style type="text/css">
        .container {
            display: flex;
            width: 800px;
            height: 300px;
            border: 1px dashed red;
            background:  linear-gradient(0deg, transparent 0, green 30%, red 60%, black 100%)
        }
        .flex {
            flex: 1;
            margin: 5px;
            background: #adc;
        }
        .flex2 {
            flex: 2;
            margin: 5px;
            background: #eee;
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="flex"></div>
        <div class="flex"></div>
        <div class="flex2"></div>
    </div>
</body>
</html>

效果图:

屏幕快照 2019-11-14 下午8.37.35.png

既然flex这么好用为什么没有大规模的使用呢?

原因是很多浏览器不兼容,并且期间有过几次的语法变动


张宇童 发布于 2019-11-14 12:35

Django去操作已经存在的数据库

Django去操作已经存在的数据库

你有没有遇到过这种情况?

数据库,各种表结构已经创建好了,甚至连数据都有了,此时,我要用Django管理这个数据库,ORM映射怎么办???

Django是最适合所谓的green-field开发,即从头开始一个新的项目

但是呢,Django也支持和以前遗留的数据库和应用相结合的。

Django的数据库层从Python代码生成SQL schemas。但是对于遗留的数据库,你已经用于SQL schemas,这种情况下你需要为你已经存在的数据库表写模型(为了使用数据库的API),幸运的是,Django自带有通过阅读你的数据库表规划来生成模型代码的辅助工具 manage.py inspectdb

 1.Django默认使用的是sqllit数据库?如何使用MySQL数据库?

#修改setting.py文件 
DATABASE = { 
    'default':{ 
        'ENGINE':'django.db.backends.mysql', 
        'NAME':'数据库名', 'HOST':'数据库地址', 
        'PORT':端口, 'USER':'用户名', 
        'PASSWORD':'密码', 
    }
 } 

#由于Django内部链接MySQL数据库的时候默认的是使用MySQLdb的 #但是Python3中没有这个模块 #所以我们要去修改他的project同名文件夹下的__init__文件 import pymysql
pymysql.install_as_MySQLdb()

 然后呢,我们就需要根据数据库去自动生成新的models文件

python manage.py inspectdb #简单可以看一下自动映射成的models中的内容

导出并且去代替models.py

python manage.py inspectdb > models.py

这样你就会发现在manage.py的同级目录下生成了一个models.py文件

使用这个models.py文件覆盖app中的models文件。

如果完成了以上的操作,生成的是一个不可修改/删除的models,修改meta class中的managed = True则可以去告诉django可以对数据库进行操作

1294578-20180703082631513-1019513692.png

此时,我们再去使models.py和数据库进行同步

python manage.py migrate

这个时候就已经大功告成了!

 然我们来验证一下:

python manage.py shell #一些查询语句

嗯.....没毛病。


张宇童 发布于 2019-11-14 07:26

Django 数据表资料

表结构

基本结构

models.AutoField  自增列 = int(11)
  如果没有的话,默认会生成一个名称为 id 的列,如果要显示的自定义一个自增列,必须将给列设置为主键     primary_key=True。
models.CharField  字符串字段
  必须 max_length 参数
models.BooleanField  布尔类型=tinyint(1)
  不能为空,Blank=True
models.ComaSeparatedIntegerField  用逗号分割的数字=varchar
  继承CharField,所以必须 max_lenght 参数
models.DateField  日期类型 date
  对于参数,auto_now = True 则每次更新都会更新这个时间;auto_now_add 则只是第一次创建添加,之后的更新不再改变。
models.DateTimeField  日期类型 datetime
  同DateField的参数
models.Decimal  十进制小数类型 = decimal
  必须指定整数位max_digits和小数位decimal_places
models.EmailField  字符串类型(正则表达式邮箱) =varchar
  对字符串进行正则表达式
models.FloatField  浮点类型 = double
models.IntegerField  整形
models.BigIntegerField  长整形
  integer_field_ranges = {
    'SmallIntegerField': (-32768, 32767),
    'IntegerField': (-2147483648, 2147483647),
    'BigIntegerField': (-9223372036854775808, 9223372036854775807),
    'PositiveSmallIntegerField': (0, 32767),
    'PositiveIntegerField': (0, 2147483647),
  }
models.IPAddressField  字符串类型(ip4正则表达式)
models.GenericIPAddressField  字符串类型(ip4和ip6是可选的)
  参数protocol可以是:both、ipvipv6
  验证时,会根据设置报错
models.NullBooleanField  允许为空的布尔类型
models.PositiveIntegerFiel  正Integer
models.PositiveSmallIntegerField  正smallInteger
models.SlugField  减号、下划线、字母、数字
models.SmallIntegerField  数字
  数据库中的字段有:tinyint、smallint、int、bigint
models.TextField  字符串=longtext
models.TimeField  时间 HH:MM[:ss[.uuuuuu]]
models.URLField  字符串,地址正则表达式
models.BinaryField  二进制
models.ImageField   图片
models.FilePathField 文件

数据字段

null=True
  数据库中字段是否可以为空
blank=True
  django的 Admin 中添加数据时是否可允许空值
primary_key = False
  主键,对AutoField设置主键后,就会代替原来的自增 id 列
auto_now 和 auto_now_add
  auto_now   自动创建---无论添加或修改,都是当前操作的时间
  auto_now_add  自动创建---永远是创建时的时间
choices
    GENDER_CHOICE = (
            (u'M', u'Male'),
            (u'F', u'Female'),
        )
        gender = models.CharField(max_length=2,choices = GENDER_CHOICE)
max_length
default  默认值
verbose_name  Admin中字段的显示名称
name|db_column  数据库中的字段名称
unique=True  不允许重复
db_index = True  数据库索引
editable=True  在Admin里是否可编辑
error_messages=None  错误提示
auto_created=False  自动创建
help_text  在Admin中提示帮助信息
validators=[]
upload-to

连表结构

  • 一对多:models.ForeignKey(其他表)
  • 多对多:models.ManyToManyField(其他表)
  • 一对一:models.OneToOneField(其他表)
应用场景:
    一对多:当一张表中创建一行数据时,有一个单选的下拉框(可以被重复选择)
    例如:创建用户信息时候,需要选择一个用户类型【普通用户】【金牌用户】【铂金用户】等。
    多对多:在某表中创建一行数据是,有一个可以多选的下拉框
    例如:创建用户信息,需要为用户指定多个爱好
    一对一:在某表中创建一行数据时,有一个单选的下拉框(下拉框中的内容被用过一次就消失了
    例如:原有含10列数据的一张表保存相关信息,经过一段时间之后,10列无法满足需求,需要为原来的表再添加5列数据

表操作

基本操作

    增
    models.Tb1.objects.create(c1='xx', c2='oo')  增加一条数据,可以接受字典类型数据 **kwargs
    obj = models.Tb1(c1='xx', c2='oo')
    obj.save()

    查

    models.Tb1.objects.get(id=123)         获取单条数据,不存在则报错(不建议)
    models.Tb1.objects.all()               获取全部
    models.Tb1.objects.filter(name='seven') 获取指定条件的数据

    删

    models.Tb1.objects.filter(name='seven').delete() 删除指定条件的数据

    改
    models.Tb1.objects.filter(name='seven').update(gender='0')  将指定条件的数据更新,均支持 **kwargs
    obj = models.Tb1.objects.get(id=1)
    obj.c1 = '111'
    obj.save()                                                 修改单条数据

        基本操作

进阶操作(了不起的双下划线)

利用双下划线将字段和对应的操作连接起来

        # 获取个数
    #
    # models.Tb1.objects.filter(name='seven').count()

    # 大于,小于
    #
    # models.Tb1.objects.filter(id__gt=1)              # 获取id大于1的值
    # models.Tb1.objects.filter(id__lt=10)             # 获取id小于10的值
    # models.Tb1.objects.filter(id__lt=10, id__gt=1)   # 获取id大于1 且 小于10的值

    # in
    #
    # models.Tb1.objects.filter(id__in=[11, 22, 33])   # 获取id等于33的数据
    # models.Tb1.objects.exclude(id__in=[11, 22, 33])  # not in

    # contains
    #
    # models.Tb1.objects.filter(name__contains="ven")
    # models.Tb1.objects.filter(name__icontains="ven") # icontains大小写不敏感
    # models.Tb1.objects.exclude(name__icontains="ven")

    # range
    #
    # models.Tb1.objects.filter(id__range=[1, 2])   # 范围bettwen and

    # 其他类似
    #
    # startswith,istartswith, endswith, iendswith,

    # order by
    #
    # models.Tb1.objects.filter(name='seven').order_by('id')    # asc
    # models.Tb1.objects.filter(name='seven').order_by('-id')   # desc

    # limit 、offset
    #
    # models.Tb1.objects.all()[10:20]

    # group by
    from django.db.models import Count, Min, Max, Sum
    # models.Tb1.objects.filter(c1=1).values('id').annotate(c=Count('num'))
    # SELECT "app01_tb1"."id", COUNT("app01_tb1"."num") AS "c" FROM "app01_tb1" WHERE "app01_tb1"."c1" = 1 GROUP BY "app01_tb1"."id"

连表操作

表结构实训

class UserProfile(models.Model):
    user_info = models.OneToOneField('UserInfo')
    username = models.CharField(max_length=64)
    password = models.CharField(max_length=64)

    def __unicode__(self):
        return self.username

class UserInfo(models.Model):
    user_type_choice = (
        (0, u'普通用户'),
        (1, u'高级用户'),
    )
    user_type = models.IntegerField(choices=user_type_choice)
    name = models.CharField(max_length=32)
    email = models.CharField(max_length=32)
    address = models.CharField(max_length=128)

    def __unicode__(self):
        return self.name

class UserGroup(models.Model):

    caption = models.CharField(max_length=64)

    user_info = models.ManyToManyField('UserInfo')

    def __unicode__(self):
        return self.caption

class Host(models.Model):
    hostname = models.CharField(max_length=64)
    ip = models.GenericIPAddressField()
    user_group = models.ForeignKey('UserGroup')

    def __unicode__(self):
        return self.hostname

一对一操作

user_info_obj = models.UserInfo.objects.filter(id=1).first()
print user_info_obj.user_type
print user_info_obj.get_user_type_display()
print user_info_obj.userprofile.password

user_info_obj = models.UserInfo.objects.filter(id=1).values('email', 'userprofile__username').first()
print user_info_obj.keys()
print user_info_obj.values()

一对多操作

类似一对一
搜索条件使用 __ 连接
获取值时使用 .    连接

多对多

user_info_obj = models.UserInfo.objects.get(name=u'Tyler')
user_info_objs = models.UserInfo.objects.all()

group_obj = models.UserGroup.objects.get(caption='CEO')
group_objs = models.UserGroup.objects.all()
 
# 添加数据
#group_obj.user_info.add(user_info_obj)
#group_obj.user_info.add(*user_info_objs)
 
# 删除数据
#group_obj.user_info.remove(user_info_obj)
#group_obj.user_info.remove(*user_info_objs)
 
# 添加数据
#user_info_obj.usergroup_set.add(group_obj)
#user_info_obj.usergroup_set.add(*group_objs)
 
# 删除数据
#user_info_obj.usergroup_set.remove(group_obj)
#user_info_obj.usergroup_set.remove(*group_objs)
 
# 获取数据
#print group_obj.user_info.all()
#print group_obj.user_info.all().filter(id=1)
 
# 获取数据
#print user_info_obj.usergroup_set.all()
#print user_info_obj.usergroup_set.all().filter(caption='CEO')
#print user_info_obj.usergroup_set.all().filter(caption='DBA')

其他操作

# F 使用查询条件的值
    #
    # from django.db.models import F
    # models.Tb1.objects.update(num=F('num')+1)

    # Q 构建搜索条件
    from django.db.models import Q
    # con = Q()
    #
    # q1 = Q()
    # q1.connector = 'OR'
    # q1.children.append(('id', 1))
    # q1.children.append(('id', 10))
    # q1.children.append(('id', 9))
    #
    # q2 = Q()
    # q2.connector = 'OR'
    # q2.children.append(('c1', 1))
    # q2.children.append(('c1', 10))
    # q2.children.append(('c1', 9))
    #
    # con.add(q1, 'AND')
    # con.add(q2, 'AND')
    #
    # models.Tb1.objects.filter(con)

    #
    # from django.db import connection
    # cursor = connection.cursor()
    # cursor.execute("""SELECT * from tb where name = %s""", ['Lennon'])
    # row = cursor.fetchone()

张宇童 发布于 2019-11-14 07:01

Django配置数据库很重要的一个步骤

from pymysql import install_as_MySQLdb

install_as_MySQLdb()

张宇童 发布于 2019-11-14 05:25

个人资料

    扫一扫体验小程序版博客哦

    个人简介: 吃饭睡觉😴,打豆豆

最新评论


搜索