一峰说:Vue的基础了解和使用

以下是本人学习的观点,如果有错或者说得不全面,记得告诉我哟

Vue是什么

官网说Vue是一套用于构建用户界面的渐进式框架,起初我也不知道渐进式是什么,大概就是想要什么添加什么,在了解一些基础后,觉得vue就是把原本我们要写很多原生html,js,css代码直接封装了,目的就是尽量让对代码不熟悉的人都能够进行学习,和python一样,都是为了方便。同时Vue只在视图层,这意味这写完这个代码,可以直接把代码扔给后端人员,并且不会影响后端的开发。

为什么要使用Vue

就是方便,而且如果想改前端,后端不用修改,只是把传送的接口再连上即可。而且代码比较人性化,容易上手,容易通过读代码就能理解是这个功能是什么,不过还是要进行学习。而且是响应式的,响应式就是说一写完就立刻变化,不用重新执行,提高了开发效率。

第一个Vue程序

idea配置vue环境

1.先下载插件
在这里插入图片描述
2.然后新建一个vue新建项,这里
https://blog.csdn.net/weixin_43906969/article/details/112305930

新建一个vue文件并插入vue的cdn

这个注意看div的id是app,而下面script是app的配置

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

</head>
<body>

<!--view层 模板-->
<div id="app">
    {{message}}
</div>


<!--    1.导入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
    var vm=new Vue({
        //Model:数据
        el:"#app",
        data:{
            message:"hello,vue!"
        }
    });

</script>
</body>
</html>

常用的vue功能

判断条件v-if、v-else-if和v-else用法

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

</head>
<body>

<!--view层 模板-->
<div id="app">
    <h1 v-if="type==='A'">A</h1>
    <h1 v-else-if="type==='B'">B</h1>
    <h1 v-else>C</h1>
</div>


<!--    1.导入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
    var vm=new Vue({
        //Model:数据
        el:"#app",
        data:{
           type: 'A'
        }
    });

</script>
</body>
</html>

循环v-for

-<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

</head>
<body>

<!--view层 模板-->
<div id="app">
    <li v-for="item in items">
        {{item.message}}
    </li>
</div>


<!--    1.导入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
    var vm=new Vue({
        //Model:数据
        el:"#app",
        data:{
            items: [
                {message: '一峰说java'},
                {message: '一峰说前端'},
                {message: '一峰运维'}
            ]
        }
    });

</script>
</body>
</html>

绑定事件v-on:click

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

</head>
<body>

<!--view层 模板-->
<div id="app">
    <button v-on:click="sayHi">点击我</button>
</div>


<!--    1.导入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
    var vm=new Vue({
        //Model:数据
        el:"#app",
        data:{
            message: "一峰说java"
        },
        methods: {//方法必须定义在Vue的Method对象中
            sayHi :function (){
                alert(this.message);
            }
        }
    });

</script>
</body>
</html>

双向绑定v-model

就是可以边写边显示

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

</head>
<body>

<!--view层 模板-->
<div id="app">
    <p>
    输入的文本:<textarea v-model="message"></textarea>{{message}}
    </p>
    <p>
    性别:
    <input type="radio" name="sex" value="男" v-model="fever1">男
    <input type="radio" name="sex" value="女" v-model="fever1">女
    <p>
        选中了: {{ fever1 }}
    </p>
    </p>
    <p>
        下拉框:
        <select name="" id="" v-model="fever2">
            <option value="" disabled>---请选择---</option>
            <option>A</option>
            <option>B</option>
            <option>C</option>
        </select>
        <span>{{fever2}}</span>
    </p>
</div>


<!--    1.导入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
    var vm=new Vue({
        //Model:数据
        el:"#app",
        data:{
            message: "",
            fever1: "",
            fever2: ""
        }
    });

</script>
</body>
</html>

组件化应用构建

可以理解自己定义组件,下面这个代码我觉得不够vue官网的那个好,因为下面这个少了v-bind:key用法,用力绑定id的

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

</head>
<body>

