1.搭建vue的开发环境
1、搭建vue的开发环境 ,安装vue的脚手架工具 官方命令行工具
npm install --global vue-cli / cnpm install --global vue-cli
2、创建项目的两种方式(前提是安装了node.js)
第一种方式:创建项目 必须 cd到对应的一个项目里面
vue init webpack vue-demo01 cd vue-demo01 cnpm install / npm install npm run dev
第二种方法:创建项目 (推荐使用)(轻量型)
vue init webpack-simple vuedemo02 cd vuedemo02 cnpm install / npm install // 安装依赖 npm run dev // 运行项目
2.VUE基础知识
1.数据绑定、对象绑定、循环数组的渲染
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <template> 2 <!-- vue的模板里面 所有的内容要被一个根节点包含起来 --> 3 <div id="app"> 4 <!-- 双向数据绑定 --> 5 <h2>{{msg}}</h2> 6 <!-- 对象绑定 --> 7 <h3>{{obj.name}}</h3> 8 <!-- 循环数组渲染 --> 9 <ul> 10 <li v-for="item in list"> 11 {{item}} 12 </li> 13 </ul> 14 <ul> 15 <li v-for="item in list1"> 16 {{item.title}} 17 </li> 18 </ul> 19 <!-- 双重循环数组渲染 --> 20 <ul> 21 <li v-for="item in list2"> 22 {{item.cate}} 23 <ol> 24 <li v-for="news in item.list"> 25 {{news.title}} 26 </li> 27 </ol> 28 29 </li> 30 </ul> 31 </div> 32 </template> 33 34 <script> 35 export default { 36 data () { /*业务逻辑里面定义的数据*/ 37 return { 38 msg: '你好vue', 39 obj:{ 40 name:"张三" 41 }, 42 list:['111','222','333'], 43 list1:[ 44 {'title':'11111'}, 45 {'title':'222'}, 46 {'title':'333333'}, 47 {'title':'44444'} 48 ], 49 list2:[ 50 { 51 "cate":"国内新闻", 52 "list":[ 53 54 {'title':'国内新闻11111'}, 55 {'title':'国内新闻2222'} 56 ] 57 }, 58 { 59 "cate":"国际新闻", 60 "list":[ 61 62 {'title':'国际新闻11111'}, 63 {'title':'国际新闻2222'} 64 ] 65 } 66 ] 67 } 68 } 69 } 70 </script> 71 72 <style lang="scss"> 73 74 75 </style>
2.v-bind、v-html、v-for、v-text绑定属性
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <template> 2 <div id="app"> 3 <h2>{{msg}}</h2> 4 <br> 5 <div v-bind:title="title">鼠标瞄上去看一下</div> 6 <img src="https://www.itying.com/themes/itying/images/logo.gif" /> 7 <!-- 绑定属性 --> 8 <img v-bind:src="url" /> 9 <img :src="url" /> 10 {{h}} 11 <!-- 绑定html --> 12 <div v-html="h"> 13 </div> 14 <!-- 绑定数据的另一种方法 --> 15 <div v-text="msg"> 16 </div> 17 <!-- v-bind:class :class的使用 --> 18 <div v-bind:class="{'red':flag}"> 19 我是一个div 20 </div> 21 <div :class="{'red':flag,'blue':!flag}"> 22 我是另一个div 23 </div> 24 <!-- 循环数据 第一个数据高量 --> 25 <ul> 26 <li v-for="(item,key) in list"> 27 {{key}}---{{item}} 28 </li> 29 </ul> 30 <ul> 31 <li v-for="(item,key) in list" :class="{'red':key==0,'blue':key==1}"> 32 {{key}}---{{item}} 33 </li> 34 </ul> 35 <!-- v-bind:style :style的使用 --> 36 <div class="box" v-bind:style="{'width':boxWdith+'px'}"> 37 我是另一个div 38 </div> 39 </div> 40 </template> 41 <script> 42 export default { 43 data () { /*业务逻辑里面定义的数据*/ 44 return { 45 msg: '你好vue', 46 title:'我是一个title', 47 url:'https://www.itying.com/themes/itying/images/logo.gif', 48 h:'<h2>我是h2</h2>', 49 list:['1111','2222','3333'], 50 flag:false, 51 boxWdith:500 52 } 53 } 54 } 55 </script> 56 <style lang="scss"> 57 .red{ 58 color: red; 59 } 60 .blue{ 61 color:blue; 62 } 63 .box{ 64 height: 100px; 65 width: 100px; 66 background: red; 67 } 68 </style>
3.VUE双向数据绑定、事件以及ref获取dom节点
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <template> 2 <div id="app"> 3 <h2>{{msg}}</h2> 4 <input type="text" v-model='msg' /> 5 <button v-on:click="getMsg()">获取表单里面的数据get</button> 6 <button v-on:click="setMsg()">设置表单的数据set</button> 7 <input type="text" ref="userinfo" /> 8 <div ref="box">我是一个box</div> 9 <button v-on:click="getInputValue()">获取第二个表单里面的数据</button> 10 </div> 11 </template> 12 <script> 13 /* 14 双向数据绑定 MVVM vue就是一个MVVM的框架。 15 M model 16 V view 17 MVVM: model改变会影响视图view,view视图改变反过来影响model 18 双向数据绑定必须在表单里面使用。 19 */ 20 export default { 21 data () { /*业务逻辑里面定义的数据*/ 22 return { 23 msg: '你好vue' 24 } 25 },methods:{ /*放方法的地方*/ 26 getMsg(){ 27 // alert('vue方法执行了'); 28 //方法里面获取data里面的数据 29 alert(this.msg); 30 }, 31 setMsg(){ 32 this.msg="我是改变后的数据"; 33 }, 34 getInputValue(){ 35 //获取ref定义的dom节点 36 console.log(this.$refs.userinfo); 37 this.$refs.box.style.background='red'; 38 alert(this.$refs.userinfo.value); 39 } 40 } 41 } 42 </script> 43 <style lang="scss"> 44 45 </style>
4.方法定义与执行、数据获取与改变、方法传值、事件对象
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <template> 2 <div id="app"> 3 <!-- 4 <img v-bind:src='url' /> 5 <img :src='url' /> --> 6 {{msg}} 7 <button v-on:click="run1()">执行方法的第一种写法</button> 8 <button @click="run2()">执行方法的第二种写法</button> 9 <button @click="getMsg()">获取data里面的msg</button> 10 <button @click="setMsg()">改变data里面的msg</button> 11 <button @click="requestData()">请求数据</button> 12 <ul> 13 <li v-for="(item,key) in list"> 14 {{key}}--- {{item}} 15 </li> 16 </ul> 17 <button @click="deleteData('111')">执行方法传值111</button> 18 <button @click="deleteData('222')">执行方法传值2222</button> 19 <button data-aid='123' @click="eventFn($event)">事件对象</button> 20 </div> 21 </template> 22 <script> 23 export default { 24 data () { 25 return { 26 msg: '你好vue', 27 list:[] 28 } 29 }, 30 methods:{ 31 run1:function(){ 32 alert('这是一个方法'); 33 }, 34 run2(){ 35 alert('这是另一个方法'); 36 }, 37 getMsg(){ 38 alert(this.msg); 39 }, 40 setMsg(){ 41 this.msg="我是改变后的数据"; 42 }, 43 requestData(){ 44 for(var i=0;i<10;i++){ 45 this.list.push('我是第'+i+'条数据'); 46 } 47 }, 48 deleteData(val){ 49 alert(val); 50 }, 51 eventFn(e){ 52 console.log(e); 53 // e.srcElement dom节点 54 e.srcElement.style.background='red'; 55 console.log(e.srcElement.dataset.aid); /*获取自定义属性的值*/ 56 } 57 } 58 } 59 </script> 60 <style lang="scss"> 61 62 </style>
5.todoList的实现以及storage的封装
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <template> 2 <div id="app"> 3 <input type="text" v-model='todo' @keydown="doAdd($event)" /> 4 <h2>进行中</h2> 5 <ul> 6 <li v-for="(item,key) in list" v-if="!item.checked"> 7 <input type="checkbox" v-model="item.checked" @change="saveList()" /> {{item.title}} -- <button @click="removeData(key)">删除</button> 8 </li> 9 </ul> 10 <h2>已完成</h2> 11 <ul> 12 <li v-for="(item,key) in list" v-if="item.checked"> 13 <input type="checkbox" v-model="item.checked" @change="saveList()" /> {{item.title}} -- <button @click="removeData(key)">删除</button> 14 </li> 15 </ul> 16 </div> 17 </template> 18 <script> 19 import storage from './model/storage.js'; 20 // console.log(storage); 21 export default { 22 data () { 23 return { 24 25 todo:'' , 26 list: [] 27 } 28 }, 29 methods:{ 30 doAdd(e){ 31 // console.log(e); 32 if(e.keyCode==13){ 33 this.list.push({ 34 title:this.todo, 35 checked:false 36 }) 37 } 38 storage.set('list',this.list); 39 }, 40 removeData(key){ 41 this.list.splice(key,1) 42 storage.set('list',this.list); 43 } 44 , saveList(){ 45 storage.set('list',this.list); 46 } 47 },mounted(){ /*生命周期函数 vue页面刷新就会触发的方法* 48 var list=storage.get('list'); 49 if(list){ /*注意判断*/ 50 this.list=list; 51 } 52 } 53 </script> 54 <style lang="scss"> 55 .finish{ 56 li{ 57 background:#eee; 58 } 59 } 60 </style>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 //封装操作localstorage本地存储的方法 模块化的文件 2 var storage={ 3 set(key,value){ 4 localStorage.setItem(key, JSON.stringify(value)); 5 }, 6 get(key){ 7 return JSON.parse(localStorage.getItem(key)); 8 },remove(key){ 9 localStorage.removeItem(key); 10 } 11 } 12 export default storage;
6.组件的创建及使用
步骤:(1)创建组件文件;(2)引入组件;(3)挂载组件;(4)在父模板中使用组件。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <template> 2 <div id="app"> 3 <v-home></v-home> 4 <v-news></v-news> 5 </div> 6 </template> 7 <script> 8 /* 9 1、引入组件 10 2、挂载组件 11 3、在模板中使用 12 */ 13 import Home from './components/Home.vue'; 14 import News from './components/News.vue'; 15 export default { 16 data () { 17 return { 18 msg:'你好vue' 19 } 20 }, 21 components:{ /*前面的组件名称不能和html标签一样*/ 22 'v-home':Home, 23 'v-news':News 24 } 25 } 26 </script> 27 <style lang="scss"> 28 29 </style>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <template> 2 <div> 3 <h2 class="header">这是一个头部组件</h2> 4 </div> 5 </template> 6 <script> 7 export default { 8 data(){ 9 return{ 10 msg:'这是一个头部组件' 11 } 12 } 13 }; 14 </script> 15 <style lang="scss"> 16 .header{ 17 background:#000; 18 color:#fff; 19 } 20 </style>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <template> 2 <!-- 所有的内容要被根节点包含起来 --> 3 <div id="home"> 4 <v-header></v-header> 5 <h2>这是一个首页组件--{{msg}}</h2> 6 <button @click="run()">执行run方法</button> 7 </div> 8 </template> 9 <script> 10 //引入头部组件 11 import Header from './Header.vue'; 12 export default{ 13 data(){ 14 return { 15 msg:'我是一个首页组件msg' 16 } 17 }, 18 methods:{ 19 run(){ 20 alert(this.msg); 21 } 22 }, 23 components:{ 24 'v-header':Header 25 } 26 } 27 </script> 28 <style lang="scss" scoped> 29 /*css 局部作用域 scoped*/ 30 h2{ 31 color:red 32 } 33 </style>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <template> 2 <div> 3 <v-header></v-header> 4 <h2>这是一个新闻组件</h2> 5 <ul> 6 <li > 7 111111 8 </li> 9 <li> 10 2222 11 </li> 12 <li> 13 333333 14 </li> 15 </ul> 16 </div> 17 </template> 18 <script> 19 //引入头部组件 20 import Header from './Header.vue'; 21 export default { 22 data(){ 23 return{ 24 msg:'我是一个新闻组件' 25 } 26 },components:{ 27 'v-header':Header 28 } 29 }; 30 </script> 31 <style lang="scss"> 32 33 </style>
7.组件的生命周期函数
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <template> 2 <!-- 所有的内容要被根节点包含起来 --> 3 <div id="life"> 4 生命周期函数的演示 ---{{msg}} 5 <br> 6 <button @click="setMsg()">执行方法改变msg</button> 7 </div> 8 </template> 9 <script> 10 /* 11 生命周期函数/生命周期钩子: 12 组件挂载、以及组件更新、组件销毁、的时候触发的一系列的方法 这些方法就叫做生命周期函数 13 */ 14 export default{ 15 data(){ 16 return{ 17 msg:'msg' 18 } 19 }, 20 methods:{ 21 setMsg(){ 22 this.msg="我是改变后的数据" 23 } 24 }, 25 beforeCreate(){ 26 console.log('实例刚刚被创建1'); 27 }, 28 created(){ 29 console.log('实例已经创建完成2'); 30 }, 31 beforeMount(){ 32 console.log('模板编译之前3'); 33 }, 34 mounted(){ /*请求数据,操作dom , 放在这个里面 mounted*/ 35 console.log('模板编译完成4'); 36 }, 37 beforeUpdate(){ 38 console.log('数据更新之前'); 39 }, 40 updated(){ 41 console.log('数据更新完毕'); 42 }, 43 beforeDestroy(){ /*页面销毁的时候要保存一些数据,就可以监听这个销毁的生命周期函数*/ 44 console.log('实例销毁之前'); 45 }, 46 destroyed(){ 47 console.log('实例销毁完成'); 48 } 49 } 50 </script>
8.请求数据
请求数据的模板有3种:(1) vue-resource;(2)axios;(3)fetch-jsonp。
、 (1)vue-resource请求数据
步骤:1、需要安装vue-resource模块, 注意加上 --save
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 import Vue from 'vue'; 2 import App from './App.vue'; 3 /*使用vue-resource请求数据的步骤 4 1、需要安装vue-resource模块, 注意加上 --save 5 npm install vue-resource --save / cnpm install vue-resource --save 6 2、main.js引入 vue-resource 7 import VueResource from 'vue-resource'; 8 3、main.js Vue.use(VueResource); 9 4、在组件里面直接使用 10 this.$http.get(地址).then(function(){ 11 }) 12 */ 13 import VueResource from 'vue-resource'; 14 Vue.use(VueResource); 15 new Vue({ 16 el: '#app', 17 render: h => h(App) 18 })
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <template> 2 <div id="app"> 3 <v-home></v-home> 4 </div> 5 </template> 6 <script> 7 import Home from './components/Home.vue'; 8 export default { 9 data () { 10 return { 11 msg:'你好vue' 12 } 13 }, 14 components:{ /*前面的组件名称不能和html标签一样*/ 15 'v-home':Home, 16 } 17 } 18 </script> 19 <style lang="scss"> 20 21 </style>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <template> 2 <!-- 所有的内容要被根节点包含起来 --> 3 <div id="home"> 4 首页组件 5 <button @click="getData()">请求数据</button> 6 <ul> 7 <li v-for="item in list"> 8 {{item.title}} 9 </li> 10 </ul> 11 </div> 12 </template> 13 <script> 14 /* 15 请求数据的模板 16 vue-resource 官方提供的 vue的一个插件 17 axios 18 fetch-jsonp 19 */ 20 export default{ 21 data(){ 22 return { 23 24 msg:'我是一个首页组件msg', 25 flag:true, 26 list:[] 27 } 28 }, 29 methods:{ 30 getData(){ 31 //请求数据 32 var api='http://www.phonegap100.com/appapi.php?a=getPortalList&catid=20&page=1'; 33 this.$http.get(api).then((response)=>{ 34 console.log(response); 35 //注意this指向 36 this.list=response.body.result; 37 },function(err){ 38 console.log(err); 39 }) 40 } 41 }, 42 mounted(){ /*生命周期函数*/ 43 this.getData(); 44 } 45 } 46 </script> 47 <style lang="scss" scoped> 48 /*css 局部作用域 scoped*/ 49 h2{ 50 color:red 51 } 52 </style>
(2)axios请求数据
步骤:1、安装axios
cnpm install axios --save
2、哪里用哪里引入axios
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <template> 2 <div id="app"> 3 <v-home></v-home> 4 </div> 5 </template> 6 <script> 7 import Home from './components/Home.vue'; 8 export default { 9 data () { 10 return { 11 msg:'你好vue' 12 } 13 }, 14 components:{ /*前面的组件名称不能和html标签一样*/ 15 'v-home':Home, 16 } 17 } 18 </script> 19 <style lang="scss"> 20 </style>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <template> 2 <!-- 所有的内容要被根节点包含起来 --> 3 <div id="home"> 4 首页组件 5 <button @click="getData()">请求数据</button> 6 <ul> 7 <li v-for="item in list"> 8 {{item.title}} 9 </li> 10 </ul> 11 </div> 12 </template> 13 <script> 14 /* 15 请求数据的模板 16 axios 的使用 17 1、安装 cnpm install axios --save 18 2、哪里用哪里引入axios 19 */ 20 import Axios from 'axios'; 21 export default{ 22 data(){ 23 return { 24 list:[] 25 } 26 }, 27 methods:{ 28 getData(){ 29 var api='http://www.phonegap100.com/appapi.php?a=getPortalList&catid=20&page=1'; 30 Axios.get(api).then((response)=>{ 31 this.list=response.data.result; 32 }).catch((error)=>{ 33 console.log(error); 34 }) 35 } 36 }, 37 mounted(){ /*生命周期函数*/ 38 this.getData(); 39 } 40 } 41 </script> 42 <style lang="scss" scoped> 43 /*css 局部作用域 scoped*/ 44 h2{ 45 color:red 46 } 47 </style>
(3)fetch-jsonp省略。
9.父组件向子组件传值
步骤:(1)父组件调用子组件的时候,绑定动态属性
<v-header :title="title"></v-header>
(2)在子组件里面通过props接受父组件传过来的数据
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <template> 2 <!-- 所有的内容要被根节点包含起来 --> 3 <div id="home"> 4 <v-header :title="title"></v-header> 5 首页组件 6 </div> 7 </template> 8 <script> 9 /* 10 父组件给子组件传值 11 1.父组件调用子组件的时候 绑定动态属性 12 <v-header :title="title"></v-header> 13 2、在子组件里面通过 props接收父组件传过来的数据 14 */ 15 import Header from './Header.vue'; 16 export default{ 17 data(){ 18 return { 19 msg:'我是一个home组件', 20 title:'首页111' 21 } 22 }, 23 components:{ 24 'v-header':Header 25 }, 26 methods:{ 27 run(data){ 28 alert('我是Home组件的run方法'+data); 29 } 30 } 31 } 32 </script> 33 <style lang="scss" scoped> 34 /*css 局部作用域 scoped*/ 35 h2{ 36 color:red 37 } 38 39 </style>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <template> 2 <div> 3 <h2>我是头部组件--{{title}}</h2> 4 </div> 5 </template> 6 <script> 7 export default{ 8 data(){ 9 return{ 10 msg:'子组件的msg' 11 } 12 }, 13 methods:{ 14 }, 15 //https://cn.vuejs.org/v2/guide/components.html#Prop-验证 16 props:{ 17 'title':String 18 } 19 } 20 </script>
10.父、子组件互相获取对方的数据和方法(广播的方式)
(1)父组件主动获取子组件的数据和方法:
步骤:a、调用子组件的时候定义一个ref
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <template> 2 <!-- 所有的内容要被根节点包含起来 --> 3 <div id="home"> 4 <v-header ref="header"></v-header> 5 首页组件 6 <button @click="getChildData()">获取子组件的数据和方法</button> 7 </div> 8 </template> 9 <script> 10 /* 11 父组件给子组件传值 12 1.父组件调用子组件的时候 绑定动态属性 13 <v-header :title="title"></v-header> 14 2、在子组件里面通过 props接收父组件传过来的数据 15 props:['title'] 16 props:{ 17 'title':String 18 } 19 3.直接在子组件里面使用 20 父组件主动获取子组件的数据和方法: 21 1.调用子组件的时候定义一个ref 22 <v-header ref="header"></v-header> 23 2.在父组件里面通过 24 this.$refs.header.属性 25 this.$refs.header.方法 26 子组件主动获取父组件的数据和方法: 27 this.$parent.数据 28 this.$parent.方法 29 */ 30 import Header from './Header.vue'; 31 export default{ 32 data(){ 33 return { 34 msg:'我是一个home组件', 35 title:'首页111' 36 } 37 }, 38 components:{ 39 'v-header':Header 40 }, 41 methods:{ 42 run(){ 43 alert('我是Home组件的run方法'); 44 }, 45 getChildData(){ 46 //父组件主动获取子组件的数据和方法: 47 // alert(this.$refs.header.msg); 48 this.$refs.header.run(); 49 } 50 } 51 } 52 </script> 53 <style lang="scss" scoped> 54 /*css 局部作用域 scoped*/ 55 h2{ 56 color:red 57 } 58 </style>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <template> 2 <div> 3 <h2>我是头部组件</h2> 4 <button @click="getParentData()">获取父组件的数据和方法</button> 5 </div> 6 </template> 7 <script> 8 export default{ 9 data(){ 10 return{ 11 msg:'子组件的msg' 12 } 13 }, 14 methods:{ 15 run(){ 16 alert('我是子组件的run方法') 17 }, 18 getParentData(){ 19 /* 20 子组件主动获取父组件的数据和方法: 21 this.$parent.数据 22 this.$parent.方法 23 */ 24 alert(this.$parent.msg); 25 this.$parent.run(); 26 } 27 } 28 } 29 </script>
11、非父子组件传值
步骤:(1)新建一个js文件,然后引入vue 实例化vue,最后暴露这个实例
(2)在要广播的地方引入刚才定义的实例
(3)通过VueEmit.$emit('名称','数据')
(4)在接收收数据的地方通过 $om接收广播的数据
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 import Vue from 'vue'; 2 var VueEvent = new Vue() 3 export default VueEvent;
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <template> 2 <div id="app"> 3 <v-home></v-home> 4 <v-news></v-news> 5 </div> 6 </template> 7 <script> 8 /*非父子组件传值 9 1、新建一个js文件 然后引入vue 实例化vue 最后暴露这个实例 10 2、在要广播的地方引入刚才定义的实例 11 3、通过 VueEmit.$emit('名称','数据') 12 4、在接收收数据的地方通过 $om接收广播的数据 13 VueEmit.$on('名称',function(){ 14 }) 15 */ 16 import Home from './components/Home.vue'; 17 import News from './components/News.vue'; 18 export default { 19 data () { 20 return { 21 msg:'你好vue' 22 } 23 }, 24 components:{ /*前面的组件名称不能和html标签一样*/ 25 'v-home':Home, 26 'v-news':News 27 } 28 } 29 </script> 30 <style lang="scss"> 31 32 </style>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <template> 2 <!-- 所有的内容要被根节点包含起来 --> 3 <div id="home"> 4 我是首页组件 5 <button @click="emitNews()">给News组件广播数据</button> 6 </div> 7 </template> 8 <script> 9 //引入 vue实例 10 import VueEvent from '../model/VueEvent.js'; 11 export default{ 12 data(){ 13 return { 14 msg:'我是一个home组件', 15 title:'首页111' 16 } 17 },methods:{ 18 emitNews(){ 19 //广播数据 20 VueEvent.$emit('to-news',this.msg) 21 } 22 }, 23 mounted(){ 24 //监听news 广播的数据 25 VueEvent.$on('to-home',function(data){ 26 console.log(data); 27 }) 28 } 29 } 30 </script> 31 <style lang="scss" scoped> 32 33 </style>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <template> 2 <div id="news"> 3 我是新闻组件 4 <button @click="emitHome()">给Home组件广播数据</button> 5 </div> 6 </template> 7 <script> 8 //引入 vue实例 9 import VueEvent from '../model/VueEvent.js'; 10 export default{ 11 data(){ 12 return { 13 msg:'我是一个新闻组件' 14 } 15 }, 16 methods:{ 17 emitHome(){ 18 //广播 19 VueEvent.$emit('to-home',this.msg) 20 } 21 }, 22 mounted(){ 23 VueEvent.$on('to-news',function(data){ 24 console.log(data); 25 }) 26 } 27 } 28 </script> 29 <style lang="scss" scoped> 30 31 </style>
3.VUE路由
1、安装
npm install vue-router --save / cnpm install vue-router --save
2、引入并 Vue.use(VueRouter) (main.js)
import VueRouter from 'vue-router'
Vue.use(VueRouter)
3、配置路由
(1)创建组价,引入组件
(2)定义路由(建议复制https://router.vuejs.org/)
const routes = [
{ path: '/foo', component: Foo },
{ path: '/bar', component: Bar },
{ path: '*', redirect: '/home' } /*默认跳转路由*/
]
(3)实例化VueRouter
const router = new VueRouter({
routes // (缩写)相当于 routes: routes
})
(4)挂载
new Vue({
el: '#app',
router,
render: h => h(App)
})
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 import Vue from 'vue'; 2 import App from './App.vue'; 3 import VueRouter from 'vue-router'; 4 Vue.use(VueRouter); 5 //1.创建组件 6 import Home from './components/Home.vue'; 7 import News from './components/News.vue'; 8 //2.配置路由 注意:名字 9 const routes = [ 10 { path: '/home', component: Home }, 11 { path: '/news', component: News }, 12 { path: '*', redirect: '/home' } /*默认跳转路由*/ 13 ] 14 //3.实例化VueRouter 注意:名字 15 const router = new VueRouter({ 16 routes // (缩写)相当于 routes: routes 17 }) 18 //4、挂载路由 19 new Vue({ 20 el: '#app', 21 router, 22 render: h => h(App) 23 }) 24 //5 <router-view></router-view> 放在 App.vue
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <template> 2 <div id="app"> 3 <router-link to="/home">首页</router-link> 4 <router-link to="/news">新闻</router-link> 5 <router-view></router-view> 6 </div> 7 </template> 8 <script> 9 export default { 10 data () { 11 return { 12 msg:'你好vue' 13 } 14 } 15 } 16 </script> 17 <style lang="scss"> 18 19 </style>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <template> 2 <!-- 所有的内容要被根节点包含起来 --> 3 <div id="home"> 4 我是首页组件 5 </div> 6 </template> 7 <script> 8 export default{ 9 data(){ 10 return { 11 msg:'我是一个home组件' 12 } 13 } 14 } 15 </script> 16 <style lang="scss" scoped> 17 18 </style>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <template> 2 <div id="news"> 3 我是新闻组件 4 </div> 5 </template> 6 <script> 7 export default{ 8 data(){ 9 return { 10 msg:'我是一个新闻组件' 11 } 12 } 13 } 14 </script> 15 <style lang="scss" scoped> 16 17 </style>
4.Vue动态路由,Get传值
(1)配置动态路由
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 import Vue from 'vue'; 2 import App from './App.vue'; 3 import VueRouter from 'vue-router'; 4 Vue.use(VueRouter); 5 //1.创建组件 6 import Home from './components/Home.vue'; 7 import News from './components/News.vue'; 8 import Content from './components/Content.vue'; 9 import Pcontent from './components/Pcontent.vue'; 10 //2.配置路由 注意:名字 11 const routes = [ 12 { path: '/home', component: Home }, 13 { path: '/news', component: News }, 14 { path: '/content/:aid', component: Content }, /*动态路由*/ 15 { path: '/pcontent', component: Pcontent }, 16 { path: '*', redirect: '/home' } /*默认跳转路由*/ 17 ] 18 //3.实例化VueRouter 注意:名字 19 const router = new VueRouter({ 20 routes // (缩写)相当于 routes: routes 21 }) 22 //4、挂载路由 23 new Vue({ 24 el: '#app', 25 router, 26 render: h => h(App) 27 }) 28 //5 <router-view></router-view> 放在 App.vue
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <template> 2 <div id="app"> 3 <router-link to="/home">首页</router-link> 4 <router-link to="/news">新闻</router-link> 5 <router-view></router-view> 6 </div> 7 </template> 8 <script> 9 /*1、不同路由传值:动态路由 10 1、配置动态路由 11 routes: [ 12 // 动态路径参数 以冒号开头 13 { path: '/user/:id', component: User } 14 ] 15 2、在对应的页面 16 this.$route.params获取动态路由的值 17 */ 18 export default { 19 data () { 20 return { 21 msg:'你好vue' 22 } 23 } 24 } 25 </script> 26 <style lang="scss"> 27 28 </style>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <template> 2 <!-- 所有的内容要被根节点包含起来 --> 3 <div id="home"> 4 我是首页组件 5 <ul> 6 <li v-for="(item,key) in list"> 7 <router-link :to="'/pcontent?id='+key">{{key}}--{{item}}</router-link> 8 </li> 9 </ul> 10 </div> 11 </template> 12 <script> 13 export default{ 14 data(){ 15 return { 16 msg:'我是一个home组件', 17 list:['商品111111','商品222222','商品333333'] 18 } 19 } 20 } 21 </script> 22 <style lang="scss" scoped> 23 24 </style>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <template> 2 <div id="news"> 3 我是新闻组件 4 <ul> 5 <li v-for="(item,key) in list"> 6 <router-link :to="'/content/'+key">{{key}}--{{item}}</router-link> 7 </li> 8 </ul> 9 </div> 10 </template> 11 <script> 12 export default{ 13 data(){ 14 return { 15 msg:'我是一个新闻组件' , 16 list:['111111','222222','333333'] 17 } 18 } 19 } 20 </script> 21 <style lang="scss" scoped> 22 23 </style>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <template> 2 <div id="content"> 3 我是详情页面 4 </div> 5 </template> 6 <script> 7 export default{ 8 data(){ 9 return{ 10 msg:'数据' 11 } 12 }, 13 mounted(){ 14 console.log(this.$route.params); /*获取动态路由传值*/ 15 } 16 } 17 </script>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <template> 2 <div id="content"> 3 商品详情 4 </div> 5 </template> 6 <script> 7 export default{ 8 data(){ 9 return{ 10 msg:'数据' 11 } 12 }, 13 mounted(){ 14 //获取get传值 15 console.log(this.$route.query); 16 } 17 } 18 </script>
5.动态路由、数据渲染
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 import Vue from 'vue'; 2 import App from './App.vue'; 3 //引入公共的scss 注意:创建项目的时候必须用scss 4 import './assets/css/basic.scss'; 5 //请求数据 6 import VueResource from 'vue-resource'; 7 Vue.use(VueResource); 8 import VueRouter from 'vue-router'; 9 Vue.use(VueRouter); 10 //1.创建组件 11 import Home from './components/Home.vue'; 12 import News from './components/News.vue'; 13 import Content from './components/Content.vue'; 14 //2.配置路由 注意:名字 15 const routes = [ 16 { path: '/home', component: Home }, 17 { path: '/news', component: News }, 18 { path: '/content/:aid', component: Content }, /*动态路由*/ 19 { path: '*', redirect: '/home' } /*默认跳转路由*/ 20 ] 21 //3.实例化VueRouter 注意:名字 22 const router = new VueRouter({ 23 routes // (缩写)相当于 routes: routes 24 }) 25 //4、挂载路由 26 new Vue({ 27 el: '#app', 28 router, 29 render: h => h(App) 30 }) 31 //5 <router-view></router-view> 放在 App.vue
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 @charset "utf-8"; 2 body, div, ul, li, ol, h1, h2, h3, h4, h5, h6, input, textarea, select, p, dl, dt, dd, a, img, button, form, table, th, tr, td, tbody, article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section { 3 margin: 0; 4 padding: 0; 5 } 6 html{ 7 font-size: 62.5%; 8 } 9 body { 10 font: 12px/1.5 'Microsoft YaHei','宋体', Tahoma, Arial, sans-serif; 11 color: #555; 12 background-color: #F7F7F7; 13 } 14 em, i { 15 font-style: normal; 16 } 17 ul,li{ 18 list-style-type: none; 19 } 20 strong { 21 font-weight: normal; 22 } 23 .clearfix:after { 24 content: ""; 25 display: block; 26 visibility: hidden; 27 height: 0; 28 clear: both; 29 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <template> 2 <div id="app"> 3 <header class="header"> 4 <router-link to="/home">首页</router-link> 5 <router-link to="/news">新闻</router-link> 6 </header> 7 <router-view></router-view> 8 </div> 9 </template> 10 <script> 11 /*1、不同路由传值:动态路由 12 1、配置动态路由 13 routes: [ 14 // 动态路径参数 以冒号开头 15 { path: '/user/:id', component: User } 16 ] 17 2、在对应的页面 18 this.$route.params获取动态路由的值 19 */ 20 export default { 21 data () { 22 return { 23 msg:'你好vue' 24 } 25 } 26 } 27 </script> 28 <style lang="scss"> 29 .header{ 30 height:4.4rem; 31 background:#000; 32 color:#fff; 33 line-height:4.4rem; 34 text-align:center; 35 a{ 36 color:#fff; 37 padding:0 2rem 38 } 39 } 40 </style>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <template> 2 <!-- 所有的内容要被根节点包含起来 --> 3 <div id="home"> 4 我是首页组件 5 </div> 6 </template> 7 <script> 8 export default{ 9 data(){ 10 return { 11 msg:'我是一个home组件' 12 } 13 } 14 } 15 </script> 16 <style lang="scss" scoped> 17 18 </style>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <template> 2 <div id="content"> 3 <h2>{{list.title}}</h2> 4 <div v-html="list.content"></div> 5 </div> 6 </template> 7 <script> 8 export default{ 9 data(){ 10 return{ 11 msg:'数据', 12 list:[] 13 } 14 }, 15 mounted(){ 16 // console.log(this.$route.params); /*获取动态路由传值*/ 17 var aid=this.$route.params.aid; 18 //调用请求数据的方法 19 this.requestData(aid); 20 21 }, 22 methods:{ 23 requestData(aid){ 24 //get请求如果跨域的话 后台php java 里面要允许跨域请求 25 var api='http://www.phonegap100.com/appapi.php?a=getPortalArticle&aid='+aid; 26 this.$http.get(api).then((response)=>{ 27 console.log(response); 28 this.list=response.body.result[0]; 29 },(err)=>{ 30 console.log(err) 31 }) 32 } 33 } 34 } 35 </script> 36 <style lang="scss"> 37 #content{ 38 padding:1rem; 39 line-height:2; 40 img{ 41 max-width:100%; 42 } 43 } 44 45 </style>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <template> 2 <div id="news"> 3 我是新闻组件 4 <ul class="list"> 5 <li v-for="(item,key) in list"> 6 <router-link :to="'/content/'+item.aid">{{item.title}}</router-link> 7 </li> 8 </ul> 9 </div> 10 </template> 11 <script> 12 export default{ 13 data(){ 14 return { 15 msg:'我是一个新闻组件' , 16 list:[] 17 } 18 }, 19 methods:{ 20 requestData(){ 21 //jsonp请求的话 后台api接口要支持jsonp 22 var api='http://www.phonegap100.com/appapi.php?a=getPortalList&catid=20&page=1'; 23 this.$http.jsonp(api).then((response)=>{ 24 console.log(response); 25 //注意:用到this要注意this指向 26 this.list=response.body.result; 27 },function(err){ 28 console.log(err); 29 }) 30 } 31 }, 32 mounted(){ 33 this.requestData(); 34 } 35 } 36 </script> 37 <style lang="scss" scoped> 38 .list{ 39 li{ 40 height:3.4rem; 41 line-height:3.4rem; 42 boder-bottom:1px solid #eee; 43 font-size:1.6rem; 44 a{ 45 color:#666; 46 } 47 } 48 } 49 </style>
6.路由的嵌套
(1)配置路由
{
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 import Vue from 'vue'; 2 import App from './App.vue'; 3 //引入公共的scss 注意:创建项目的时候必须用scss 4 import './assets/css/basic.scss'; 5 /*路由的嵌套 6 1.配置路由 7 { 8 path: '/user', 9 component: User, 10 children:[ 11 { path: 'useradd', component: UserAdd }, 12 { path: 'userlist', component: Userlist } 13 ] 14 } 15 2.父路由里面配置子路由显示的地方 <router-view></router-view> 16 */ 17 //请求数据 18 import VueResource from 'vue-resource'; 19 Vue.use(VueResource); 20 import VueRouter from 'vue-router'; 21 Vue.use(VueRouter); 22 //1.创建组件 23 import Home from './components/Home.vue'; 24 import News from './components/News.vue'; 25 import Content from './components/Content.vue'; 26 import User from './components/User.vue'; 27 import UserAdd from './components/User/UserAdd.vue'; 28 import Userlist from './components/User/Userlist.vue'; 29 //2.配置路由 注意:名字 30 const routes = [ 31 { path: '/home', component: Home }, 32 { path: '/news', component: News,name:'news' }, 33 { 34 path: '/user', 35 component: User, 36 children:[ 37 { path: 'useradd', component: UserAdd }, 38 { path: 'userlist', component: Userlist } 39 ] 40 }, 41 { path: '/content/:aid', component: Content }, /*动态路由*/ 42 { path: '*', redirect: '/home' } /*默认跳转路由*/ 43 ] 44 //3.实例化VueRouter 注意:名字 45 const router = new VueRouter({ 46 mode: 'history', /*hash模式改为history*/ 47 routes // (缩写)相当于 routes: routes 48 }) 49 50 51 52 53 //4、挂载路由 54 55 new Vue({ 56 el: '#app', 57 router, 58 render: h => h(App) 59 }) 60 61 62 //5 <router-view></router-view> 放在 App.vue
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <template> 2 <div id="app"> 3 <header class="header"> 4 <router-link to="/home">首页</router-link> 5 <router-link to="/news">新闻</router-link> 6 <router-link to="/user/useradd">用户</router-link> 7 </header> 8 <router-view></router-view> 9 </div> 10 </template> 11 <script> 12 export default { 13 data () { 14 return { 15 msg:'你好vue' 16 } 17 } 18 } 19 </script> 20 <style lang="scss"> 21 .header{ 22 height:4.4rem; 23 background:#000; 24 color:#fff; 25 line-height:4.4rem; 26 text-align:center; 27 a{ 28 color:#fff; 29 padding:0 2rem 30 31 } 32 } 33 </style>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <template> 2 <!-- 所有的内容要被根节点包含起来 --> 3 <div id="home"> 4 我是首页组件 5 <button @click="goNews()">通过js跳转到新闻页面</button> 6 </div> 7 </template> 8 <script> 9 export default{ 10 data(){ 11 return { 12 msg:'我是一个home组件' 13 } 14 }, 15 methods:{ 16 goNews(){ 17 // 注意:官方文档写错了 18 //第一种跳转方式 19 // this.$router.push({ path: 'news' }) 20 // this.$router.push({ path: '/content/495' }); 21 //另一种跳转方式 22 // { path: '/news', component: News,name:'news' }, 23 // router.push({ name: 'news', params: { userId: 123 }}) 24 this.$router.push({ name: 'news'}) 25 } 26 } 27 } 28 </script> 29 <style lang="scss" scoped> 30 31 </style>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <template> 2 <div id="news"> 3 我是新闻组件 4 <ul class="list"> 5 <li v-for="(item,key) in list"> 6 <router-link :to="'/content/'+item.aid">{{item.title}}</router-link> 7 </li> 8 </ul> 9 </div> 10 </template> 11 <script> 12 export default{ 13 data(){ 14 return { 15 msg:'我是一个新闻组件' , 16 list:[] 17 } 18 }, 19 methods:{ 20 requestData(){ 21 //jsonp请求的话 后台api接口要支持jsonp 22 var api='http://www.phonegap100.com/appapi.php?a=getPortalList&catid=20&page=1'; 23 this.$http.jsonp(api).then((response)=>{ 24 console.log(response); 25 //注意:用到this要注意this指向 26 this.list=response.body.result; 27 },function(err){ 28 console.log(err); 29 }) 30 } 31 }, 32 mounted(){ 33 this.requestData(); 34 } 35 } 36 </script> 37 <style lang="scss" scoped> 38 .list{ 39 li{ 40 height:3.4rem; 41 line-height:3.4rem; 42 boder-bottom:1px solid #eee; 43 font-size:1.6rem; 44 a{ 45 color:#666; 46 } 47 } 48 } 49 </style>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <template> 2 <div id="content"> 3 <h2>{{list.title}}</h2> 4 <div v-html="list.content"></div> 5 </div> 6 </template> 7 <script> 8 export default{ 9 data(){ 10 return{ 11 msg:'数据', 12 list:[] 13 } 14 }, 15 mounted(){ 16 // console.log(this.$route.params); /*获取动态路由传值*/ 17 var aid=this.$route.params.aid; 18 //调用请求数据的方法 19 this.requestData(aid); 20 }, 21 methods:{ 22 requestData(aid){ 23 //get请求如果跨域的话 后台php java 里面要允许跨域请求 24 var api='http://www.phonegap100.com/appapi.php?a=getPortalArticle&aid='+aid; 25 this.$http.get(api).then((response)=>{ 26 console.log(response); 27 this.list=response.body.result[0]; 28 },(err)=>{ 29 console.log(err) 30 }) 31 } 32 } 33 } 34 </script> 35 <style lang="scss"> 36 #content{ 37 padding:1rem; 38 line-height:2; 39 img{ 40 max-width:100%; 41 } 42 } 43 </style>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <template> 2 <!-- 所有的内容要被根节点包含起来 --> 3 <div id="user"> 4 <div class="user"> 5 <div class="left"> 6 <ul> 7 <li> 8 <router-link to="/user/useradd"> 增加用户</router-link> 9 </li> 10 <li> 11 <router-link to="/user/userlist"> 用户列表</router-link> 12 </li> 13 </ul> 14 </div> 15 <div class="right"> 16 <router-view></router-view> 17 </div> 18 </div> 19 </div> 20 </template> 21 <script> 22 export default{ 23 data(){ 24 return { 25 msg:'我是一个user组件' 26 } 27 } 28 } 29 </script> 30 <style lang="scss" scoped> 31 .user{ 32 display:flex; 33 .left{ 34 width:200px; 35 min-height:400px; 36 border-right:1px solid #eee; 37 li{ 38 line-height:2; 39 } 40 } 41 .right{ 42 flex:1; 43 } 44 } 45 </style>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <template> 2 <div id="adduser"> 3 增加用户 4 </div> 5 </template>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <template> 2 <div id="adduser"> 3 用户列表 4 </div> 5 </template>