Vue学习😀

  • A+
所属分类:Web前端
摘要

渐进式 JavaScript 框架官网:https://cn.vuejs.org前端体系、前后端分离SOC:关注点分离


Vue

Vue学习😀

渐进式 JavaScript 框架

1、简介

官网:https://cn.vuejs.org

前端体系、前后端分离

SOC:关注点分离

只管视图层

  • 网络通信:axios

  • 页面跳转:vue-router

  • 状态管理:vuex

  • Vue-UI: ICE

  • 结构层:HTML

  • 表示层:CSS

    • CSS预处理器:动态变化——>SASS(Ruby)、LESS(NodeJS)
  • 行为层:JavaScript

2、UI框架

Vue学习😀

NodeJS 带来的全栈时代:http://nodejs.cn/

Vue学习😀

3、Vue基础语法

  1. CDN

    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> 
  2. 官网的GitHub也可以直接下文件

3.1、v-bind:title = ''

<!DOCTYPE html> <html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml"> <head>     <meta charset="UTF-8">     <title>Title</title> </head> <body>     <!-- MVC模型 ——> MVVM模型 -->      <!-- view层 模板 -->     <!-- 方式一 -->     <!-- <div id="app">         {{message}}     </div> -->      <!-- 方式二 -->     <!-- 会出现 message 的数据 -->     <div id="app">         <!-- v-bind:title 绑定元素的 title 与 message 属性一致 -->         <!-- 用于鼠标触碰显示信息 -->         <span v-bind:title="message">             鼠标悬停几秒查看此处动态绑定的提示信息         </span>     </div>          <!-- 也可以用lib包下的vue.js文件 -->     <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script>     <script>         var vm = new Vue({             el:"#app",             //Model层 数据             data:{                 message:"hello,vue"             }         });          //双向绑定,就是前端数据改变,data数据也会改变,反过来也可以,而且这个页面不用刷新         //上面这种被广泛应用了,例如节假日做活动,只需要改变前端样式即可,不需要不断刷新页面         vm.message = 'Happy~Study?';     </script>  </body> </html> 

Vue学习&#128512;

3.2、v-if 和 v-else