<!--view层 模板-->
<div id="app">
    <!--组件: 传递给组件中的值:props-->
    <fever v-for="item in items" v-bind:todo="item"></fever>
</div>


<!--    1.导入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>

    //定义一个Vue组件名字叫fever
    Vue.component("fever",{
        props: ['todo'],//props是绑定一个属性,并且名字是item
        template: '<li>{{todo}}</li>'//
    });

    var vm=new Vue({
        //Model:数据
        el:"#app",
        data:{
            items: ["Java","Linux","前端"]
        }
    });

</script>
</body>
</html>

使用异步通信axios

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
<!--    v-clock:解决闪烁问题,就是打开网页的时候,可能会因为网络加载太慢问题先出现空白-->
    <style>
        [v-clock]{
            display: none;
        }
    </style>
</head>
<body>

<div id="vue" v-clock>
    <div>{{info.name}}</div>
    <div>{{info.address.street}}</div>
    <a v-bind:href="info.url">去我博客</a>
</div>

//记得导入这个axios异步cdn
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.0/axios.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script type="text/javascript">
    var vm=new Vue({
        el: "#vue",
        //data: 属性:vm
        data(){
            return{
                //请求的的返回参数合适,必须和json字符串一样
                info: {//简介
                    name: null,//姓名
                    url: null,//url地址
                    address: {//地址
                        street: null,//街道
                        city: null,//城市
                        country:null //国家
                    }
                }
            }
        },
        mounted(){  //钩子函数 链式编程 ES6新特性
            axios.get('../data.json').then(response=>(this.info=response.data));//异步通信方式,data.json在下面
        }

    });
</script>

</body>
</html>

data.json:

{
  "name": "fever说java",
  "url": "https://blog.csdn.net/weixin_43906969?spm=1001.2101.3001.5343",
  "page": 1,
  "isNonProfit": true,
  "address": {
      "street": "香香街",
      "city":   "广东广州",
      "country": "中国"
  },
  "links": [
    {
      "name": "csdn",
      "url":  "https://blog.csdn.net/weixin_43906969?spm=1001.2101.3001.5343"
    },
    {
      "name": "fever说java",
      "url":  "https://blog.csdn.net/weixin_43906969?spm=1001.2101.3001.5343"
    },
    {
      "name": "百度",
      "url": "https://www.baidu.com"
    }
  ]
}

计算属性

计算属性就是用来解决因为经常放太多模板导致很难维护的问题。就是在一个叫computed的属性里面使用变量函数。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

</head>
<body>

<!--view层 模板-->
<div id="app">
    <p>currentTime1:{{currentTime1()}}</p>
    <p>currentTime2:{{currentTime2}}</p>
</div>

<!--    1.导入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
    var vm=new Vue({
        //Model:数据
        el:"#app",
        data:{
            message:"hello,fever!"
        },
        //方法属性
        methods: {
            currentTime1: function (){
                return Date.now();//返回一个时间戳
            }
        },
        computed: {//计算属性:methods,computed 方法不能重名,重名之后只会调用methods中的方法
            currentTime2: function (){
                return Date.now();//返回一个时间戳
            }
        }
    });

</script>
</body>
</html>

插槽slot

先看div的部分,然后通过div里面的东西我们可以看到它和下面组件component有关(设置插槽标签),同时再下一个component也和插槽才是绑定数据。
可能这个数据传送看起来很懵,就是new Vue那面有数据了,然后传到div上面,接着div有插槽,其实插槽就是去到哪插到哪,方便位置而已,然后第二个component绑定了插槽数据并且有一个删除remove方法,点击的时候会执行new Vue里面的methods属性里面的方法。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<!--view层 模板-->
<div id="app">
    <todo>
        <todo-title slot="todo-title" :title="title"></todo-title>
        <todo-items slot="todo-items" v-for="(item,index) in todoItems"
                    :item="item" v-bind:index="index" v-on:remove="removeItems(index)"//v-bind简写是:
        ></todo-items>
    </todo>
</div>


