新建个项目myPro,进入项目
执行npm相关命令,获取包
npm init //根目录下生成了package.json文件
npm install webpack --save-dev
npm install vue --save
npm install webpack-dev-server --save-dev
npm install babel-loader --save-dev
npm install babel-core --save-dev
npm install vue-loader --save-dev
npm install vue-template-compiler --save-dev
npm install css-loader --save-dev
npm install babel-runtime --save-dev
package.json
{
"name": "myPro",
"version": "1.0.0",
"description": "学习vue",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack", //会调用webpack.config.js文件,执行相关功能,如编译,执行npm run build
"server": "webpack-dev-server --hot --inline" //本地开发上,搭建个服务,执行npm run server
},
"keywords": [
"vue"
],
"author": "author",
"license": "ISC",
"devDependencies": {
"babel-core": "^6.26.0",
"babel-loader": "^7.1.2",
"babel-runtime": "^6.26.0",
"css-loader": "^0.28.8",
"vue-loader": "^13.7.0",
"vue-template-compiler": "^2.5.13",
"webpack": "^3.10.0",
"webpack-dev-server": "^2.10.0"
},
"dependencies": {
"vue": "^2.5.13",
"vue-resource": "^1.3.5",
"vue-router": "^3.0.1"
}
}
新建个webpack.config.js文件:
module.exports = {
entry:__dirname+'/src/main.js',
output:{
path:__dirname+"/build",
filename:"main.js"
},
devServer: {
contentBase: __dirname, //__dirname获取当前目录(根目录),在当前目录下找index.html,在浏览器打开
historyApiFallback: true,
inline: true,
progress:true,
hot:true
},
module:{
rules:[{
test: /(\.jsx|\.js)$/,
use: {
loader: "babel-loader",
},
exclude: /node_modules/
},{
test:/\.vue$/,
use:{
loader:'vue-loader'
},
exclude:/node_modules/
}]
},
resolve: {
alias: { 'vue': 'vue/dist/vue.js' }
}
}
项目目录结构
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no, minimal-ui">
<meta name="screen-orientation" content="portrait"/>
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="format-detection" content="telephone=no">
<meta name="full-screen" content="yes">
<meta name="x5-fullscreen" content="true">
<title>VUE</title>
<script src="node_modules\vue\dist\vue.min.js"></script>
</head>
<body>
<div id="app">
<app></app>
</div>
<script type="text/javascript" src="build/main.js"></script>
<body>
</html>
main.js(编译前的)
import Vue from 'vue'
import App from './App.vue'
var vue = new Vue({
el:"#app",
components:{
"app":App
}
});
App.vue组件
<template>
<div>
<div id="top">
{{form}}
</div>
<div id="pageContent">
{{response}}
<br/>
<!--
fromapp属性可以通过在子组件的props注册后,即可在子组件里使用
listen2为父组件自定义的事件,将listenFromPageContent在methods里定义个函数
-->
<page-content fromapp="hello" v-on:listen2="listenFromPageContent"></page-content>
</div>
<div id="bottom">
<span v-bind:style="[spancss]" @click="updateWho(1)">1</span>
<span v-bind:style="[spancss]" @click="updateWho(2)">2</span>
<span v-bind:style="[spancss]" @click="updateWho(3)">3</span>
<span v-bind:style="[spancss]" @click="updateWho(4)">4</span>
</div>
</div>
</template>
<script>
import PageContent from './PageContent.vue' //导入子组件
export default {
data(){
return {
form:"myself",
spancss:{
backgroundColor:'red',
fontSize: '2rem',
},
response:""
}
},
methods:{
listenFromPageContent:function(msg){//获取子组件里返回的内容msg
this.response = msg; //response需要在data函数里注册,否则无法使用
},
updateWho:function(msg){
this.form = msg;
}
},
components:{
PageContent
}
}
</script>
<style>
#top{
position:fixed;
display:flex;
justify-content:center;
align-items:center;
top:0px;
left:0px;
height:10rem;
width:100%;
background-color:red;
}
#pageContent{
width:100%;
position:fixed;
top:10rem;
bottom:5rem;
}
#bottom{
position:fixed;
display:flex;
bottom:0px;
left:0px;
height:5rem;
width:100%;
background-color:blue;
}
#bottom>span{
margin:auto;
width:1.5rem;
}
</style>
PageContent.vue(App.vue引用的子组件)
<template>
<div>
{{fromapp}}
<br/>
<button v-on:click="responseApp()">Response App</button>
</div>
</template>
<script>
export default {
data(){
return {
form:"myself",
spancss:{
backgroundColor:'red',
fontSize: '2rem'
},
response:"Welcome to Look at me."
}
},
props:["fromapp"],// 注册,父组件里的值
methods:{
responseApp:function(){
console.log(this.response);
this.$emit("listen2",this.response);//子组件将数据传回给父组件里自定义的事件listen2
}
}
}
</script>
<style>
</style>
npm run build
$ npm run build
> mypro@1.0.0 build D:\workspace\javascript\vue\mypro
> webpack
Hash: 7d953487d0b16c3d63ad
Version: webpack 3.10.0
Time: 2588ms
Asset Size Chunks Chunk Names
main.js 327 kB 0 [emitted] [big] main
[0] (webpack)/buildin/global.js 509 bytes {0} [built]
[2] ./node_modules/babel-loader/lib!./node_modules/vue-loader/lib/selector.js?type=script&index=0!./src/App.vue 568 bytes {0} [built]
[3] ./node_modules/babel-loader/lib!./node_modules/vue-loader/lib/selector.js?type=script&index=0!./src/PageContent.vue 458 bytes {0} [built]
[4] ./src/main.js 135 bytes {0} [built]
[11] ./src/App.vue 1.8 kB {0} [built]
[12] ./node_modules/vue-style-loader!./node_modules/css-loader!./node_modules/vue-loader/lib/style-compiler?{"vue":true,"id":"data-v-04c2046b","scoped":false,"hasInlineConfig":false}!./node_modules/vue-loader/lib/selector.js?type=styles&index=0!./src/App.vue 1.54 kB {0} [built]
[13] ./node_modules/css-loader!./node_modules/vue-loader/lib/style-compiler?{"vue":true,"id":"data-v-04c2046b","scoped":false,"hasInlineConfig":false}!./node_modules/vue-loader/lib/selector.js?type=styles&index=0!./src/App.vue 652 bytes {0} [built]
[15] ./src/PageContent.vue 1.84 kB {0} [built]
[16] ./node_modules/vue-style-loader!./node_modules/css-loader!./node_modules/vue-loader/lib/style-compiler?{"vue":true,"id":"data-v-00a03298","scoped":false,"hasInlineConfig":false}!./node_modules/vue-loader/lib/selector.js?type=styles&index=0!./src/PageContent.vue 1.56 kB {0} [built]
[17] ./node_modules/css-loader!./node_modules/vue-loader/lib/style-compiler?{"vue":true,"id":"data-v-00a03298","scoped":false,"hasInlineConfig":false}!./node_modules/vue-loader/lib/selector.js?type=styles&index=0!./src/PageContent.vue 223 bytes {0} [built]
[18] ./node_modules/vue-loader/lib/template-compiler?{"id":"data-v-00a03298","hasScoped":false,"buble":{"transforms":{}}}!./node_modules/vue-loader/lib/selector.js?type=template&index=0!./src/PageContent.vue 693 bytes {0} [built]
[19] ./node_modules/vue-loader/lib/template-compiler?{"id":"data-v-04c2046b","hasScoped":false,"buble":{"transforms":{}}}!./node_modules/vue-loader/lib/selector.js?type=template&index=0!./src/App.vue 1.89 kB {0} [built]
+ 8 hidden modules
npm run server
$ npm run server
> myPro@1.0.0 server D:\workspace\javascript\vue\myPro
> webpack-dev-server --hot --inline
10% building modules 1/1 modules 0 active
Project is running at http://localhost:8080/
webpack output is served from /
Content not from webpack is served from D:\workspace\javascript\vue\myPro
404s will fallback to /index.html
Hash: 4661e38b73bd59bc1996
Version: webpack 3.10.0
Time: 2906ms
Asset Size Chunks Chunk Names
main.js 681 kB 0 [emitted] [big] main
[2] (webpack)/hot/log.js 1.04 kB {0} [built]
[5] ./node_modules/vue/dist/vue.js 285 kB {0} [built]
[6] (webpack)/hot/emitter.js 77 bytes {0} [built]
[13] multi (webpack)-dev-server/client?http://localhost:8080 webpack/hot/dev-server ./src/main.js 52 bytes {0} [built]
[14] (webpack)-dev-server/client?http://localhost:8080 7.63 kB {0} [built]
[15] ./node_modules/url/url.js 23.3 kB {0} [built]
[22] (webpack)-dev-server/node_modules/strip-ansi/index.js 150 bytes {0} [built]
[24] ./node_modules/loglevel/lib/loglevel.js 7.86 kB {0} [built]
[25] (webpack)-dev-server/client/socket.js 1.06 kB {0} [built]
[27] (webpack)-dev-server/client/overlay.js 3.69 kB {0} [built]
[32] (webpack)/hot nonrecursive ^\.\/log$ 170 bytes {0} [built]
[34] (webpack)/hot/dev-server.js 1.61 kB {0} [built]
[35] (webpack)/hot/log-apply-result.js 1.31 kB {0} [built]
[36] ./src/main.js 135 bytes {0} [built]
[40] ./src/App.vue 1.8 kB {0} [built]
+ 32 hidden modules
webpack: Compiled successfully.
页面效果
点击Response App 按钮和点下面任一数字
基于上一小实例,调整
项目目录结构
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no, minimal-ui">
<meta name="screen-orientation" content="portrait"/>
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="format-detection" content="telephone=no">
<meta name="full-screen" content="yes">
<meta name="x5-fullscreen" content="true">
<title>myPro</title>
</head>
<body>
<div id="app">
<router-view></router-view><!--最高级路由 -->
</div>
<script type="text/javascript" src="build/main.js"></script>
<body>
</html>
main.js
import Vue from 'vue'
import VueRouter from 'vue-router'
import routes from './routes'
Vue.use(VueRouter);
const router = new VueRouter({
routes
});
var vue = new Vue({
router
}).$mount("#app");
routes.js
import Vue from 'vue'
import App from './App.vue'
import home from './children/home.vue'
import one from './children/app_one.vue'
import two from './children/app_two.vue'
const routes = [{
path:"/",
component: App, //最高级路由对应的组件
children:[{
path:"",
component:home //嵌套路由对应的组件
},{
path:"1",
component:one
},{
path:"2",
component:two
},{
path:"3",
component:two
},{
path:"4",
component:two
}]
}];
export default routes;
App.vue
<template>
<div>
<div id="top">
{{form}}
</div>
<div id="pageContent">
<router-view></router-view><!-- 嵌套路由-->
</div>
<div id="bottom">
<span v-bind:style="[spancss]" @click="updateWho(1)"><router-link to="/1">1</router-link></span>
<span v-bind:style="[spancss]" @click="updateWho(2)"><router-link to="/2">2</router-link></span>
<span v-bind:style="[spancss]" @click="updateWho(3)"><router-link to="/3">3</router-link></span>
<span v-bind:style="[spancss]" @click="updateWho(4)"><router-link to="/4">4</router-link></span>
</div>
</div>
</template>
<script>
export default {
data(){
return {
form:"myself",
spancss:{
backgroundColor:'red',
fontSize: '2rem',
},
response:""
}
},
methods:{
updateWho:function(msg){
this.form = msg;
}
}
}
</script>
<style>
#top{
position:fixed;
display:flex;
justify-content:center;
align-items:center;
top:0px;
left:0px;
height:10rem;
width:100%;
background-color:red;
}
#pageContent{
width:100%;
position:fixed;
top:10rem;
bottom:5rem;
}
#bottom{
position:fixed;
display:flex;
bottom:0px;
left:0px;
height:5rem;
width:100%;
background-color:blue;
}
#bottom>span{
margin:auto;
width:1.5rem;
}
</style>
home.vue
<template>
<div>
Home
</div>
</template>
<script>
export default {
data(){
return {
form:"myself",
spancss:{
backgroundColor:'red',
fontSize: '2rem'
},
response:"Welcome to Look at me."
}
},
methods:{
responseApp:function(){
}
}
}
</script>
<style scoped>
div{
display:flex;
justify-content:center;
align-items:center;
}
</style>
app_one.vue(其他app的子组件可以参考这个模拟实现,省略)
<template>
<div>
<button v-on:click="responseApp()">Response App</button>
</div>
</template>
<script>
export default {
data(){
return {
form:"myself",
spancss:{
backgroundColor:'red',
fontSize: '2rem'
},
response:"Welcome to Look at me."
}
},
methods:{
responseApp:function(){
alert(this.response);
}
}
}
</script>
<style>
</style>
页面效果
点击下面数字1