<body>      <!-- 这就只需要后端传数据过来就可以判断选择 -->     <div id="app">         <h1 v-if="type==='A'">A</h1>         <h1 v-else-if="type==='B'">B</h1>         <h1 v-else>C</h1>     </div>          <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script>     <script>         var vm = new Vue({             el:"#app",             data:{                 // ok:true                 type:'A'             }         });          // vm.ok = false;  //显示 No          // vm.type = 'B'; //显示B         // vm.type = 'R'; //显示C     </script> </body> 

3.3、v-for

<body>     <div id="app">                  <li v-for="(item,index) in items">             {{item.message}}--{{index}}--{{item}}         </li>      </div>          <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script>     <script>         var vm = new Vue({             el:"#app",             data:{                 // 下面 items 数组有两个对象                 items:[                     {message:'Happy?'},                     {message:'Sad?'},                     {message:'angry?'},                 ]             }         });     </script> </body> 

Vue学习&#128512;

4、事件

4.1、v-on

<body>     <div id="app">                  <button v-on:click="sayHi">click me</button>      </div>          <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script>     <script>         var vm = new Vue({             el: "#app",             data: {                 message: "Happy?"             },             methods: {                 //方法必须定义在 vue 的 methods 对象里面                 sayHi: function(){                     alert(this.message);                 }             }         });     </script> </body> 

Vue学习&#128512;

5、双向绑定

input

<body>     <div id="app">         输入的文本:<input type="text" v-model="message">{{message}}     </div>          <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script>     <script>         var vm = new Vue({             el: "#app",             data: {                 message: "???????"             },             methods: {                              }         });     </script> </body> 

Vue学习&#128512;

textarea

<textarea name="" id="" cols="30" rows="10"v-model="message"></textarea> {{message}} 

Vue学习😀

单选框

<body>     <div id="app">         性别:         <input type="radio" name="sex" value="??" v-model="qinjiang">??         <input type="radio" name="sex" value="??" v-model="qinjiang">??          <p>             选中了谁:{{qinjiang}}         </p>      </div>          <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script>     <script>         var vm = new Vue({             el: "#app",             data: {                 qinjiang: ''             },             methods: {                              }         });     </script> </body> 

Vue学习&#128512;

下拉框

<body>     <div id="app">         下拉框:         <select v-model="qinjiang">             <option value="" disabled>--请选择--</option>             <option>?</option>             <option>?</option>             <option>?</option>             <option>?</option>         </select>         <span>value:{{qinjiang}}</span>     </div>          <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script>     <script>         var vm = new Vue({             el: "#app",             data: {                 qinjiang: ''             },             methods: {                              }         });     </script> </body> 

Vue学习&#128512;

6、Vue组件

6.1、第一个组件程序

<body>     <div id="app">         <qinjiang></qinjiang>     </div>          <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script>     <script>          //定义组件component         Vue.component(             "qinjiang",             {                 //用qinjiang代替li标签                 template: '<li>Hello</li>'             }         );          var vm = new Vue({             el: "#app"         });     </script> </body> 

6.2、进阶版

<body>     <div id="app">         <!-- 组件:传递给组件中的值:props -->         <qinjiang v-for="item in items" v-bind:qin="item"></qinjiang>     </div>          <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script>     <script>          //定义组件component         Vue.component(             "qinjiang",             {                 props: ['qin'],                 template: '<li>{{qin}}</li>'             }         );          var vm = new Vue({             el: "#app",             data: {                 items: ["?","?","?"]             }         });     </script> </body> 

Vue学习😀

Vue学习&#128512;

6.3、进阶到.vue文件

模板

<template>    </template>  <script> export default {  } </script>  <style>  </style> 

7、axios 网络通信

实现ajax异步通信

Vue学习😀

官网:http://axios-js.com

CDN

<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.js"></script> 

7.1、第一个程序

data.json

{     "name": "Happy~Study?",     "url": "https://www.cnblogs.com/happy-msh/",     "page": 1,     "isNonProfit": true,     "address": {         "street": "三峡大学",         "city": "湖北宜昌",         "country": "中国"     },     "links": [         {         "name": "B站",         "url": "https://space.bilibili.com/95256449"         },         {         "name": "我的博客",         "url": "https://www.cnblogs.com/happy-msh/"         },         {         "name": "百度",         "url": "https://www.baidu.com/"         }     ] } 
<body> 	<div id="vue"></div> 	<!--引入js文件--> 	<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> 	<script src="https://unpkg.com/axios/dist/axios.min.js"></script> 	<script type="text/javascript"> 	    var vm = new Vue({ 	        el:"#vue", 	        mounted(){//钩子函数 	            axios.get('data.json').then(response=>(console.log(response.data))); 	        } 	    }); 	</script> </body> 

data.json 实现了ajax的异步刷新:Vue学习&#128512;

Vue学习&#128512;

7.2、进阶版

<head> <!-- v-clock:解决页面闪烁问题 -->     <style>         [v-clock]{             display: none;         }     </style> </head> <div id="vue" v-clock>     <div>{{info.name}}</div>     <div>{{info.address.country}}--{{info.address.city}}--{{info.address.street}}</div>      <a v-bind:href="info.url">点?进入❤️世界</a> </div>  <script type="text/javascript">     var vm = new Vue({         el:"#vue",         data(){             return{                 //请求返回参数合适,必须和json字符串一样                 info:{                     name: null,                     address: {                         street: null,                         city: null,                         country: null                     },                     url: null                 }             }         },         mounted(){//钩子函数,链子编程             axios.get('data.json').then(response=>(this.info=response.data));         }     }); </script> 

Vue学习&#128512;

8、计算属性

计算出来的结果,保存在属性

可以想象成缓存

<body> <div id="app">     <p>currentTime2:{{currentTime1()}}</p>     <p>currentTime2:{{currentTime2}}</p> </div>  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <script src="https://unpkg.com/axios/dist/axios.min.js"></script> <script type="text/javascript">     var vm = new Vue({         el:"#app",         data: {             message: 'Happy~Study?'         },         methods: {             currentTime1: function(){                 return Date.now();//返回一个时间戳             }         },         computed:{//计算属性,建议不要和 methods 方法重名,因为重名后只会调用 methods 里面的方法             //节省浏览器的成本,不需要多次调用方法,在缓存去拿就行             currentTime2: function(){                 this.message;                 return Date.now();//返回一个时间戳             }         }     }); </script> </body> 

Vue学习&#128512;

一个是方法,一个是属性

9、插槽 slot

承载分发内容的出口,即内容分发

<body> <div id="app">      <!-- 改用插槽实现 -->     <!-- <p>书籍目录</p>     <ul>         <li>Java</li>         <li>Mybatis</li>         <li>Python</li>     </ul> -->      <todo>         <todo-title slot="todo-title" :title="title"></todo-title>         <todo-items slot="todo-items" v-for="item in todoItems" :item="item"></todo-items>     </todo> </div>  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <script src="https://unpkg.com/axios/dist/axios.min.js"></script> <script type="text/javascript">      Vue.component("todo",{         // slot 定义插槽 实现动态编辑         template: '<div>                         <slot name="todo-title"></slot>                         <ul>                             <slot name="todo-items"></slot>                         </ul>                   </div>'     });      Vue.component("todo-title",{         props: ['title'],         template: '<p>{{title}}</p>'     });     Vue.component("todo-items",{         props: ['item'],         template: '<li>{{item}}</li>'     });      var vm = new Vue({         el:"#app",         data: {             title: "秦老师系列列表",             todoItems: ['狂神说Java','狂神说前端',"你好"] //前端就只需要在这改动数据就行,就会在对应位置插入数据         }     }); </script> </body> 

10、自定义事件

this.$emit('自定义事件名',参数)

实现参数传递与事件的并发

<body> <div id="app">      <!-- 改用插槽实现 -->     <!-- <p>书籍目录</p>     <ul>         <li>Java</li>         <li>Mybatis</li>         <li>Python</li>     </ul> -->      <todo>         <todo-title slot="todo-title" :title="title"></todo-title>         <!-- v-bind:title  => 简写: :title -->         <todo-items slot="todo-items" v-for="(item,index) in todoItems"                     :item="item" :index="index" v-on:remove="removeItems(index)" :key="index"></todo-items>     </todo> </div>  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <script src="https://unpkg.com/axios/dist/axios.min.js"></script> <script type="text/javascript">      // 组件     Vue.component("todo",{         // slot 定义插槽 实现动态编辑         template: '<div>                         <slot name="todo-title"></slot>                         <ul>                             <slot name="todo-items"></slot>                         </ul>                   </div>'     });      Vue.component("todo-title",{         props: ['title'],//传参         template: '<p>{{title}}</p>'     });     Vue.component("todo-items",{         props: ['item','index'],//传参         // @ => v-on         template: '<li>{{index}}---{{item}}<button @click="remove">删除</button></li>',         methods:{             remove: function(index){                 //                 this.$emit('remove',index);             }         }     });      // Vue 实例     var vm = new Vue({         el:"#app",         data: {             title: "秦老师系列列表",             todoItems: ['狂神说Java','狂神说前端',"你好"] //前端就只需要在这改动数据就行,就会在对应位置插入数据         },         methods: {             removeItems: function(index){                 console.log("删除了" + this.todoItems[index] + "OK");                 this.todoItems.splice(index,1);//一次只删除一个元素             }         }     }); </script> </body> 

Vue学习&#128512;

Vue学习&#128512;

思路:

Vue学习😀

11、总结

核心:数据驱动,组件化

常用属性

  • v-if
  • v-else-if
  • v-else
  • v-for
  • v-on 绑定事件,简写@
  • v-model 数据双向绑定
  • v-bind 给组件绑定参数,简写 :

组件化

  • solt 插槽,组合组件
  • this.$emit('自定义事件名',参数); 组件内部绑定事件需要用到
  • 计算属性的特色,缓存计算数据

12、第一个vue-cli项目

vue-cli是一个脚手架

12.1、安装NodeJS

官网:http://nodejs.cn/

Vue学习&#128512;

12.2、安装vue-cli

安装加速器:https://blog.csdn.net/m0_46462506/article/details/118641566?ops_request_misc=%7B%22request%5Fid%22%3A%22162851321916780269846081%22%2C%22scm%22%3A%2220140713.130102334..%22%7D&request_id=162851321916780269846081&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduend~default-1-118641566.first_rank_v2_pc_rank_v29&utm_term=npm+install+cnpm+-g&spm=1018.2226.3001.4187

安装vue-cli:cnpm install vue-cli -g

测试:vue list

需要创建的文件地址下,用cmd创建项目:vue init webpack myvue

Vue学习😀

12.3、初始化并运行

cmd

  • cd myvue 到这个文件下下载
  • npm install 下载
  • npm run dev 运行
    • 关闭直接:ctrl + c

​ 在 idea 下打开文件后,改动 HelloWorld.vue文件的 template 标签下的内容,然后在 idea 最下面位置的 Terminal 处输入 npm run dev 即可产生如下效果

Vue学习😀

13、Webpack学习使用

是一款模块加载器兼打包工具,他能把各种资源作为模块来处理和使用

13.1、安装Webpack

cmd:

  • npm install webpack -g
  • npm install webpack-cli -g

Vue学习&#128512;

13.2、配置

创建 webpack.config.js 配置文件

  • entry:入口文件,指定webpack用哪个文件作为项目的入口
  • output:输出,指定webpack把处理完成的文件放置到指定路径
  • module:模块,用于处理各种类型的文件
  • plugin:插件,如:热更新,代码重用等
  • resolve:设置路径指向
  • watch:监听,用于设置文件改动后直接打包

模板:

module.exports = {     entry: "",     output: {         path: "",         filename: ""     }     module: {     	loaders: [     		{test: /.js$/, loader: ""}     	] 	},     plugins: {},     resolve: {},     watch: true } 

13.3、第一个webpack程序

Vue学习&#128512;

  1. main.js

    //主入口 var hello = require("./hello");//相当于创建一个对象,下面就可以调用对象中的方法 hello.sayHi(); 
  2. hello.js

    //暴露一个方法,类似与 Java 类中的 public,就是写函数 exports.sayHi = function () {     document.write("<h1>Happy~Study?</h1>") } 
  3. webpack.config.js

    module.exports = {     entry:'./modules/main.js',//入口     output:{         filename:"./js/bundle.js"//不要自己写文件,在Terminal处输入webpack打包即可产生文件     } }; 
  4. index.html

    <body> <!--前端的模块化开发--> <script src="dist/js/bundle.js"></script> </body> 
  5. 结果:Vue学习&#128512;

14、vue-router路由

14.1、安装

cmd

  • install vue-router --save-dev

干净的项目:Vue学习&#128512;

  1. App.vue

    <template>   <div id="app">    </div> </template>  <script> // import HelloWorld from './components/HelloWorld'  export default {   name: 'App' } </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> 
  2. main.js

    import Vue from 'vue' import App from './App' import VueRouter from "vue-router";  Vue.config.productionTip = false  //显示声明使用 VueRouter Vue.use(VueRouter);  new Vue({   el: '#app',   components: { App },   template: '<App/>' }) 

14.2、第一个vue-router程序

  1. App.vue

    <template>   <div id="app">     <h1>Happy~Study?</h1>     <!--router-link 就是类似与 a 标签-->     <router-link to="/main">首页</router-link>     <router-link to="/content">内容</router-link>     <!--显示内容-->     <router-view></router-view>   </div> </template>  <script> export default {   name: 'App', } </script> 

    前端显示:Vue学习&#128512;

  2. main.js

    import Vue from 'vue' import App from './App' import router from './router' //自动扫描里面的路由配置  Vue.config.productionTip = false  new Vue({   el: '#app',   //配置路由   router,   components: { App },   template: '<App/>' }) 
  3. Content.vue

    <template>   <div>     <h1>内容</h1>   </div> </template>  <script> export default {   name: "Content" } </script>  <!--scoped : 指定只在当前作用域有用--> <style scoped>  </style> 
  4. Main.vue

    <template>   <div>     <h1>首页</h1>   </div> </template>  <script> export default {   name: "Main" } </script>  <style scoped>  </style> 
  5. index.js

    import Vue from "vue"; import VueRouter from "vue-router";  import Content from "../components/Content"; import Main from "../components/Main"; import Happy from "../components/Happy"; import App from "../App";  //安装路由 Vue.use(VueRouter);  //配置导出路由 export default new VueRouter({   // 千万别写成 routers   routes: [     {       // 路由路径,就是页面跳转       path: '/content',       name: 'content',       // 跳转的组件       component: Content     },     {       // 路由路径,就是页面跳转       path: '/main',       name: 'main',       // 跳转的组件       component: Main     }   ] }); 
  6. 结果Vue学习😀

15、vue+elementui

cmd

  1. 创建工程

    vue init webpack hello-vue

Vue学习&#128512;

  1. 打开工程目录

    cd hello-vue

    Vue学习&#128512;

  2. 安装 vue-router

    npm install vue-router --save-dev

  3. 安装 element-ui

    npm i element-ui -S

  4. 安装依赖

    npm install

  5. 安装SASS加载器

    cnpm install sass-loader node-sass --save-dev

  6. 启动测试

    npm run dev

main.js

import Vue from 'vue' import App from './App'  import router from './router'  Vue.config.productionTip = false  //导入element-ui import ElementUI from 'element-ui'; import 'element-ui/lib/theme-chalk/index.css';  import axios from 'axios'; import VueAxios from 'vue-axios';  Vue.use(router); Vue.use(ElementUI); Vue.use(VueAxios,axios);  new Vue({   el: '#app',   router,   render: h => h(App) //ElementUI }); 

index.js

import Vue from "vue"; import Router from "vue-router";  import Main from "../views/Main"; import Login from "../views/Login";  import UserProfile from "../views/user/Profile"; import UserList from "../views/user/List"; import NotFound from "../views/NotFound";  Vue.use(Router);  export default new Router({   mode: 'history', //解决 http://localhost:8080/#/login 中的 # ,让其变成 http://localhost:8080/login   routes:[     {       path: '/main/:name',       component: Main,       props: true,       children: [// 路由嵌套         {           path: '/user/profile/:id',           name: 'UserProfile',           component: UserProfile,           props: true         },         {           path: '/user/list',           component: UserList         },       ]     },     {       path: '/login',       component: Login     },     {       path: '/goLogin',       redirect: '/login'     },     {       path: '*',       component: NotFound     }   ] }); 

15.1、路由嵌套

path: '/main/:name', component: Main, props: true, children: [// 路由嵌套     {       path: '/user/profile/:id',       name: 'UserProfile',       component: UserProfile,       props: true     },     {       path: '/user/list',       component: UserList     }, ] 

效果

Vue学习&#128512;

15.2、参数传递

path: '/user/profile/:id', name: 'UserProfile', component: UserProfile, props: true 
<template>   <div>     <h1>个人信息</h1>     <!--{{ $route.params.id }} //组件后面配置了props就不需要这样了-->     {{id}}   </div> </template> <script> export default {     props: ['id'],//传参     name: "UserProfile" } </script> 

效果

Vue学习&#128512;

15.3、重定向

path: '/goLogin', redirect: '/login' 

15.4、404

path: '*', component: NotFound 

Vue学习😀

15.5、路由钩子

使用 axios 实现异步

  1. 安装:cmd :cnpm install axios -s
  2. main.js 绑定

Profile.vue

<script> export default {   props: ['id'],//传参   name: "UserProfile",   //进入路由之前执行   /* 拦截器     to:路由将要跳转的路径信息     from:路由跳转前的路径信息     next:路由的控制参数       next(); 跳到下一个页面       next('/path') 改变路由的跳转位置,使其跳转到另外一个路由       next(false) 返回原来的界面       next((vm)=>{}) 仅在 beforeRouterEnter 中可用,vm 是组件实例    */   beforeRouteEnter:(to,from,next)=>{     console.log("进入路由前");// 加载数据     next(vm => {       vm.getData();// 进入路由之前执行方法     });   },   //离开路由之前执行   beforeRouteLeave:(to, from, next)=>{     console.log("离开路由前");     next();   },   methods:{     getData: function () {       this.axios({         method: 'get',         url: 'http://localhost:8080/static/mock/data.json'       }).then(function (response) {         console.log(response);       });     }   } } </script> 

效果

Vue学习😀