<!--    1.导入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>

    //Slot:插槽
    Vue.component("todo",{
        template:
        '<div>\
            <slot name="todo-title"></slot>\
            <ul>\
                <slot name="todo-items"></slot>\
            </ul>\
        </div>'
    });

    Vue.component("todo-title",{
        props: ['title'],
        template: '<div>{{title}}</div>'
    });
    Vue.component("todo-items",{
        props: ['item','index'],
        //只能绑定当前组件的方法
        template: '<li>{{index}}---{{item}}<button @click="remove">删除</button></li> ',//@是v-on简写
        methods: {
            remove: function (index){
                //this.$emit 自定义表
                this.$emit('remove',index);
            }
        }
    });

    var vm=new Vue({
        //Model:数据
        el:"#app",
        data:{
            title: "王同学列表",
            todoItems:['一峰说Java','一峰说前端','一峰说Linux']
        },
        methods: {
            removeItems:function (index){
                console.log("删除了"+this.todoItems[index]+"OK");
                this.todoItems.splice(index,1);//一次删除一个元素
            }
        }
    });

</script>
</body>
</html>

第一个vue-cli程序

vue-cli就是快速生成一个vue的项目模板

安装node.js

下载直接安装就可,不要放在c盘,它会自动配置环境变量。下载链接:http://nodejs.cn/download/

node -v  查看node.js版本
npm -v   查看npm软件包管理工具版本

安装node.js淘宝镜像加速器(cnpm)

npm install cnpm -g //-g是全局安装的意思

安装vue-cli

cnpm install vue-cli -g

创建一个基于webpack模板的vue应用程序

vue init webpack myvue

一路选no就可以了,东西需要再加

初始化并运行vue项目

如果想在idea上执行命令,记得把idea设置为管理员权限

cd myvue //进入vue项目
npm install
npm run dev
或者
cnpm install
cnpm run dev

学习Webpack

webpack就是一个js的静态模块打包器。

创建一个目录modules

在这里插入图片描述
1.导入一个方法

hello.js:
//暴露一个方法
exports.sayHi =function (){
    document.write("<h1>一峰说ES6</h1>");
};

2。引用一个方法

main.js:
var hello = require('./hello');
hello.sayHi();

3.配置

webpack.config.js:
module.exports = {
    entry: './modules/main.js',
    output: {
        filename: "./js/bundle.js"
    }
};

4.生成配置文件

在idea当前项目所在目录下执行命令
webpack.config.js

5.插入显示

index.html:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<!--前段的模块化开发-->
<script src="dist/js/bundle.js"></script>
</body>
</html>

路由+elementUI+路由嵌套+参数传递+重定向+404+路由钩子

vue-router路由

1.首先安装

cnpm install vue-router --save-dev

2.在App.vue添加布局

<template>
  <div id="app">
    <h1>Vue-Router</h1>
    <router-link to="/main">首页</router-link>
    <router-link to="/content">内容页</router-link>
    <router-link to="/xiaobu">小布</router-link>
    <router-view></router-view>
  </div>
</template>

<script>
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>

3…在main.js导入router包

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/>'
})

4.配置router目录下index.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/>'
})

5.router下的index.js配置

import Vue from 'vue'
import VueRouter from "vue-router";
import Content from "../components/Content";
import Main from "../components/Main";
import Xiaobu from "../components/Xiaobu";

//安装路由
Vue.use(VueRouter);

//配置导出路由
export  default new VueRouter({
  routes: [
    {
      //路由路径 @RequestMapping
      path: '/content',
      name: 'content',
      //跳转的组件
      component: Content
    },
    {
      //路由路径
      path: '/main',
      name: 'main',
      //跳转的组件
      component: Main
    },
    {
      //路由路径
      path: '/xiaobu',
      name: 'xiaobu',
      //跳转的组件
      component: Xiaobu
    }
  ]
});

6.components文件夹,添加vue文件
Content.vue:

<template>
  <h1>内容页</h1>
</template>

<script>
export default {
  name: "Content"
}

</script>
<style scoped>
</style>

Main.vue:

<template>
  <h1>首页</h1>
