--a.vue项目脚手架搭建:【默认端口为8080】
1.项目搭建:vue-cli3(不用手动配置webpack配置项)/vue-cli2(vue init webpack mydemo[手动设置配置项vue.config.js内的配置项])
2.全局安装:npm install -g @vue/cli
3.检测:vue -V
4.搭建自己项目(项目名:mydemo):vue create mydemo
5.搭建方式:1.默认 第一条default (一般选择第二条)2.manuslly(根据自己的需求配置 里面包含bable,TS,router,vuex,css预编译器,eslint...)
*选择上述需求的时候通过(上下左右)+空格选中想选的项,选完然后回车确定
6.安装完后npm install跑一下环境,根据packjson.js的启动项进行启动检查是否搭建完成
--b.express搭建node.js服务器,通过脚手架搭建
1.项目搭建:(cd进入项目文件夹,cmd通过npm进行安装)
安装命令:1.npm install express-generator -g 2.express -e
2.npm install(跑环境,注意拿到项目首先看package.json),然后看根据package.json启动项进行启动检查是否安装成功【默认端口为3000】
3.默认的端口就是3000,更改端口:路径:app/bin/www --- var port = normalizePort(process.env.PORT || '3000');
--c.项目请求(ajax/fetch/axios)
特点:ajax是通过ajax的核心对象xhr对服务器端进行请求,拿到请求响应回的数据返回,用JavaScript将其渲染到DOM结构,axios是node.js创建的http请求,
支持promise,还可以防止 CSRF,fetch是window的一个方法,使用promise的异步处理机制解决回调,不会发送cookie
以fetch为例子:(首先他们都可能遇到跨域问题,解决跨域问题小技巧如下:app.js内引入)
//下面这一步是为了实现跨域访问资源
app.all("*",(req,res,next)=>{
res.header("Access-Control-Allow-Origin", "*");
res.header('Access-Control-Allow-Methods', 'PUT, GET, POST, DELETE, OPTIONS');
res.header("Access-Control-Allow-Headers", "X-Requested-With");
res.header('Access-Control-Allow-Headers', 'Content-Type');
res.header('Access-Control-Allow-Credentials', true);
if(req.method=="OPTIONS") res.send(200);/*让options请求快速返回*/
else next();
})
#【express生成的脚手架,在router文件夹下的index.js(路由器)内有俩写好的路由,一般使用一个路由(可根据自己意愿更改)即可,可以将user的路由在app.js内删掉
然后设置根路由(app.use('/index', indexRouter);--'/index' 值表示的是根路由地址,可以自己修改)】
1.get-请求:子路由地址('/api/test'),请求的url地址为 eg:http://localhost:3000/index/api/test ,该地址对应一个被请求的文件,文件格式一般为json,通过fetch的默认请求(get)进行请求,返回请求地址对应的json文件,下例的data即为json内的内容可以根据自己需求进行渲染
eg:
路由器: router.get('/api/test', (req, res)=> {
res.json(require("../data/test.json"))
});
前端请求:fetch("http://localhost:3000/index/api/test").then(res=>{
res.json().then(data=>{
//this.data=data
console.log(data)
})
})
2.post-请求:post请求一般伴随值传值问题,所以需要node.js的读写模块fs,可以通过require的方式进行直接引入,var fs=require('fs');
eg:
路由器端: router.post("/api/test1", (req, res) => {//路由地址同get请求,不要设置成一样的名字,req,res 为请求响应
var params = req.body; //req.body是前端传回的数据,将其赋值给params
fs.readFile("./data/cart.json", function (err, data) { //读取json,读出来的是二进制
if (err) {
return console.error(err);
} //如果有错误抛出错误
var dataString = data.toString(); //二进制的数据转换为字符串
var dataJson = JSON.parse(dataString); //字符串转化为json对象
dataJson.style.splice(0,dataJson.style.length); //dataJson是json文件内的内容,sytle,是json文件内部的数据结构的值,
可以通过splice方法,对想要删除的数据进行操作
dataJson.style.push(params); //同上,将传来的对象push进json文件
var str = JSON.stringify(dataJson);
//因为nodejs的写入文件只认识字符串或者二进制数,所以把json对象转换成字符串重新写入json文件中
fs.writeFile("./data/cart.json", str, function (err) {
if (err) {
console.error(err);
}
console.log("读写完成,此时data目录下的cart.json(举例的json)内容发生改变,OK");
res.json({
"state": 1
});
});
})
});
前端POST请求:
fetch('http://localhost:3000/cart/api/note', {
method: "post", //传参方式
headers: {
"Content-Type": "application/json" //请求头
},
body: JSON.stringify(info) //传的参数,路由端的req.body 接收
}).then(res => {
res.json().then(data => {
console.log(data)
if (data.state == 1) {
alert("上传数据到course.json");
}
});
})
d-- 路由传参的query方式:(路由传参有三种方式,包括query一种,和params(俩种),在url中显示参数和不显示参数俩种)
##定义路由中我们都使用了mode:history 作用就是去除路由跳转时路由路径前的 “#”,默认为hash模式带有#
1.params显示参数:path: "/one/login/:num"(path表示的是配置路由的参数)路径和to="/one/login/001"(to后面跟的对应的路由地址)必须书写正确
子路由通过 this.$route.params.num 的形式来获取父路由向子路由传递过来的参数,通过这样的方式将参数在父路由到子路由之间进行了传值
2.params不显示参数:在配置路由的时候,使用name参数映射对应路由,在父路由组件上使用router-link进行路由导航,使用 <router-link :to="{name:'home',params:{id:001}}>
形式传递参数。注意 ': to= ' 前面的冒号,子路由获取的参数:{{this.$route.params.num}},这种方式传递的值,会在页面刷新后丢失
3.query进行传参:修改路由导航<router-link :to="{path:'/one/log',query:{num:123}}">,
子路由组件通过 this.$route.query.num 来显示传递过来的参数
路由传参:router-link 用 to 通过模板字符串,路由地址?id的方式 (路由传参的query方式)
eg:(拿单个商品的路由传参来说明,可以通过自己喜欢的形式进行传参数) :to="`routerLink?id=${index}`"(routerLink代表路由地址,id="index"代表单个商品信息对应的索引值)
通过这种方式将,需要传输的值传到 url地址里面,然后用 this.$router.query的方式来获取到传过去的值
<router-link :to="`/shopDetails?id=${index}`"
class="shops"
v-for="(item,index) in data" :key="index"
tag="div">
e-- $router 是全局的路由器对象,包括很多的子对象 history,this.$router.push,$route 是当前正在跳转的路由对象,有 query ,params,name ,path等属性
f-- vue组件传值的问题:父子传值(包括父传子,子传父)还有兄弟传值(事件总线 event.bus ,vuex进行状态管理)
父传子:
如果需要传递的值在data中,可以通过自定义属性在 被传递的子组件上通过自定义属性的方式将data内的值传递出去,
子组件通过在props内写好父组件的自定义属性,来完成接口的对接
如果需要传递的值从,fetch/axios中获取到,提前在data内写好接收的地方(占位子),
此时就可以将通过fetch/axios请求的数据,然后通过this打点的方式,赋值给data内提前占好的位置,然后如上进行传递和子组件接受
eg:父组件内子组件的标签上写 :UserNoteContent="UserNoteContent" ,
(:UserNoteContent自定义属性,"UserNoteContent"是在data内的占位数据)
data(){
return{
UserNoteContent:'' //如果有数据 '' 内写的就是数据,如果数据从fetch或axios获取,则 this.UserNoteContent = data.UserNoteContent
}
}
子传父:
#子传父需要用到 this.$emit("参数一:自定义事件名(父组件内和子组件内相同)",参数二:需要传递的值)
eg:
子组件内通过事件触发,eg:@click = "isShowNote",定义一个自定义事件("isShowNote3"),this.showNode3是data内定义的showNote3的值(需要传递的值即可),
将其作为this.$emit()的第二个参数进行传递
isShowNote(){
this.$emit("isShowNote3",this.showNode3)
console.log([this.showNode3,this.show])
},
在父组件内在,通过想对父组件传递值所对应的子组件上通过v-on:或者 @符进行绑定父组件内定义的自定义事件,然后触发自定义事件内绑定的函数,
然后在该函数内处理从子组件传递过来的值,
eg:
@isShowNote3="isShowNote3"
isShowNotes3(data){ //data为子组件内this.$emit()内的参数2,可以在这里处理从子组件传递回来的数据
this.showNode3 = data
},
兄弟组件传值: