1.2重复创建项目: 从哪一步
Vue init webpack 项目名
1.3复制项目: 不要直接复制
复制除了node_modules, 之外的文件
复制完成之后, cnpm install
1.4目录不一样
没关系,
npm run dev 能启动就成
1.5启动后按Ctrl + c关闭
就访问不到http://localhost:8080/ 了。
因为npm run dev启动的是前端服务器,你关掉之后就没有这个服务了,服务都不在了,谁来监听端口呢?当然访问不到端口号8080了。
服务最重要的特点: 监听端口, 分析请求, 返回内容
1.6分析一下目录结构
在IDEA中:File—>open—>E:\WangDao\Vue_project\vuetest,打开昨天新建的项目。
可能需要你改变的文件:
前端程序员日常工作目录其实就是src目录
1.6.1默认端口
npm run dev后端口号不是8080 一般是端口被占用了
1.6.2关于打包(在部署的时候,把项目放到服务器上给用户访问的时候,就需要打包):
有两种打包方式:Windows和Mac
Windows不用任何改变,Mac或Linux系统需要加个“.”。
mac注意:改两处
1.6.3代理
红线部分就是代理
代理,我们一般访问服务器就是浏览器向服务器发送请求,服务器响应浏览器。
有时候不能直接访问服务器,就先访问别的地方,让这个地方访问服务器。
前端有个问题:跨域? (不允许两个不同的ip或者端口请求, 在同一个页面产生)
这是浏览器的一种同源策略,否则会有安全问题。
但是我们想让浏览器实现这种功能。根据前后端分离这张图我们知道,只有浏览器得有两个请求,一次请求前端的页面,一次请求后端的数据。
两种跨域(通用)的解决办法?
1.后端做处理
2.代理
刚开始得页面从8085(前端服务器)来的,我想要获取数据,得去8084(后端服务器)获取,但是浏览器不允许啊,那我就还去8085获取,8085做代理,发请求给8084,获取数据之后再返回给浏览器。
如果你的IDEA打不开前端项目,可以试着把.idea文件删除,然后再打开。
主要原因是你给IDEA设置的内存太小了,因为node_modules这个文件很大,IDEA是需要建立索引才能打开的(IDEA打开java项目也是),索引建立失败就打不开了。
对于java项目也是这样。
解读具体文件
Package.json:
{
"name": "vuetest",
"version": "1.0.0",
"description": "A Vue.js project",
"author": "liushihao <2592693386@qq.com>",
"private": true,
"scripts": {
"dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
"start": "npm run dev",
//打包命令:npm run build
"build": "node build/build.js"
},
//cnpm install就是装包,根据的就是以下内容装,左边表示包名,右边表示版本号。
//node_modules就是根据这些内容下载的包
//"dependencies"(打包版)表示项目真正打包的时候依赖的包
"dependencies": {
"vue": "^2.5.2"
},
//"devDependencies"(开发版)npm run dev启动的就是开发版的
//我们程序员在开发的时候用到的包
"devDependencies": {
"autoprefixer": "^7.1.2",
"babel-core": "^6.22.1",
"babel-helper-vue-jsx-merge-props": "^2.0.3",
"babel-loader": "^7.1.1",
"babel-plugin-syntax-jsx": "^6.18.0",
"babel-plugin-transform-runtime": "^6.22.0",
"babel-plugin-transform-vue-jsx": "^3.5.0",
"babel-preset-env": "^1.3.2",
"babel-preset-stage-2": "^6.22.0",
"chalk": "^2.0.1",
"copy-webpack-plugin": "^4.0.1",
"css-loader": "^0.28.0",
"extract-text-webpack-plugin": "^3.0.0",
"file-loader": "^1.1.4",
"friendly-errors-webpack-plugin": "^1.6.1",
"html-webpack-plugin": "^2.30.1",
"node-notifier": "^5.1.2",
"optimize-css-assets-webpack-plugin": "^3.2.0",
"ora": "^1.2.0",
"portfinder": "^1.0.13",
"postcss-import": "^11.0.0",
"postcss-loader": "^2.0.8",
"postcss-url": "^7.2.1",
"rimraf": "^2.6.0",
"semver": "^5.3.0",
"shelljs": "^0.7.6",
"uglifyjs-webpack-plugin": "^1.1.1",
"url-loader": "^0.5.8",
"vue-loader": "^13.3.0",
"vue-style-loader": "^3.0.1",
"vue-template-compiler": "^2.5.2",
"webpack": "^3.6.0",
"webpack-bundle-analyzer": "^2.9.0",
"webpack-dev-server": "^2.9.1",
"webpack-merge": "^4.1.0"
},
"engines": {
"node": ">= 6.0.0",
"npm": ">= 3.0.0"
},
"browserslist": [
"> 1%",
"last 2 versions",
"not ie <= 8"
]
}
Index.html是入口文件,整个项目就是从这个文件进入的。
你写的java代码的入口在main方法。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>vuetest</title>
</head>
<body>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
再看src目录下的main.js文件:
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
components: { App },
template: '<App/>'
})
这就是我们之前讲的用Vue对象操作html页面。
Vue对象中的模板会替换挂载的元素,模板从子组件App中来,App是从import App from './App'导入的,指的就是同级目录下的App.vue,也就是说,把App.vue当成一个子组件导入到入口对象中使用。
App.vue:
<template>
<div id="app">
<img src="./assets/logo.png">
//默认是这样写的<HelloWorld/>,但我们应当是下一行代码的写法,原因在组件的 //大小写中讲过,这个HelloWorld是下面对象中的子组件,这个HelloWorld从哪来呢
//import HelloWorld from './components/HelloWorld' 从这里来
<hello-world/>
</div>
</template>
<script>
import HelloWorld from './components/HelloWorld'
//上面的template模板是下面对象的模板,相当于对象中有个template属性一样。
//它本身是一个对象,经过main.js中入口对象(new Vue)的引用components: { App }
//之后称为了Vue对象,成为一个子组件,从而具有了实际意义。
//export default默认导出,也就是说,App.vue对外界输出的默认就是这个对象
//也就是说,main.js中import App from './App'实际导入的就是一个对象
export default {
name: 'App',
components: {
HelloWorld
}
}
</script>
<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
HelloWorld.vue:
<template>
<div class="hello">
<h1>{{ msg }}</h1>
<h2>Essential Links</h2>
<ul>
<li>
<a
href="https://vuejs.org"
target="_blank"
>
Core Docs
</a>
</li>
<li>
<a
href="https://forum.vuejs.org"
target="_blank"
>
Forum
</a>
</li>
<li>
<a
href="https://chat.vuejs.org"
target="_blank"
>
Community Chat
</a>
</li>
<li>
<a
href="https://twitter.com/vuejs"
target="_blank"
>
Twitter
</a>
</li>
<br>
<li>
<a
href="http://vuejs-templates.github.io/webpack/"
target="_blank"
>
Docs for This Template
</a>
</li>
</ul>
<h2>Ecosystem</h2>
<ul>
<li>
<a
href="http://router.vuejs.org/"
target="_blank"
>
vue-router
</a>
</li>
<li>
<a
href="http://vuex.vuejs.org/"
target="_blank"
>
vuex
</a>
</li>
<li>
<a
href="http://vue-loader.vuejs.org/"
target="_blank"
>
vue-loader
</a>
</li>
<li>
<a
href="https://github.com/vuejs/awesome-vue"
target="_blank"
>
awesome-vue
</a>
</li>
</ul>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
//data域换了个写法而已,其实本质上和之前学的data:{}这种写法没啥区别
//methods写法不变,除了data写法不一样,其他属性的写法都和之前一样
data () {
return {
msg: 'Welcome to Your Vue.js App'
}
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h1, h2 {
font-weight: normal;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>
1.7Idea安装插件 Setting--->plugins,搜vue
如果你安装好插件之后想新建一个.vue文件还是新建不出来,设置一下:
版本1:
写一个和css中Homework1一样的页面,左边有链接,右边显示网页。
那么就用到两个子组件:Left.vue和Right.vue。
index.html中是代码的入口。main.js是第父组件,其中导入了第二级子组件App.vue,
第二级子组件App.vue中导入第三级子组件:Left.vue和Right.vue,第三级自组件中导入第四级子组件:Right1.vue、Right2.vue、Right3.vue
所以我们只需要在App.vue、Left.vue和Right.vue和Right1.vue、Right2.vue、Right3.vue中写代码就好了。
App.vue:
<template>
<div id="app">
<!--父组件监听change-->
<left class="left" @change="change"></left>
<!--用tag通知子组件,向下传值-->
<right class="right" v-bind:tag="tag"></right>
</div>
</template>
<script>
//导入
import Left from './components/Left'
import Right from './components/Right'
export default {
name: 'App',
components: {
//注册
Left,
Right
},
data() {
return {
tag: 0
}
},
methods: {
change: function (parm) {
//tag是随着点击的变化而变化
this.tag = parm
}
}
}
</script>
<style>
.left {
float: left;
width: 100px;
height: 400px;
padding: 20px;
border: 1px solid silver;
margin: 30px 0px 0px 30px;
}
.right {
float: left;
width: 700px;
height: 500px;
border: 1px solid silver;
margin: 30px 0px 0px 30px;
}
</style>
Left.vue:
<template>
<div>
<!--左组件有个click方法,点击后右组件就能跳转到对应的页面-->
<!--应当怎么实现呢?左组件和右组件是同级关系,没法直接实现-->
<!--先让左组件向上传值给父组件,再让父组件向下传值给右组件-->
<div class="left-div" @click="click1(1)">首页</div>
<div class="left-div" @click="click1(2)">百度</div>
<div class="left-div" @click="click1(3)">淘宝</div>
</div>
</template>
<!--现在我们想实现css中Homework1的页面,左边链接,右边能显示百度和淘宝首页的功能-->
<script>
export default {
name: "Left",
methods: {
click1: function (parm) {
this.$emit('change', parm)
}
}
}
</script>
<style scoped>
.left-div {
height: 30px;
line-height: 30px;
border-bottom: 1px solid silver;
}
</style>
Right.vue:
<template>
<!--这是最顶端的div-->
<div>
<!--将Right又细分成了3个子组件Right1、Right2、Right3-->
<Right1 v-if="tag==1" class="right-div"></Right1>
<!--class="right-div"的div占据父div的100%,class="iframe1"的iframe占据class="right-div"的div的100%-->
<Right2 v-else-if="tag==2" class="right-div"></Right2>
<Right3 v-else="tag==3" class="right-div"></Right3>
</div>
</template>
<script>
import Right1 from './Right/Right1'
import Right2 from './Right/Right2'
import Right3 from './Right/Right3'
export default {
name: "Right",
props: ['tag'],
components: {
Right1,
Right2,
Right3
}
}
</script>
<style scoped>
.right-div {
width: 100%;
height: 100%;
background: aqua;
}
</style>
Right1.vue:
<template>
<div>
首页
</div>
</template>
<script>
export default {
name: "Right1"
}
</script>
<style scoped>
</style>
Right2.vue:
<template>
<div>
<iframe class="iframe1" src="https://baidu.com"></iframe>
</div>
</template>
<script>
export default {
name: "Right2"
}
</script>
<style scoped>
.iframe1 {
width: 100%;
height: 100%;
}
</style>
Right3.vue:
<template>
<div>
<iframe class="iframe1" src="https://taobao.com"></iframe>
</div>
</template>
<script>
export default {
name: "Right3"
}
</script>
<style scoped>
.iframe1 {
width: 100%;
height: 100%;
}
</style>
注:不能这样打开刚刚写的项目
之前能这样打开是因为我们创建的是一个java项目,只不过在java项目里写了一些html代码。
现在IDEA对Vue项目来说只是充当了一个编辑器的作用,就像Notepad++似的。
刚刚的项目主要讲了两个问题:
1.组件嵌套
2.Left和right组件之间的交互(组件间传值)
版本2:
试想一下,如果嵌套层次较深,就要多级传值,可以实现,但是牵连的对象太多,万一哪一步出错,就完犊子了。
所以,直接交互(父子之间交互)的话可以用组价间传值,非直接交互就用中央总线事务。
1.8中央总线事务
Vuex: 主要用来存储数据
总线: 计算机硬件上的一个词汇(计算机硬件包括cpu 内存, 外存等 )
我们想让Vue对象也像这样,分布在一条“线”上,彼此之间可以相互交互。
这条“线”其实也是Vue对象,其他对象都可以与这个对象进行交互。
先有接收方: 监听动作
监听当然是,对象刚创建好就要监听,这就用到了生命周期函数。
再有触发方: 触发的动作
Bus: 公交车
就像我们坐公交车,当然是先知道去哪,再坐公交车。
版本3:
我们在Left.vue和Right.vue中都导入了bus目录下的index.js,即:
import Bus from “…/bus”
试想一下,如果总线上有很多对象,那每个对象都要:import Bus from "…/bus"么?
为了避免这样做,有了版本3:
Vue对象、包、插件的使用流程:
分三步: 导入到项目
1, 下包(导包), 导入文件,
2, 在项目中配置,引入到项目
3, 使用
落实到我们版本3的项目中,就是这三步:
1.创建bus目录下的index.js文件
2.在main.js中导入index.js
3.使用
开发模式(dev)启动时访问
Package.json -> dev
–host 0.0.0.0,
即把dev属性改成这样:
“dev”: “webpack-dev-server --host 0.0.0.0 --inline --progress --config build/webpack.dev.conf.js”,
我把我的ip告诉你,你访问我的ip+8080端口号依然访问不到,两个原因:
1.我的ip地址不是公网ip
2.即使是公网ip,我是开发模式启动,你依然无法访问
如果想让别人访问,我还是公网ip,就加个–host 0.0.0.0就成
还有一种情况,另一台电脑和你在一个局域网,那你加个–host 0.0.0.0,另一台电脑就可访问你,浏览器输入http://192.168.xxx.xxx:8080/。
1.9Json 是一种数据格式: 用来传输数据 可以查看一下Vue3项目下的package.json文件: { }外面是一个json对象,里面是键值对
{
"name": "vue3",
"version": "1.0.0",
"description": "A Vue.js project",
"author": "liushihao <2592693386@qq.com>",
"private": true,
"scripts": {
"dev": "webpack-dev-server --host 0.0.0.0 --inline --progress --config build/webpack.dev.conf.js",
"start": "npm run dev",
"build": "node build/build.js"
},
"dependencies": {
"vue": "^2.5.2"
},
"devDependencies": {
"autoprefixer": "^7.1.2",
"babel-core": "^6.22.1",
"babel-helper-vue-jsx-merge-props": "^2.0.3",
"babel-loader": "^7.1.1",
"babel-plugin-syntax-jsx": "^6.18.0",
"babel-plugin-transform-runtime": "^6.22.0",
"babel-plugin-transform-vue-jsx": "^3.5.0",
"babel-preset-env": "^1.3.2",
"babel-preset-stage-2": "^6.22.0",
"chalk": "^2.0.1",
"copy-webpack-plugin": "^4.0.1",
"css-loader": "^0.28.0",
"extract-text-webpack-plugin": "^3.0.0",
"file-loader": "^1.1.4",
"friendly-errors-webpack-plugin": "^1.6.1",
"html-webpack-plugin": "^2.30.1",
"node-notifier": "^5.1.2",
"optimize-css-assets-webpack-plugin": "^3.2.0",
"ora": "^1.2.0",
"portfinder": "^1.0.13",
"postcss-import": "^11.0.0",
"postcss-loader": "^2.0.8",
"postcss-url": "^7.2.1",
"rimraf": "^2.6.0",
"semver": "^5.3.0",
"shelljs": "^0.7.6",
"uglifyjs-webpack-plugin": "^1.1.1",
"url-loader": "^0.5.8",
"vue-loader": "^13.3.0",
"vue-style-loader": "^3.0.1",
"vue-template-compiler": "^2.5.2",
"webpack": "^3.6.0",
"webpack-bundle-analyzer": "^2.9.0",
"webpack-dev-server": "^2.9.1",
"webpack-merge": "^4.1.0"
},
"engines": {
"node": ">= 6.0.0",
"npm": ">= 3.0.0"
},
"browserslist": [
"> 1%",
"last 2 versions",
"not ie <= 8"
]
}
Xml: 也用来数据传输
越来越多的公司用json传输数据,而不用xml
版本4:
加入Json这种数据格式,来看一下效果:
//啥时候从后台取数据来着?Vue对象创建或挂载的时候
//获取json数据,拿来直接用,java可以利用jar包对Jason数据做一个转换,转化成java对象
//你就能拿来操作
//这就是前后端分离那幅图中的两个过程:
//1.浏览器向后端服务器发送请求
//2.后端服务器返回数据给浏览器
什么是json
JSON 指的是 JavaScript 对象表示法(JavaScript Object Notation)
JSON 是轻量级的文本数据交换格式
JSON 独立于语言
JSON 具有自我描述性,更易理解
JSON 使用 JavaScript 语法来描述数据对象,但是 JSON 仍然独立于语言和平台。JSON 解析器和 JSON 库支持许多不同的编程语言。
回忆一下网络三要素: 1.Html,用来描述资源 2.http(协议),用来确定资源的传输方式 3.Url,用来指示资源
HTTP协议(HyperText Transfer Protocol,超文本传输协议)是因特网上应用最为广泛的一种网络传输协议,所有的WWW文件都必须遵守这个标准。
HTTP是一个基于TCP/IP通信协议来传递数据(HTML 文件, 图片文件, 查询结果等)。
用json来承载数据,传输数据的方式是http协议
1.10接口文档
提供一个文档: 描述一个接口
接口:
url: 协议部分、IP地址+端口号部分、第三部分是主机资源的具体地址。如目录和文件名等。: 是给服务器看的。
第三部分必须匹配接口,才能进入服务器,进行访问。
前端和后端交互,主要就是利用接口
1.11Axios包 我们现在还不知道如何从后台获取数据。 Axios包就可以帮助我们实现第二次请求:浏览器向后端服务器请求数据。
Vue对象、包、插件(轮子)的使用流程:
分三步: 导入到项目
1, 下包(导包), 导入文件,
2, 在项目中配置,引入到项目
3, 使用
1.装包: cnpm install axios --save
–save:将保存配置信息到pacjage.json。默认为dependencies节点中。
–dev:将保存配置信息devDependencies节点中。
因此:
–save:将保存配置信息到pacjage.json的dependencies节点中。
–save-dev:将保存配置信息到pacjage.json的devDependencies节点中。
dependencies:运行时的依赖,发布后,即生产环境下还需要用的模块
devDependencies:开发时的依赖。里面的模块是开发时用的,发布时用不到它。
2.导入: 引入到项目中去:
在main.js文件中:
import axios from ‘axios’
Vue.prototype.$axios = axios
3.使用
//对象创建完之后,向后端发送请求,请求数据。
created() {
var _this = this
//发送一个get请求,请求java后台传数据
//then表示请求成功返回一个东西,把res.data.data返回给obj
//catch表示如果请求不成功
this.$axios.get('http://115.29.141.32:8084/api/mall/getGoodsByType?typeId=-1')
.then(res => {
console.log(res)
//不能用this,因为this现在指代的是这个方法
//res.data返回的是一个axios封装的返回值
//我们实际封装的返回值在res.data.data里
_this.obj = res.data.data
})
.catch(error => {
console.log(error)
})
}
2补充
2.1前端
学会用轮子:
前端: 组件化的天下
版本5
2.2Element-ui
接下来我们进入element-ui这个网站:
https://element.eleme.cn/#/zh-CN/component/installation
npm i element-ui -S
其实就相当于:
Cnpm install element-ui --save
如何使用?依然是安装轮子的三步,我们用版本5做演示
1.创建好项目vue5之后,cmd命令行输入:Cnpm install element-ui --save,下载包
2.导包
在main.js中输入这几行代码:
import ElementUI from ‘element-ui’;
import ‘element-ui/lib/theme-chalk/index.css’;
Vue.use(ElementUI);
3.使用。
我们在Element-ui这个网站上找一个现成的代码,放到App.vue中。
npm run dev
https://iview.github.io/docs/guide/introduce
这是另一个ui网站
2.3Iconfont
阿里矢量图库 :https://www.iconfont.cn/home/index
矢量图:放大后不会走形的图
3作业
4重点
前后端分离的项目一个页面是怎么产生的
结合axios
想明白
5网址
http://115.29.141.32:8085/#/mall/show/index
https://iview.github.io/
https://www.iconfont.cn/
http://www.googlefonts.cn/
https://v-charts.js.org/#/funnel
https://element.eleme.cn/#/zh-CN/component/layout