</template>

<script>
export default {
  name: "Main"
}
</script>

<style scoped>

</style>

Xiaobu.vue:

<template>
  <h1>小布</h1>
</template>

<script>
export default {
  name: "Xiaobu"
}
</script>

<style scoped>

</style>

vue+elementUI

1.在main.js下导添加

import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';

Vue.use(ElementUI)


new Vue({
  el: '#app',
  render: h => h(App)//ElementUI
})

2.添加页面样式即可,例如
在这里插入图片描述

路由嵌套

直接展示
在这里插入图片描述

参数传递

参数传递有页面直接操作和后端获取数据,后端一般会用axios,前段用url

页面直接操作:
这里固定是1,一般是可变的id
在这里插入图片描述
然后在router下的index.js对应的路径添加多一个name属性:
在这里插入图片描述
接着在对应vue文件绑定好参数
在这里插入图片描述
后端获取数据
简单说说就是在对应页面的script标签下写几行代码,这里是输出到控制台
在这里插入图片描述
一般结合vue-axios是要安装命令:
建议去axios的官网看看安装教程,很短的

npm install --save axios vue-axios

重定向

在这里插入图片描述

404

在这里插入图片描述

路由钩子

路由中的钩子函数,就是在路由前后有个函数,有时作用是过滤

在这里插入图片描述

完整的例子

目录:
在这里插入图片描述

App.vue:

<template>
  <div id="app">

    <router-view></router-view>
  </div>
</template>

<script>


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>

main.js

import Vue from 'vue'
import App from './App'
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import router from './router'

import axios from 'axios'
import VueAxios from 'vue-axios'

Vue.use(VueAxios, axios)

Vue.use(router)
Vue.use(ElementUI)


new Vue({
  el: '#app',
  router,
  render: h => h(App)//ElementUI
})

Login.vue

<template>
  <div>
    <el-card class="box-card">
    <el-form ref="loginForm" :model="form" :rules="rules" label-width="80px" class="login-box">
      <h3 class="login-title">欢迎登录</h3>
      <el-form-item label="账号" prop="username">
        <el-input type="text" placeholder="请输入账号" v-model="form.username"/>
      </el-form-item>
      <el-form-item label="密码" prop="password">
        <el-input type="password" placeholder="请输入密码" v-model="form.password"/>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" v-on:click="onSubmit('loginForm')">登录</el-button>
      </el-form-item>
    </el-form>
    </el-card>

    <el-dialog
      title="温馨提示"
      :visible.sync="dialogVisible"
      width="30%"
      :before-close="handleClose">
      <span>请输入账号和密码</span>
      <span slot="footer" class="dialog-footer">
        <el-button type="primary" @click="dialogVisible = false">确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>
<script>
export  default {
  name:"Login",
  data(){
    return{
    form:{
        username: '',
        password: ''
      },
      //表单验证,需要再el-form-item 元素中增加prop属性
      rules:{
        username:[
            {required:true,message:'账号不能为空',trigger:'blur'} //trigger:'blur'失去焦点
          ],
    password:[
    {required: true,message: '密码不能为空',trigger:'blur'}
          ]
  },
    //对话框显示和隐藏
    dialogVisible:false
  }
  },
  methods:{
    handleClose: function () {
      console.log("Handle Close,空函数");
    },
    onSubmit(formName) {
      //为表单绑定验证功能
      this.$refs[formName].validate((valid) =>{
        if (valid){
          //使用 vue-router路由到指定页面,该方式称之为编程式导航
          this.$router.push("/main");
        } else {
          this.dialogVisible = true;
          return false;
        }
      });
    }
  }
}
</script>
<style lang="scss" scoped>
.login-box{
  border: 1px solid #DCDFE6;
  width: 350px;
  margin:180px auto;
  padding:35px 35px 15px 35px;
  border-radius: 5px;
  -webkit-border-radius: 5px;
  -moz-border-radius: 5px;
  box-shadow:0 0 25px #909399;

}
.box-card {width: 480px;margin: auto;}

