学习笔记
2020-12-02 学习笔记
var和let的区别
var是全局变量;
可以重复声明;
有变量提升默认值为undefined;
不存在暂时性死区;
{
var i=9
}
console.log(i) // 9
let是块级变量;
不可以重复声明,会报错;
没有变量提升,会报错;
存在暂时性死区,即声明变量时,区块中对这些声明变量形成封闭作用域,凡是在声明之前使用变量就会报错;
{
let i=9
}
console.log(i) //Uncaught ReferenceError: i is not defined
分析代码执行结果
var a=123;
if(true){
a='zsh';
let a;
}
会报错,a变量声明两次,在let声明后在循环内形成暂时性死区,即在声明之前使用变量a会报错
补全代码
var person={
name:'zs',
age:12
}
let str=` `;
结果呈现:用户的姓名为 ,年龄是
result.innerHTML=str;
补充代码为
let str=`用户的姓名为${person.name},年龄是${person.age}`
将下面字符串改用模板字符串实现
$("#result").append(
"He is <b>"+person.name+"</b>"+"and we wish to
know his"+person.age+".That is all" )
答:
$("#result").append(`
He is <b>${person.name}</b>and we wish to know
his ${person.age}.That is all
`)
下面程序输出的结果是
let object = { first: 'Bill', lasts: 'Gates' };
let { first: firstName, last: lastName } = object;
console.log(firstName+'\t'+lastName);
Bill undefined
key值发生了改变object中的key值为lasts下面的key值变成了last 所以解构得到的不是Gates,而是undefined
下列程序执行f()函数运行的结果是
var tmp = new Date();
function f(){
console.log(tmp);
if (false){
var tmp = "hello world";
}
}
f()
undefined
函数内部变量tmp声明覆盖了外层tmp声明,内部变量输出在声明之前,所以输出默认值undefined
对比以下两道程序输出的值相同吗
//A程序:
var a = [];
for (let i = 0; i < 10; i++) {
a[i] = function () {
console.log(i);
};
}
a[8]();
a[9]();
//B程序
var a = [];
for (var i = 0; i < 10; i++) {
a[i] = function () {
console.log(i);
};
}
a[8]();
a[9]();
不同
A程序i为块级变量当调用函数并赋值的时候根据当前下标值进行输出
B程序i为全局变量无论当前下标值为何值,输出值均是i的跳出循环的值
A:// 8 9
B:// 10 10
2020-12-05 学习笔记
下面程序的执行结果是什么?请分析原因?
function f({ x = 10 } = {}, { y } = { y: 10 }) {
console.log( x + " " + y +"\n");
}
结果:
f(); // 10 10
f( undefined, undefined ); // 10 10
f( {}, undefined ); // 10 10
f( {}, {} ); // 10 undefined
f( undefined, {} ); // 10 undefined
f( { x: 2 }, { y: 3 } ); // 2 3
原因:f()运用了es6的解构语法
形参x声明并且赋值,所以无论实参的值为null还是undefined,x均为10,若实参赋值为2,那么x赋值为2。
形参y声明未赋值,所以实参的值undefined,y为10,实参为null,y为默认值undefined,若实参赋值为3,那么y赋值也为3,
Array.from方法的作用是什么
Array.from 是为了将类数组和对象转化为数组
Array.of和使用Array()或new Array()构建数组实例有什么区别
Array.of() 相当于扩展了 new Array();
例如:创建长度为 1 的数组,值为 10
var arr=Array.of(10);
下面程序执行结果是什么?
function push(array, ...items) {
items.forEach(function(item) {
array.push(item);
console.log(item);
});
}
var a = [1,2];
push(a, 1, 2, 3)
//1 2 3
items内包含1,2,3依次压入数组a每压入一个值就打印一个值
下面程序执行结果是什么?
const headAndTail = (head, ...tail) => [head, tail];
headAndTail(6, 2, 3, 4, 5)
[6,[2,3,4,5]]
…tail将head变量对应的6之后的参数形成一个数组
node是什么?
Node.js 就是运行在服务端的 JavaScript。
Node.js 是一个基于Chrome JavaScript 运行时建立的一个平台。
Node.js是一个事件驱动I/O服务端JavaScript环境,基于Google的V8引擎,V8引擎执行Javascript的速度非常快,性能非常好。
2020-12-07 学习笔记
编写程序使用ES6定义 Person类,包括类实例属性(name,age),实例方法say()该方法
返回name和age字符串
答:
class Person{
constructor(name,age){
this.name=name;
this.age=age;
this.say=function(){
return [name,age];
}
}
}
var p=new Person('jack',12)
p.say()
下面程序执行结果为:
var p=new Person();
console.log(p.__proto__===Person.prototype)
答:true 二者在同一条原型链上
下面程序正确吗?错在哪里?如何改正?
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
}
class ColorPoint extends Point {
constructor(x, y, color) {
this.color = color; // ReferenceError
super(x, y);
}
}
var cp=new ColorPoint(10,20,'red');
答:
将super(x, y); 和 this.color = color; 互换位置,this要写在super()后面
下面程序执行结果为?
class Parent {
static myMethod(msg) {
console.log('static', msg);
}
myMethod(msg) {
console.log('instance', msg);
}
}
class Child extends Parent {
static myMethod(msg) {
super.myMethod(msg);
}
myMethod(msg) {
super.myMethod(msg);
}
}
Child.myMethod(1);
var child = new Child();
child.myMethod(2);
答:
// static 1
// instance 2
静态函数只能由构造函数自身调用,非静态函数可以使用实例对象调用
利用class重新定义Cat,并让它从已有的Animal继承,然后新增一个方法say(),返回字符串’Hello, xxx!’
class Animal {
constructor(name) {
this.name = name;
}
}
答:
class Cat extends Animal{
constructor(name){
super(name)
}
say(){
console.log('hello,xxx')
}
}
var c=new Cat('jack')
console.log(c.say())
接上面程序分析下面代码执行结果为
var kitty = new Cat('Kitty');
var doraemon = new Cat('哆啦A梦');
if ((new Cat('x') instanceof Animal) && kitty && kitty.name === 'Kitty' && kitty.say &&
typeof kitty.say === 'function' && kitty.say() === 'Hello,Kitty!' &&
kitty.say === doraemon.say) {
console.log('测试通过!');
} else {
console.log('测试失败!');
}
答:测试失败
下面程序执行结果为
(typeof (new (class { class () {} })));
答:new 方法构造的是一个类
2020-12-09 学习笔记
node是什么?
个人认为Node.js是一个服务端JavaScript运行平台
这是其他平台的定义,觉得很不错[转自菜鸟教程
Node.js 就是运行在服务端的 JavaScript。
Node.js 是一个基于Chrome JavaScript 运行时建立的一个平台。
Node.js是一个事件驱动I/O服务端JavaScript环境,基于Google的V8引擎,V8引擎执行Javascript的速度非常快,性能非常好。
Node.js和java/php的区别
转自菜鸟教程
PHP
- Rasmus Lerdorf在1994年创造出了PHP。它是由安装在web服务器(Apache、Ngix)上的组件运行的。PHP代码可以和HTML混合到一块。 对于初学者就能很快写出很有价值的代码,这并不需要太多的练习。 这让PHP变得越来越流行, 现在全球百分之八十的服务器上都在运行着PHP。全球四分之一的网站都在用的一个内容管理系统–WordPress,就是用PHP写的。
- PHP 有办法开发桌面应用和命令行工具,但是你不会使用他们。本质上,PHP 是一个服务端技术,他很擅长该领域,但是很少延伸到这之外。
- PHP 跟其他多数服务端语言采用阻塞执行的模型。 当你执行一个命令,比如从数据库取数据,那么必须等这个指令执行完成后,才会执行下面的内容。
Node.js
- Ryan Dahl在2009年创造了Node.js。它是基于Google的V8 JavaScript解释引擎(在Chrome浏览器里它负责执行客户端的JavaScript代码)。与其它语言不同的是Node.js内置了处理网络请求和响应的函数库,所以你不需要单独的服务器(Apache、Ngix)或者其他依赖。Node.js虽然很新但是很快就获得了极大的追捧。
- 若干年前,JavaScript 被认为限制很多,有一些边缘技术,但是他的主战场还是浏览器。Node.js 已经改变了这一感觉并井喷出了很多 JavaScript 项目,你可以在任何地方使用 JavaScript:浏览器,服务器,终端,桌面甚至嵌入式系统,这使得 JavaScript 无处不在。
- Node.js 通常不会等的。 取而代之的是, 你需要提供一个回调函数,这个函数当指令执行完后会被调用一次。
2020-12-14 学习笔记
简述前端模块化发展史
简单的js脚本引入=>更换为object封装=>闭包封装=>node和npm
node作为后端语言,没有模块化加载机制是运转不起来的,node 最先选择 commonJS 作为它的模块加载方案,因为COMMONJS用于是服务端的,不能直接用于浏览器,于是出现了适用于浏览器的AMD规范,CMD规范,AMD的存在的一些问题不被COMMONJS社区认同,最后独立运作,当然RequireJS也确实也大火了一段时间,后来CMD的产物seajs开发出来。到现在来看这两个产物估计是已经过时了,当然还有在用的,毕竟后来的webpack es6的发展势不可挡,webpakc对三种规范完全支持
实现模块化流程
- 创建项目文件夹 demoProject
md demoProject
- 初始化项目
npm init -y
- 下载
yarn add babel-cli -dev
yarn add babel-preset-es2015 -dev
新建 .babelrc 文件
{
"presets":["es2015"],
"plugins":[]
}
- 创建src文件夹书写es6语法文件
a.js
export export var a="这是a文件";
b.js
export var b="这是b文件";
main.js
import {a} from './a.js';
import {b} from './b.js';
console.log(a,b)
- 在项目文件夹下的 ./node_modules/.bin 文件夹执行
babel ../../src -d ../../dist
- 在项目文件夹下的dist文件夹下执行
node main.js
便可以实现在main.js文件中对于a.js和b.js文件夹模块的调用
2020-12-16 学习笔记
同步和异步区别?
同步:上一步执行完后下一步才能得到执行。
异步:将比较复杂的任务制作成任务线程,以任务线程实现,不用等上一句执行完,下一句也可以执行。
总而言之:同步就是程序自上而下运行,而异步就是不用等待上面的运行完后再运行下面的操作。异步编程依托于回调来实现,但不能说使用了回调后程序就异步化了。
判断文件夹下文件状态
fs.readdir(__dirname,(err,files)=>{
if(err) throw err;
console.log(files);
for(let i in files){
fs.stat(__dirname,(err,stats)=>{
if(stats.isFile()){
console.log(files[i]+"是文件");
return;
}
console.log(files[i]+"是目录")
})
}
})
实现静态资源读取
- 创建demo文件夹作为测试文件夹
- 在demo文件夹下,创建www文件夹存储静态文件夹,在静态文件夹内创建两个不同的项目文件夹
└─www ├─jd └─taobao ├─css ├─image └─js
- jd文件夹下存123.html文件
taobao文件夹下存储index.html - 在demo文件夹下,创建readFile.js文件作为静态文件读取主文件
const http=require('http');
const fs=require('fs');
const path=require('path');
const common=require('./common');//见下面common.js
http.createServer((req, res)=>{
//req.url 获取请求地址 /favicon.ico地址是自动请求的
if (req.url=='/favicon.ico')return;
//a.startsWith(b) 字符串以b开始的
if (req.url.startsWith('/taobao')) {
common.demo(req,res)
}else if (req.url.startsWith('/jd')){
console.log(req.url)
common.demo(req,res)
}
}).listen('8989');
console.log('http://127.0.0.1:8989/');
创建common模块文件执行www文件夹读取,common.js
const fs=require('fs');
const path=require('path');
module.exports.demo=function (req,res){
fs.readFile(path.join(__dirname,'www',req.url),(err,data)=>{
if(err)throw err;
res.writeHead(200,{'Content-type':'text/pkain;charset=utf-8'})
res.end(data)
});
}
在
http://127.0.0.1:8989/
后添加www文件夹下的分支文件夹内的文件即可得出相应文件夹内的静态文件。
例如:http://127.0.0.1:8989/taobao/index.html
2020-12-21 学习笔记
(简易)封装加减乘除模块
- 创建项目文件夹cul,并在项目文件夹下创建node_modules文件夹
- 在node_modules文件夹下创建模块文件夹calculation
- 在模块文件夹下创建index.js模块文件
module.exports=class calculation{ constructor(x,y){ this.x=x, this.y=y } add(x,y){ let sum=this.x+this.y; return sum } subtract(x,y){ let difference=this.x-this.y; return difference } multiply(x,y){ let product=this.x*this.y; return product } divide(x,y){ let merchant=this.x/this.y; return merchant } }
模拟进行模块引用,在项目文件夹下创建cul.js引用文件
const cul=require('calculation')
let v=new cul(3,4)
console.log(v.add())
console.log(v.subtract())
console.log(v.multiply())
console.log(v.divide())
并且在当前项目文件夹下运行cmd命令
node cul.js
便可以调用模块进行运算
get和post区别
转自 Laravel社区vinhson
对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);
而对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。
也就是说,GET只需要汽车跑一趟就把货送到了,而POST得跑两趟,第一趟,先去和服务器打个招呼“嗨,我等下要送一批货来,你们打开门迎接我”,然后再回头把货送过去。
因为POST需要两步,时间上消耗的要多一点,看起来GET比POST更有效。因此Yahoo团队有推荐用GET替换POST来优化网站性能。但这是一个坑!跳入需谨慎。为什么?
- GET与POST都有自己的语义,不能随便混用。
- 据研究,在网络环境好的情况下,发一次包的时间和发两次包的时间差别基本可以无视。而在网络环境差的情况下,两次包的TCP在验证数据包完整性上,有非常大的优点。
- 并不是所有浏览器都会在POST中发送两次包,Firefox就只发送一次。
node实现登录和注册
创建项目文件夹demo
在demo下,创建form表单文件夹,form文件夹下文件如下
├─css
└─index.css
├─image
├─js
├─index.html
├─get.html
└─post.html
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<title></title>
<meta charset="UTF-8">
<link rel="stylesheet" type="text/css" href="./css/index.css">
</head>
<body>
<a href="get.html">登录</a>
<a href="post.html">注册</a>
</body>
</html>
index.css
p{
background: red;
}
get.html
<!DOCTYPE html>
<html>
<head>
<title>登录</title>
<meta charset="UTF-8">
</head>
<body>
<p>登陆页面</p><a href="./index.html">返回主界面</a>
<form action="http://localhost:8989/submit" method="get">
<input type="text" name="username" placeholder="用户名"><br>
<input type="text" name="password" placeholder="密码"><br>
<input type="submit" value="登录">
</form>
</body>
</html>```
post.html
```html
<!DOCTYPE html>
<html>
<head>
<title>注册</title>
<meta charset="UTF-8">
</head>
<body>
<p>注册页面</p><a href="./index.html">返回主界面</a>
<form action="http://localhost:8989/submit" method="post">
<input type="text" name="user" placeholder="用户名"><br>
<input type="password" name="pass" placeholder="密码"><br>
<input type="submit" value="注册">
</form>
</body>
</html>
在项目文件夹下创建node_modules文件夹
并在该文件夹下创建readFile文件夹
在readFile文件夹下创建index.js文件读取模块文件
const fs=require('fs');
const path=require('path');
module.exports=function (p,req,res){
fs.readFile(path.join(p,req.url),(err,data)=>{
if(err)throw err;
res.end(data)
});
}
在项目文件夹下创建主文件main.js
const http=require('http');
const fs=require('fs');
const path=require('path');
const url=require('url');
const querystring=require('querystring')
//引入读文件的模块
const readfile=require('readFile');
http.createServer((req, res)=>{
if (req.url=='/favicon.ico')return;
if (req.url.startsWith('/form')) {
readfile(__dirname,req,res)
}else if(req.url.startsWith('/submit')){
if(req.url.startsWith('/submit?username')){
//get方法
res.writeHead(200,{'Content-type':'text/plain;charset=utf-8'})
let ps= url.parse(req.url,true).query;
console.log(ps)
res.end(`姓名:${ps.username},密码:${ps.password}`)
}else{
//post方法
res.writeHead(200,{'Content-type':'text/plain;charset=utf-8'})
let allData= '';
req.on('data',(chunk)=>{
allData+=chunk;
})
req.on('end',()=>{
console.log(querystring.parse(allData));
let asd=querystring.parse(allData)
console.log(asd)
res.end(`姓名:${asd.user},密码:${asd.pass}`);
});
}
}else{
res.end('404')
}
}).listen('8989');
console.log('http://127.0.0.1:8989/form/index.html');
2020-12-23 学习笔记
node登录注册(express,ajax)
创建项目文件夹demo,目录文件夹,书写文件位置如下
demo
├─node_modules
├─express.js
└─www
└─jd
├─post.html
├─index.html
├─css
└─index.css
└─js
└─jquery-1.11.3.js
主页面文件index.html
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="UTF-8">
<link rel="stylesheet" type="text/css" href="./css/index.css">
</head>
<body>
<h1>登录页面</h1>
<input type="text" placeholder="用户名"><br>
<input type="password" placeholder="密码"><br>
<button>登录</button><a href="./post.html">未注册请注册</a>
</body>
<script src="./js/jquery-1.11.3.js"></script>
<script type="text/javascript">
var url="http://localhost:8989/submit?"
$('button').click(()=>{
$.ajax({
url:url,
method:"get",
data:{
username:$('input[type="text"]').val(),
password:$('input[type="password"]').val()
},
success:function(res){
console.log(res)
location.href=`${url}username=${res.username}&password=${res.password}`//页面跳转
}
})
})
</script>
</html>
post注册页面post.html
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<h1>注册界面</h1>
<input type="text" name="user" placeholder="用户名"><br>
<input type="password" name="pwd" placeholder="密码"><br>
<button>注册</button>
<a href="./index.html">已注册请登录</a>
</body>
<script src="./js/jquery-1.11.3.js"></script>
<script type="text/javascript">
var url="http://localhost:8989/submit?"
$('button').click(()=>{
$.ajax({
url:url,
method:"post",
data:{
username:$('input[type="text"]').val(),
password:$('input[type="password"]').val()
},
success:function(res){
console.log(res)
location.href=`${url}username=${res.username}&password=${res.password}`//页面跳转
}
})
})
</script>
</html>
js主文件express.js,运行该文件,根据控制台地址登录,即可运行该网站,实现登录注册效果
const express=require('express');
const path=require('path');
const bodyparser=require('body-parser')
//WEB框架实例化
var app=express()
app.use(bodyparser.urlencoded({extended:true})) //路由解码
app.use(express.static(path.join(__dirname,"www","jd")))
.post("/submit",function(req,res) {
// post请求需要依赖专门的模块
// 1. npm install body-parser -S;
// 2. 在页面中引入
// 3. 在post请求的第二个参数加上刚刚解析body-parser得到的参数。
res.json(req.body)
})
.get("/submit",function(req,res) {
res.json(req.query)
})
.use("/",(req,res)=>{
res.send("404")
})
//监听端口
app.listen('8989',function(err) {
if (err)throw err;
console.log("http://localhost:8989")
})
2020-12-26 学习笔记
关系型数据库有哪些,非关系型数据库有哪些?两者区别?
**关系型数据库:**Oracle、DB2、Microsoft SQL Server、Microsoft Access、MySQL
**非关系型数据库:**NoSql、Cloudant、MongoDb、redis、HBase
关系型数据天然就是表格式的,因此存储在数据表的行和列中;数据表可以彼此关联协作存储,也很容易提取数据。而非关系型数据不适合存储在数据表的行和列中,而是大块组合在一起;非关系型数据通常存储在数据集中,就像文档、键值对或者图结构。
整理一份数据库操作手册。只需要指令即可
show dbs //显示现有数据库
use mydb //建立数据库
db.stu.insert({name:‘www’,age:‘30’})
- 在数据库中创建表格
- 格式: db.数据库名称.insert(添加内容)**
use mydb //使用数据库
show tables //显示数据库表格
精确查找
.count()加在find()后面,可返回值符合标准的数量
db.stu.find() //显示数据库表格内容每一个对象都会生成id
db.stu.find({name:‘www’})
- //在小括号内可添加查询条件,增加条件可直接添加,
- 例如:db.stu.find({name:‘www’})
db.stu.findOne({name:‘www’})//只返回一个对象
db.stu.find($or:[{name:‘www’},{age:‘30’}])
- find括号内添加多个条件,格式如下:
- $or:[条件一,条件二]
db.stu.find({name:{$in:[‘www’,‘age’]}})
- 查找所有满足$in后条件的均显示
- {查找对象:{$in:[条件一,条件二]}}
db.stu.find({name:/www/})
db.stu.find({name:/^w/})
- 可使用正则语法
范围查找
db.stu.find({age:{$gte:50,lte:100}})
- find括号内增加查找范围
- {查找条件:{$gte:下限值,lte:上限值}}
更改指令
db.stu.update({name:‘www’},{$set:{age:999}})
- update()为更改指令,只更新一条指令
- update(查找条件,{$set:{条件对象内对应变量 : 条件对象内修改的值}},false,true)
- 第三个参数默认为false无操作,若为true时,查找条件不存在则进行添加
- 第四个参数默认为false,只更新一条指令,若为true则全部更新
删除指令
db.stu.remove({name:‘www’})
- 删除符合条件项
db.stu.remove({})
- remove括号内为 {} 删除所有
2020-12-28 学习笔记
增删改查mongodb封装
用到的包文件 express,path,MD5,mongodb
前端页面 – index.html
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="UTF-8">
<link rel="stylesheet" type="text/css" href="./css/index.css">
</head>
<body>
<h1>用户页面</h1>
<form action="http://localhost:8989/adddata">
<input type="text" name="name" placeholder="用户名"><br>
<input type="text" name="hobby" placeholder="爱好"><br>
<button>注册(增)</button>
</form>
<form action="http://localhost:8989/selectdata">
<input type="text" name="name" placeholder="用户名"><br>
<input type="text" name="hobby" placeholder="爱好"><br>
<button>登录(查)</button>
</form>
<form action="http://localhost:8989/selectalldata">
<button>查询整个数据库数据</button>
</form>
<form action="http://localhost:8989/removedata">
<input type="text" name="name" placeholder="用户名"><br>
<input type="text" name="hobby" placeholder="爱好"><br>
<button>注销(删)</button>
</form>
<form action="http://localhost:8989/changedata">
<input type="text" name="name" placeholder="用户名"><br>
<input type="text" name="hobby" placeholder="爱好"><br>
<input type="text" name="newhobby" placeholder="新爱好"><br>
<button>更改爱好(改)</button>
</form>
</body>
</html>
封装模块包 – mongodb.js
const MongoClient = require('mongodb').MongoClient;
const url = "mongodb://localhost:27017/";
function _connect(callback){
MongoClient.connect(url,{ useUnifiedTopology: true }, function(err, db) {
if (err) throw err;
callback(db)
});
}
//查询(登录)
exports.findAll=function(dbname,tablename,data,callback){
_connect(function(db){
var dbo = db.db(dbname);
dbo.collection(tablename). find(data).toArray(function(err, result) {
// 返回集合中所有数据
if (err) throw err;
db.close();
callback(result)
});
})
}
//增加数据(注册)
exports.add=function(dbname,tablename,data,callback){
_connect(function(db){
var dbo = db.db(dbname);
if (data instanceof Array) {
data=data
}else{
data=[data]
}
dbo.collection(tablename).insertMany(data,function(err, result) {
// 返回集合中所有数据
if (err) throw err;
console.log(result);
db.close();
callback(result)
});
})
}
//删除数据(注销)
exports.remove=function(dbname,tablename,data,callback){
_connect(function(db){
var dbo = db.db(dbname);
dbo.collection(tablename).deleteOne(data,function(err, result) {
// 返回集合中所有数据
if (err) throw err;
console.log(result);
db.close();
callback(result)
});
})
}
//更改数据(更改爱好)
exports.change=function(dbname,tablename,olddata,data,callback){
_connect(function(db){
var dbo = db.db(dbname);
dbo.collection(tablename).updateMany(olddata,data,function(err, result) {
// 返回集合中所有数据
if (err) throw err;
console.log(result);
db.close();
callback(result)
});
})
}
const express=require('express');
const path=require('path');
const bodyparser=require('body-parser');
const md5=require("md5");
//mongodb模块
const mdb = require('./mongodb.js');
const app=express();
app.use(bodyparser.urlencoded({extended:true}))//路由解码
app.use(express.static(path.join(__dirname,"www","form")))
//增
.get("/adddata",(req,res)=>{
let mydata={name:req.query.name,hobby:md5(req.query.hobby)};
mdb.add("mydb","stu",mydata,(r)=>res.json(r.ops))
})
//查
.use("/selectdata",(req,res)=>{
let mydata={name:req.query.name,hobby:md5(req.query.hobby)};
mdb.findAll("mydb","stu",mydata,(r)=>res.send(r))
})
//查数据库
.use("/selectalldata",(req,res)=>{
mdb.findAll("mydb","stu",{},(r)=>res.send(r))
})
//删
.use("/removedata",(req,res)=>{
let mydata={name:req.query.name,hobby:md5(req.query.hobby)};
mdb.remove("mydb","stu",mydata,(r)=>res.send(r))
})
//改
.use("/changedata",(req,res)=>{
let olddata={name:req.query.name,hobby:md5(req.query.hobby)};
let mydata={$set:{hobby:md5(req.query.newhobby)}};
mdb.change("mydb","stu",olddata,mydata,(r)=>res.send(r))
})
app.listen("8989")
2020-12-30 学习笔记
商品增删改查
用到的包文件 express,MD5,mongodb,cookie-parser
注册页面- index.html
<!DOCTYPE html>
<html>
<head>
<title>注册页面</title>
</head>
<body>
<input type="text" placeholder="请输入用户名"><br>
<input type="password" placeholder="请输入密码"><br>
<button>注册</button><a href="./login.html">已注册请点击登录</a>
</body>
<script src="./js/jquery-1.11.3.js"></script>
<script>
$('button').click(()=>{
$.ajax({
url:"http://localhost:8989/msg",
data:{
name:$('input:eq(0)').val(),
pwd:$('input:eq(1)').val()
},
success:function(res){
console.log(res);
location.href="http://localhost:8989/login.html"
}
})
})
</script>
</html>
登录页面 – login.html
<!DOCTYPE html>
<html>
<head>
<title>登陆页面</title>
</head>
<body>
<input type="text" placeholder="请输入用户名"><br>
<input type="password" placeholder="请输入密码"><br>
<button onclick="login()">登录</button>
<button onclick="del()">注销</button>
</body>
<script src="./js/jquery-1.11.3.js"></script>
<script>
$.ajax({
url:"http://localhost:8989/z",
success:function(res){
console.log(res)
if(res!=""){
$('input:eq(0)').val(res.name)
$('input:eq(1)').val(res.pwd)
location.href="http://localhost:8989/shop.html"
}
}
})
//登录
function login() {
$.ajax({
url:"http://localhost:8989/log",
data:{
name:$('input:eq(0)').val(),
pwd:$('input:eq(1)').val()
},
success:function(res){
console.log(res)
if(res!="未注册"){
location.href="http://localhost:8989/shop.html"
}
}
})
}
//注销
function del(){
$.ajax({
url:"http://localhost:8989/removedata",
data:{
name:$('input:eq(0)').val(),
pwd:$('input:eq(1)').val()
},
success:function(res){
console.log(res)
}
})
}
</script>
</html>
商品页面 – shop.html
<!DOCTYPE html>
<html>
<head>
<title>商品页面</title>
<style type="text/css">
.write_name{
width:40px;
}
.write_price{
width:40px;
}
</style>
</head>
<body>
<input type="text" class="proname" placeholder="输入商品名字">
<input type="text" class="price" placeholder="输入商品价格">
<button id="add">增加商品</button><button id="findOne">查询商品</button>
<table>
<thead>
<tr>
<td>商品名称</td>
<td>商品价格</td>
<td>编辑商品</td>
<td>删除商品</td>
</tr>
</thead>
<tbody></tbody>
</table>
</body>
<script src="./js/jquery-1.11.3.js"></script>
<script>
//查询
(function(){
$.ajax({
url:"http://localhost:8989/find",
data:{},
success:function(res){
console.log(res)
for(let i in res){
$('tbody').append(`
<tr>
<td>${res[i].proname}</td>
<td>${res[i].proprice}</td>
<td οnclick="change(this)">编辑</td>
<td οnclick='del(this)'>删除</td>
</tr>
`)
}
}
})
})();
$("#findOne").click(function(){
$.ajax({
url:"http://localhost:8989/findOne",
data:{
proname:$('.proname').val(),
proprice:$('.proprice').val()
},
success:function(res){
console.log(res)
for(let i in res){
$('tbody').html(`
<tr>
<td>${res[i].proname}</td>
<td>${res[i].proprice}</td>
<td οnclick="change(this)">编辑</td>
<td οnclick='del(this)'>删除</td>
</tr>
`)
}
}
})
})
//编辑
var name="",price="";
function change(a){
console.log()
name=$(a).siblings().eq(0).html();
price=$(a).siblings().eq(1).html();
$(a).siblings().eq(0).html(`
<input type="text" class="write_name" value="${name}">
`)
$(a).siblings().eq(1).html(`
<input type="text" class="write_price" value="${price}">
`)
$(a).attr({"onclick":"changeok(this)"}).html("确定")
}
function changeok(a){
$.ajax({
url:"http://localhost:8989/write",
method:"get",
data:{
name:name,
price:price,
proname:$('.write_name').val(),
proprice:$('.write_price').val()
},
success:function(res){
console.log(res)
$(a).siblings().eq(0).html(`${$('.write_name').val()}`)
$(a).siblings().eq(1).html(`${$('.write_price').val()}`)
$(a).attr({"onclick":"change(this)"}).html("编辑")
}
})
}
//删除
function del(a){
$.ajax({
url:"http://localhost:8989/del",
data:{
proname:$(a).siblings().eq(0).html()
},
success:function(res){
$(a.parentNode).remove()
}
})
}
//添加
$('#add').click(()=>{
$.ajax({
url:"http://localhost:8989/add",
method:"get",
data:{
proname:$('.proname').val(),
proprice:$('.price').val()
},
success:function(res){
console.log(res)
if (res!=="均不能为空") {
$('tbody').append(`
<tr>
<td>${res[0].proname}</td>
<td>${res[0].proprice}</td>
<td οnclick='change(this)'>编辑</td>
<td οnclick='del(this)'>删除</td>
</tr>
`)
$('.proname').val("");
$('.price').val("");
}else{
alert(res)
}
}
})
})
</script>
</html>
后端模块文件 – mongodb.js
const MongoClient = require('mongodb').MongoClient;
const url = "mongodb://localhost:27017/";
function _connect(callback){
MongoClient.connect(url,{ useUnifiedTopology: true }, function(err, db) {
if (err) throw err;
callback(db)
});
}
//查询(登录)
exports.findAll=function(dbname,tablename,data,callback){
_connect(function(db){
var dbo = db.db(dbname);
dbo.collection(tablename).find(data).toArray(function(err, result) {
// 返回集合中所有数据
if (err) throw err;
console.log(result)
db.close();
callback(result)
});
})
}
//增加数据(注册)
exports.add=function(dbname,tablename,data,callback){
_connect(function(db){
var dbo = db.db(dbname);
if (data instanceof Array) {
data=data
}else{
data=[data]
}
dbo.collection(tablename).insertMany(data,function(err, result) {
// 返回集合中所有数据
if (err) throw err;
console.log(result);
db.close();
callback(result)
});
})
}
//删除数据(注销)
exports.remove=function(dbname,tablename,data,callback){
_connect(function(db){
var dbo = db.db(dbname);
dbo.collection(tablename).deleteOne(data,function(err, result) {
// 返回集合中所有数据
if (err) throw err;
db.close();
callback(result)
});
})
}
//更改数据(更改爱好)
exports.change=function(dbname,tablename,olddata,data,callback){
_connect(function(db){
var dbo = db.db(dbname);
dbo.collection(tablename).updateMany(olddata,data,function(err, result) {
// 返回集合中所有数据
if (err) throw err;
db.close();
callback(result)
});
})
}
后端主文件 – main.js
const express=require('express');
const path=require('path');
const bodyparser=require('body-parser');
const md5=require("md5");
//mongodb模块
const mdb = require('./mongodb.js');
//cookies包
const cookieParser=require('cookie-parser')
const app=express();
app.use(cookieParser())
app.use(bodyparser.urlencoded({extended:true}))//路由解码
app.use(express.static('./www/form/'))
//注册用户
.get('/msg',(req,res)=>{
console.log(req.query)
mdb.add("mydb","stu",req.query,(r)=>res.json(r.ops))
})
//检测是否登录过,若是直接跳转
.get('/z',(req,res)=>{
//console.log(req.cookies.msg)
if (req.cookies.msg) {
res.send(req.cookies.msg)
}else{
res.send('')
}
})
//登录并记录cookie
.get('/log',(req,res)=>{
console.log(req.query)
mdb.findAll("mydb","stu",req.query,(r)=>{
if(r!=""){
//书写cookie Pes.cookie( 'cookie名字’,值,{maxAge:设置cookie存在时间ms})
res.cookie('msg',req.query,{maxAge:8400000,httpOnly:true})
res.json(r);
}else{
res.send("未注册")
}
})
})
//增加商品
.get('/add',(req,res)=>{
if(req.query.proname!==""&&req.query.proprice!==""){
mdb.add("mydb","shop",req.query,(r)=>res.json(r))
}else{
res.json("均不能为空")
}
})
//扫描全部商品
.use('/find',(req,res)=>{
mdb.findAll("mydb","shop",{},(r)=>res.json(r))
})
.use('/findOne',(req,res)=>{
mdb.findAll("mydb","shop",req.query,(r)=>res.json(r))
})
//删除商品
.use('/del',(req,res)=>{
console.log(req.query)
mdb.remove("mydb","shop",req.query,(r)=>res.send(r))
})
//编辑商品
.get('/write',(req,res)=>{
console.log(req.query.proname,req.query.proprice)
console.log(req.query.name,req.query.price)
let olddata={proname:req.query.name,proprice:req.query.price};
let mydata={$set:{proname:req.query.proname,proprice:req.query.proprice}};
mdb.change("mydb","shop",olddata,mydata,(r)=>res.send(r.ops))
})
app.listen("8989")
问题整理
在使用cookie-parser包时,调用cookie的时候注意res.json(r);
放到最后一行避免报错
res.cookie('msg',req.query,{maxAge:8400000,httpOnly:true})
res.json(r);
2021-01-04 学习笔记
分页功能
//扫描全部商品
.use('/find',(req,res)=>{
let num=parseInt(req.query.num);
console.log(req.query.type,num)
if(req.query.type=="next"){
num>=1?num=parseInt(num)*10+1:num=0;
}else if(req.query.type=='prov'){
num<=0?num=0:num=(parseInt(num)-2)*10+1;
}
mdb.findAll("mydb","shop",{},(r)=>{
res.json(r)
},{},num,10)
})
var back=2;
function next(){
console.log(num,back)
if(num<back){
$.ajax({
url:"http://localhost:8989/find",
data:{
num:num,
type:"next"
},
success:function(res){
num=parseInt(num+=1)
console.log(res.length)
$('tbody').html("")
for(var i in res){
$('tbody').append(`
<tr>
<td>${res[i].proname}</td>
<td>${res[i].proprice}</td>
<td id="${res[i]._id}" onclick="change(this)">编辑</td>
<td onclick='del(this)'>删除</td>
</tr>
`)
}
back++;
res.length<10&&(back=num);
}
})
}
}
function prov(){
console.log(num)
if(num>1){
$.ajax({
url:"http://localhost:8989/find",
data:{
num:num,
type:"prov"
},
success:function(res){
num=parseInt(num-=1)
console.log(res,num)
//if(res.length<10)return "第一页"
$('tbody').html("")
for(var i in res){
$('tbody').append(`
<tr>
<td>${res[i].proname}</td>
<td>${res[i].proprice}</td>
<td id="${res[i]._id}" onclick="change(this)">编辑</td>
<td onclick='del(this)'>删除</td>
</tr>
`)
}
res.length=10&&(back=num+1);
}
})
}
}
2021-01-09 学习笔记
聊天室
运用node中ejs,express,mongodb,socket.io配置聊天室
登录后进行会话
后端主文件chat.js
const express=require('express');
const app=express();
//mongodb模块
const mdb = require('./mongodb.js');
//配置socket.io
const http=require('http').Server(app);
const io=require('socket.io')(http);
//配置ejs
const ejs=require('ejs');
app.set('view engine','ejs');
//呈递静态资源
app.use(express.static('./www'))
app.use(express.static('./views'))
app.get('/',(req,res)=>{
console.log(req.query)
let user=req.query.name;
res.render('index',{user:user});
})
app.get('/log',(req,res)=>{
mdb.findAll("mydb","stu",req.query,(r)=>{
console.log(r)
if(r!=""){
res.json(r);
}else{
res.send("未注册")
}
})
})
app.get('/chat',(req,res)=>{
console.log(req.query,"chat")
res.render('chat',{msg:req.query,user:req.query.name});
})
.get('/msg',(req,res)=>{
console.log(req.query,"msg")
/*mdb.add("mydb","talk",req.query,(r)=>{
res.json(r.ops)
})*/
})
//配置长连接
io.on('connection',(socket)=>{
//接收客户端数据 on监听数据接收
socket.on('chat',(msg)=>{
//发送数据给客户端
io.emit('send',msg)
mdb.findAll("mydb","talk",{},(r)=>{
console.log(r.ops)
})
})
})
//如果使用socket.io 不能使用app监听
http.listen('8989')
mongodb.js模块文件
const MongoClient = require('mongodb').MongoClient;
const url = "mongodb://localhost:27017/";
function _connect(callback){
MongoClient.connect(url,{ useUnifiedTopology: true }, function(err, db) {
if (err) throw err;
callback(db)
});
}
//查询(登录)
// 查询封装的时候,考虑是否需要分页是否需要排序
// 需要书写函数参数的默认值,因为用户有可能不会书写
exports.findAll=function(dbname,tablename,data,callback,mysort={},myskip=0,mylimit=0){
_connect(function(db){
var dbo = db.db(dbname);
// sort排序
// skip跳过多少条数据
// limit()限制取数据的数量
dbo.collection(tablename).find(data).sort(mysort).skip(myskip).limit(mylimit).toArray(function(err, result) {
// 返回集合中所有数据
if (err) throw err;
db.close();
callback(result)
});
})
}
//增加数据(注册)
exports.add=function(dbname,tablename,data,callback){
_connect(function(db){
var dbo = db.db(dbname);
if (data instanceof Array) {
data=data
}else{
data=[data]
}
dbo.collection(tablename).insertMany(data,function(err, result) {
// 返回集合中所有数据
if (err) throw err;
//console.log(result);
db.close();
callback(result)
});
})
}
//删除数据(注销)
exports.remove=function(dbname,tablename,data,callback){
_connect(function(db){
var dbo = db.db(dbname);
dbo.collection(tablename).deleteOne(data,function(err, result) {
// 返回集合中所有数据
if (err) throw err;
db.close();
callback(result)
});
})
}
//更改数据(更改爱好)
exports.change=function(dbname,tablename,olddata,data,callback){
_connect(function(db){
var dbo = db.db(dbname);
dbo.collection(tablename).updateMany(olddata,data,function(err, result) {
// 返回集合中所有数据
if (err) throw err;
db.close();
callback(result)
});
})
}
聊天室页面chat.ejs
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<h1>欢迎 <%=user %> 进入聊天室</h1>
<input type="text">
<button οnclick="talk()">发送</button>
<ul>
</ul>
<script type="text/javascript" src="form/js/jquery-1.11.3.js"></script>
<!-- 引人sotket.io框票自动去node_modules文件夹寻我 -->
<script type="text/javascript" src="socket.io/socket.io.js"></script>
<script type="text/javascript">
//引入框架
let socket=io();
$('button').click(()=>{
//发送数据socket.emit('发送的名字和后台接收保持一致',[数据})
socket.emit('chat',{msg:$('input').val()})
})
socket.on('send',(msg)=>{
console.log(msg)
$("ul").append(`<p><%=user%>:${msg.msg}</p>`)
})
function talk() {
$.ajax({
url:"http://localhost:8989/msg",
data:{
msg:$('input:eq(0)').val()
},
success:function(res){
console.log(res)
}
})
}
</script>
</body>
</html>
登陆页面index.ejs
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<% if(user){ %>
<h1>欢迎<%= user %>登陆</h1>
<% }else{ %>
<h1>请登陆</h1>
<input type="text" placeholder="请输入用户名"><br>
<input type="password" placeholder="请输入密码"><br>
<button οnclick="login()">登录</button>
<% } %>
</body>
<script type="text/javascript" src="form/js/jquery-1.11.3.js"></script>
<script type="text/javascript">
//登录
function login() {
$.ajax({
url:"http://localhost:8989/log",
data:{
name:$('input:eq(0)').val(),
pwd:$('input:eq(1)').val()
},
success:function(res){
console.log(res)
if(res!="未注册"){
location.href=`http://localhost:8989/chat?name=${res[0].name}`
}
}
})
}
</script>
</html>
20210123 学习笔记
vue.js简介
Vue.js 是一个轻巧、高性能、可组件化的 MVVM 库,拥有非常容易上手的 API;
Vue.js是一个构建数据驱动的 Web 界面的库。
而其中的MVVM指的是一种架构模式。通俗的来讲就是 视图 模型 和控制器的关系
<!-- 指的是MVVM中的(V)view视图 -->
<div id="app">
{{msg}}
</div>
// new Vue指的是MVVM中的VM(viewModel控制器) 把视图和数据联系起来
new Vue({
el:'#app',
// data指的是MVVM中的M(model数据模型)
data:{
msg:'hello'
}
})
vue.js使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div id="app">
{{msg}}
{{list}}
</div>
<div id="box">
{{msg}}
</div>
<!-- 第一步:引入框架 -->
<script src="js/vue.js"></script>
<script>
new Vue({
// el绑定元素不能是html/body。可以是标签名、类名、id名。一般使用的是id名(避免不必要的问题)。如果多个符合条件,只执行第一个符合条件的。
// id名是唯一的,一个标签只能有一个id名
el:'#app',
data:{
// 数据的格式k:v,k:v
msg:'hello vue',
list:['a','b']
}
})
// 可以实例化多个对象,不建议
new Vue({
// el绑定元素不能是html/body。可以是标签名、类名、id名。一般使用的是id名(避免不必要的问题)。如果多个符合条件,只执行第一个符合条件的。
// id名是唯一的,一个标签只能有一个id名
el:'#box',
data:{
msg:'hello box'
}
})
</script>
</body>
</html>
vue插值表达式
在vue语法内部,可以使用{{}}称为插值表达式。表达式内部,可以放置变量或者表达式或者函数
注意:
1、vue语法外部,使用不了插值表达式
2、{{放置的变量,只能是在data中声明过的,外部的数据不能使用}}
vue事件结构
事件的结构:
v-on:事件类型="方法名()"
click mouseenter mouseleave focus blur
事件方法中的实参this指的是window对象,不再是当前标签
$event
指的是事件相关的参数
$event.target
可以获取当前标签
vue中有专门封装的获取标签的方法 给标签取ref值 this.$refs.标签的ref的值
<button ref="btn">按钮</button>
<script src="js/vue.js"></script>
<script>
new Vue({
el:'#app',
methods:{
a(){
this.$refs.app.style.background='red';
}
}
})
</script>
v-html和v-text
v-html和v-text都可以增加内容
v-html可以识别标签。有xss(可以通过html书写病毒,攻击网站)风险
v-text识别不了标签,把标签当做普通文本处理。可以使用{{}}代替
20210125 学习笔记
使用vue实现发微博效果(发布和删除效果)
<!DOCTYPE html>
<html>
<head>
<title></title>
<style type="text/css">
#titlebox{
display: inline-block;
margin: 5px;
}
#msgbox{
background: #eee;
}
</style>
</head>
<body>
<div id="app">
<div id="titlebox">
<input type="text" ref="title" placeholder="输入博文标题"><br><br>
<textarea cols="50" ref="massage" rows="5" placeholder="输入博文内容"></textarea><br>
<button v-on:click="a">提交</button>
</div>
<div id="msgbox" v-for="(item,index) in msg">
<p>{{item.title}}</p>
<p>{{item.massage}}</p>
<p v-on:click="del(index)">删除博文</p>
</div>
</div>
</body>
<script type="text/javascript" src="./js/vue.js"></script>
<script type="text/javascript">
new Vue({
el:'#app',
data:{
msg:[]
},
methods:{
a(){
console.log(this.$refs.title.value,this.$refs.massage.value)
this.msg.push({
title:this.$refs.title.value,
massage:this.$refs.massage.value,
})
console.log(this.msg)
},
del(a){
this.msg.splice(a,1)
}
},
})
</script>
</html>
使用vue实现tab栏
<!DOCTYPE html>
<html>
<head>
<title></title>
<style type="text/css">
#titlebox{
display: inline-block;
margin: 5px;
}
#msgbox{
width: 300px;
height: 200px;
background: #eee;
}
</style>
</head>
<body>
<div id="app">
<div id="titlebox" v-for="(item,index) in title">
<span v-on:click="a(index)">{{item}}</span>
</div>
<div id="msgbox">
{{msg[num]}}
</div>
</div>
</body>
<script type="text/javascript" src="./js/vue.js"></script>
<script type="text/javascript">
new Vue({
el:'#app',
data:{
num:0,
title:['新闻','娱乐','科技'],
msg:['新闻热点-----','娱乐热点++++++','科技热点/']
},
methods:{
a(a){
this.num=a
},
},
})
</script>
</html>
computed和watch有何区别
computed
支持缓存,只有依赖数据发生改变,才会重新进行计算
不支持异步,当computed内有异步操作时无效,无法监听数据的变化
computed 属性值会默认走缓存,计算属性是基于它们的响应式依赖进行缓存的,也就是基于data中声明过或者父组件传递的props中的数据通过计算得到的值
如果一个属性是由其他属性计算而来的,这个属性依赖其他属性,是一个多对一或者一对一,一般用computed
如果computed属性值是函数,那么默认会走get方法;函数的返回值就是属性的属性值;在computed中的,属性都有一个get和一个set方法,当数据变化时,调用set方法。
watch
不支持缓存,数据变化,直接触发;
watch支持异步;
监听的函数接收两个参数,第一个参数是最新的值;第二个参数是输入之前的值;
当一个属性发生变化时,需要执行对应的操作;一对多;
监听数据必须是data中声明过或者父组件传递过来的props中的数据,当数据变化时,触发其他操作,函数有两个参数:
20210127 学习笔记
spa单页面开发
单页 Web 应用 (single-page application 简称为 SPA) 是一种特殊的 Web 应用。它将所有的活动局限于一个Web页面中,仅在该Web页面初始化时加载相应的HTML、JavaScript 和 CSS。一旦页面加载完成了, 以后的每次请求, 仅仅是获取必要的数据.然后, 由页面中js解析获取的数据, 展示在页面中
vue实现spa的优势
- 良好的交互体验
因为是局部渲染,避免了不必要的跳转和重复渲染 - 前后端分离提高开发效率
- 减轻服务器的压力。
服务器只需要提供数据,不需要管前端展示逻辑和页面合成 - 共用一套后端程序代码。
实现分类页面
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0, shrink-to-fit=no, viewport-fit=cover">
<style>
*{
margin: 0px;
padding: 0px;
list-style: none;
}
/* 一般两边留白固定20px */
header{
height: 40px;
background: lime;
}
section{
height: calc(100vh - 40px - 40px);
background: pink;
}
footer{
position: fixed;
bottom: 0px;
left: 0px;
height: 40px;
width: 100%;
background: lime;
}
.left{
width: 20%;
float: left;
height: calc(100vh - 40px - 40px);
overflow: scroll;
text-align: center;
}
.right{
width: 80%;
float: right;
height: calc(100vh - 40px - 40px);
overflow: scroll;
}
footer li{
width: 20%;
float: left;
background: red;
height: 40px;
}
footer li:nth-of-type(2n){
width: 20%;
float: left;
background: blue;
height: 40px;
}
</style>
</head>
<body>
<div id="app">
<header></header>
<section>
<ul class="left">
<li v-for="(item,index) in list" @click='msg=item.msg'>{{item.con}}</li>
</ul>
<div class="right">
<component :is="msg"></component>
</div>
</section>
<footer>
<ul>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
</footer>
</div>
<template id="man">
<h1>男装</h1>
</template>
<template id="woman">
<h1>女装</h1>
</template>
<template id="mshoes">
<h1>男鞋</h1>
</template>
<template id="wshoes">
<h1>女鞋</h1>
</template>
</body>
<script src="js/vue.js"></script>
<script>
new Vue({
el:"#app",
data:{
msg:'man',
list:[
{
con:"男装",
msg:"man"
},
{
con:"女装",
msg:"woman"
},
{
con:"男鞋",
msg:"mshoes"
},
{
con:"女鞋",
msg:"wshoes"
},
],
shoplist:['111T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','T恤','222T恤'],
},
components:{
'man':{
template:"#man"
},
'woman':{
template:"#woman"
},
'mshoes':{
template:"#mshoes"
},
'wshoes':{
template:"#wshoes"
}
}
})
</script>
</html>
20210130 学习笔记
子组件的值传递给父组件
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>练习</title>
</head>
<body>
<!-- 子组件的值传递给父组件
1、 在子组件中定义方法/事件,方法/事件内部
this.$emit('事件名',所需发送的数据(发送给父组件的数据))
2、 在占位符中 @事件名(在子组件定义的事件)='方法名(不加括号!需要在父组件中定义过)'
3、 在父组件中,定义接受数据的方法
4、 在子组件中,执行刚刚定义的事件方法
-->
<div id="app">
<v-header @send="get"></v-header>
{{t.msg}}<br>
<button @click="change">change</button>
</div>
<template id="header">
<div>
<h1>head</h1>
<!-- 自动触发fn方法 -->
{{fn()}}
</div>
</template>
</body>
<script src="js/vue.js"></script>
<script>
var header={
template:"#header",
data(){
return{
msg:{
msg:'this is son'
},
}
},
methods:{
fn(){
this.$emit('send',this.msg)
}
}
}
new Vue({
el:"#app",
data:{
num:'this is father',
t:'',
},
methods:{
get(a){
this.t=a
console.log('send successful')
console.log(a)
},
change(){
this.t.msg+=1
}
},
components:{
'v-header':header
}
})
</script>
</html>
父组件的值传递给子组件
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>练习</title>
</head>
<body>
<!-- 父组件的值传递给子组件
1、 占位符中 :a="fmsg" a子组件中需要接收的数据(自定义) fs父组件数据
2、 在子组件中定义属性 props 接受a props:['a']
3、 在子组件中可以直接使用a
-->
<div id="app">
<!-- {{msg}} 报错 -->
<v-header :a="num"></v-header>
</div>
<template id="header">
<div>
<h1>head</h1>
<button @click='change'>按钮</button>
{{a.num}}
</div>
</template>
</body>
<script src="js/vue.js"></script>
<script>
var header={
template:"#header",
data(){
return{
msg:'this is son',
}
},
watch:{
},
methods:{
change(){
this.a.num+=1
//console.log(this.a)
}
},
props:['a'],
}
new Vue({
el:"#app",
data:{
num:{
num:'this is father'
}
},
components:{
'v-header':header
}
})
</script>
</html>