.login-title{
  text-align:center;
  margin:0 auto 40px auto;
  color:#303133;
}
</style>

Main.vue

<template>
  <div>
    <el-container>
      <el-aside width="200px">
        <el-menu :default-openeds="['1']">
          <el-submenu index="1">
            <template slot="title"><i class="el-icon-caret-right"></i>用户管理</template>
            <el-menu-item-group>
              <el-menu-item index="1-1">
                <router-link :to="{name: 'UserProfile',params: {id :1}}">个人信息</router-link>
              </el-menu-item>
              <el-menu-item index="1-2">
                <router-link to="/user/list">用户列表</router-link>
              </el-menu-item>
              <el-menu-item index="1-3">
                <router-link to="/goHome">回到首页</router-link>
              </el-menu-item>
            </el-menu-item-group>
          </el-submenu>
          <el-submenu index="2">
            <template slot="title"><i class="el-icon-caret-right"></i>内容管理</template>
            <e1-menu-item-group>
              <el-menu-item index="2-1">分类管理</el-menu-item>
              <el-menu-item index="2-2">内容列表</el-menu-item>
            </e1-menu-item-group>
          </el-submenu>
        </el-menu>
      </el-aside>


      <el-container>
        <el-header style="text-align: right; font-size: 12px">
          <el-dropdown>
            <i class="el-icon-setting" style="margin-right:15px"></i>
            <el-dropdown-menu slot="dropdown">
              <el-dropdown-item>个人信息</el-dropdown-item>
              <el-dropdown-item>退出登录</el-dropdown-item>
            </el-dropdown-menu>
          </el-dropdown>

        </el-header>

        <el-main>
          <router-view/>
        </el-main>

      </el-container>
    </el-container>
  </div>
</template>

<script>
export default {

  name: "Main"
}
</script>

<style scoped lang="scss">
.el-header {
  background-color: #048bd1;
  color: #333;
  line-height: 60px;
}

.el-aside {
  color: #333;
}
</style>

NoFound.vue

<template>
  <h1>404,你的页面走丢了</h1>
</template>

<script>
export default {
  name: "NoFound"
}
</script>

<style scoped>

</style>

List.vue

<template>
  <h1>用户列表</h1>
</template>

<script>
export default {
  name: "List"
}
</script>

<style scoped>

</style>

Profile.vue

<template>
  <div>
    <h1>个人信息</h1>
    {{ id }}
  </div>
</template>

<script>
export default {
  props: ['id'],
  name: "Profile",
  //过滤器 chain
  beforeRouteEnter:(to,from,next)=>{
      console.log("进入路由之前");
      next(vm =>{
        vm.getData();//进入路由之前执行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>

<style scoped>

</style>

index.js

import Vue from 'vue'
import Router from 'vue-router'

import Main from '../views/Main'
import Login from '../views/Login'
import UserList from '../views/user/List'
import UserProfile from '../views/user/Profile'
import NotFound from '../views/NoFound'

Vue.use(Router);

export default new Router({
  mode: 'history',//去掉#号
  routes:[
    {
      path: '/main',
      component: Main,  //嵌套路由

      children:
        [
          {path: '/user/profile/:id',name: 'UserProfile',component:UserProfile,props:true},
          {path: '/user/list',component: UserList},
        ]
    },{
      path: '/login',
      component: Login
    },{
      path: '/goHome',
      redirect: '/main'
    },{
      path: '*',
      component: NotFound
    }
  ]
});

mock是虚拟伪造的意思,data.json:

{
  "name":"一峰说java",
  "url": "http://baidu.com",
  "page": "1",
  "isNonProfit":"true",
  "address": {
    "street": ";八一路",
    "city":"广东广州",
    "country": "中国"
  },
  "links": [
    {
      "name": "B站",
      "url": "https://www.bilibili.com/"
    },
    {
      "name": "4399",
      "url": "https://www.4399.com/"
    },
    {
      "name": "百度",
      "url": "https://www.baidu.com/"
    }
  ]
}


版权声明:本文为weixin_43906969原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。