Vue笔记

1、Vue初识

安装Vue

IDEA -- setting -- plugins -- vue.js

image-20221126161507792

官网:Vue.js - 渐进式 JavaScript 框架 | Vue.js (vuejs.org)

第一个Vue程序

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

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

</head>
<body>

<!--view层 模板-->
<div id="app">
    <span v-bind:title="message">
        鼠标悬停几秒钟,查看此处动态绑定的提示信息!
    </span>
</div>

<script>
    let vm = new Vue({
        el: "#app",
        /*Model:数据*/
        data:{
            message: "hello,vue!"
        }
    });
</script>

</body>
</html>

2、Vue基础语法

v-bind:绑定组件参数

<div id="app">
    <span v-bind:title="message">
        鼠标悬停几秒钟,查看此处动态绑定的提示信息!
    </span>
</div>

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

条件判断语句

  • v-if
  • v-else
<!--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>

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

循环语句

v-for

<div id="app">
    <li v-for="(item, index) in items">
        {{item.message}} --- {{index}}
    </li>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
    let vm = new Vue({
    el: "#app",
    data: {
        items: [
            {message: '狂神说Java'},
            {message: '狂神说前端'},
            {message: '狂神说运维'}
        ]
    }
  });
</script>

监听事件:v-on

v-on:绑定事件

<div id="app">
    <!--使用v-on绑定了 click事件,并指定了名为 sayHello的方法-->
    <button v-on:click="sayHello">click me</button>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
    let vm = new Vue({
        el: "#app",
        data: {
            message: "狂神说Java"
        },
        methods: { //方法必须定义在Vue的methods对象中,通过v-on绑定事件
            sayHello: function () {
                alert(this.message);
            }
        }
    });
</script>

3、表单双绑

3.1、什么是双向数据绑定

Vue.js 是一个 MVVM 框架,即数据双向绑定,即当数据发生变化,视图也就发生变化,当视图发生变化,数据也发生变化。

3.2、在表单中使用双向数据绑定

使用 v-model 指令在表单 <input><textarea><select> 元素上创建双向数据绑定。

文本:

<div id="app">
    输入的文本:<input type="text" v-model="message"> {{message}}
</div>

<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
    let vm = new Vue({
        el: "#app",
        data: {
            message: 123
        }
    });
</script>

单选框:

<div id="app">
    性别:
    <input type="radio" name="sex" value="男" v-model="value"> 男
    <input type="radio" name="sex" value="女" v-model="value"> 女
    <p>
        选中了谁:{{value}}
    </p>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
    let vm = new Vue({
        el: "#app",
        data: {
            value: ''
        }
    });
</script>

下拉单:

<div id="app">
    下拉框:
    <select v-model="selected">
        <option value="" disabled>---请选择---</option>
        <option>A</option>
        <option>B</option>
        <option>C</option>
    </select>
    <p>
        选中了谁:{{selected}}
    </p>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
    let vm = new Vue({
        el: "#app",
        data: {
            selected: ""
        }
    });
</script>

4、组件

组件是可复用的 Vue 实例,说白了就是一组可以重复使用的模板,跟 JSTL 的自定义标签、Thymeleaf 的 th:fragment 等框架有着异曲同工之妙。

通常一个应用会以一棵组件树的形式组织:

image-20221126173538847

<div id="app">
    <!-- v-bind:接收参数=遍历参数 -->
    <my-component v-for="item in items" v-bind:val="item"></my-component>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>

    //定义一个vue组件
    Vue.component("my-component",{
        props: ['val'], //参数
        template: '<li>{{val}}</li>'
    });

    let vm = new Vue({
        el: "#app",
        data: {
            items: ["Java", "Linux", "windows"]
        }
    });
</script>

5、Axios异步通信

Axios 是一个开源的可以用在浏览器端和 NodeJS 的异步通信框架,主要作用就是实现 AJAX 异步通信。

Github:https://github.com/axios/axios

中文文档:http://www.axios-js.com/

引入 axios cdn

<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

json数据:

{
  "name": "狂神说Java",
  "url": "https://blog.kuangstudy.com",
  "page": 1,
  "isNonProfit": true,
  "address": {
    "street": "含光门",
    "city": "陕西西安",
    "country": "中国"
  },
  "links": [
    {
      "name": "bilibili",
      "url": "https://space.bilibili.com/95256449"
    },
    {
      "name": "狂神说Java",
      "url": "https://blog.kuangstudy.com"
    },
    {
      "name": "百度",
      "url": "https://www.baidu.com/"
    }
  ]
}

测试:

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

    <!--解决闪烁问题-->
    <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>


<!--引入 js文件-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
  let vm = new Vue({
    el: '#vue',
    data() {
        return {
            //请求的返回参数必须和json字符串一样
            info: {
                name: null,
                address: {
                    name: null,
                    city: null,
                    country: null
                },
                url: null
            }
        }
    },
    mounted() {//钩子函数 链式编程
        axios.get('../data.json').then(response=>(this.info=response.data));
    }
  });
</script>

</body>
</html>

6、计算属性

计算属性的重点突出在 属性 两个字上,首先它是个属性,其次这个属性有 计算 的能力,这里的计算就是个函数。简单点,他就是一个能够计算结果缓存起来的属性(将行为转化为静态的属性),可以想象成缓存。

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

<div id="app">
    <p>currentTime1 = {{currentTime1()}}</p>
    <p>currentTime2 = {{currentTime2}}</p>
</div>


<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
  let vm = new Vue({
      el: '#app',
      data: {
          message: 'hello,kuangshen',
      },
      methods: {
          currentTime1: function () {
              return Date.now(); //返回当前时间戳
         }
      },
      computed: { //计算属性,methods,computed 方法名不能重名,重名之后,只会调用 methods中的方法
          currentTime2: function () {
              return Date.now(); //返回当前时间戳
         }
     }
  });
</script>

</body>
</html>

注意:methods,computed 方法名不能重名,重名之后,只会调用 methods中的方法

说明:

  • methods:定义方法,调用时需要加上 (),调用方法时,每次都需要进行计算
  • computed:定义计算属性,调用时不需要加上 ()。使用计算属性时,只有数据刷新了,才会重新计算,存入“缓存”。

7、内容分发

在 Vue.js 中,我们使用 <slot> 元素作为承载分发内容的出口,作者称其为 插槽,可以应用在组合组件的场景中;

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

<div id="app">
  <todo>
    <todo-title slot="todo-title" v-bind:title="title"></todo-title>
    <todo-items slot="todo-items" v-for="item in todoItems" v-bind:item="item"></todo-items>
  </todo>
</div>


<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>

  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'],
    template: '<li>{{item}}</li>>'
  });

  let vm = new Vue({
    el: '#app',
    data: {
      title: "秦老师课程",
      todoItems: ['狂神说Java', '狂神说前端', '狂神说Linux']
    }
  });
</script>

</body>
</html>

8、自定义事件

数据项在 Vue 实例中,但删除操作要在组件中完成,那么组件如何才能删除 Vue 实例中的数据呢?此时就涉及 参数传递 和 事件分发了, Vue 为我们提供了自定义事件的功能帮我们解决这个问题。

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

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

<div id="app">
  <todo>
    <todo-title slot="todo-title" v-bind:title="title"></todo-title>
    <todo-items slot="todo-items" v-for="(item, index) in todoItems"
                v-bind:item="item" v-bind:index="index" v-on:remove="removeItems(index)"></todo-items>
  </todo>
</div>


<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>

  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>{{item}} <button @click="remove">删除</button></li>>',
    methods: {
      remove: function(index) {
        this.$emit('remove', index);
      }
    }
  });

  let vm = new Vue({
    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>

9、第一个Vue-cli项目

vue-cli 是官方提供的一个脚手架,用于快速生成一个vue项目模板。

环境

确认node.js 安装成功:

  • cmd 下输入 node -v ,查看是否能够正确打印出版本号即可!
  • cmd 下输入 npm -v ,查看是否能够正确打印出版本号即可!

这个npm,就是一个软件包管理工具,就和linux下的apt软件安装差不多。

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

# -g 就是全局安装
npm install cnpm -g

# 或使用如下语句解决 npm 速度慢的问题
npm install --registry=https://registry.npm.taobao.org

安装 Vue-cli

cnpm install vue-cli -g

# 测试是否安装成功
# 查看可以基于哪些模块创建 vue 应用程序,通常我们选择 webpack
vue list

image-20221128113805075

第一个 vue-cli 应用程序

1、创建一个Vue项目,我们随便建立一个空的文件夹在电脑上

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

# 这里的 myvue 是项目名称,可以根据自己的需求起名
vue init webpack myvue

一路都选择no即可

3、初始化并运行

cd myvue
npm install # 安装依赖环境
npm run dev # 运行项目

10、Webpack

本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包器。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图,其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。

ES6 模块的设计思想,是尽量静态化,使编译时就能确定模块的依赖关系,以及输入和输出的变量。

import "jquery";
export function doStuff() {}
module "localModule" {}

安装 Webpack

Webpack 是一款模块加载器兼打包工具,它能把各种资源,如 JS、JSX、ES6、SASS、LESS图片等都作为模块来处理和使用。

安装:

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

测试成功:

  • webpack -v
  • webpack-cli -v

配置

创建 webpack.config.js 配置文件

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

直接运行 webpack 命令打包

使用 webpack

1、创建项目

2、创建一个名为 modules 的目录,用于放置 JS 模块等资源文件

3、在 modules 下创建模块文件,如 hello.js,用于编写 JS 模块相关代码

// 暴露一个方法:sayHi
exports.sayHi = function () {
    document.write("<div>Hello WebPack</div>");
};

4、在 modules 下创建一个名为 main.js 的入口文件,用于打包时设置 entry 属性

//require 导入一个模块,就可以调用这个模块中的方法了
let hello = require("./hello");
hello.sayHi();

5、在项目目录下创建 webpack.config.js 配置文件,使用 webpack 命令打包

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

6、在项目目录下创建 html 页面,如 index.html,导入 webpack 打包后的 js 文件

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

<script src="dist/js/bundle.js"></script>

</body>
</html>

7、在IDEA控制台中直接执行 webpack,如果失败,就是用管理员权限运行即可。

# 参数  --watch 用于监听变化
webpack --watch

11、vue-router 路由

vue-router 是 vue.js 官方的路由管理器。它和 vue.js 的核心深度集成,让构建单页面应用变得易如反掌。

安装

vue-router 是一个插件包,所以需要使用 npm/cnpm 来进行安装。打开命令行工具,进入项目目录,输入下面命令

npm install vue-router --save-dev

如果在一个模块化工程中使用它,必须要通过 Vue.use() 明确地安装功能:

import Vue from 'vue'
import VueRouter from 'vue-router'

Vue.use(VueRouter);

测试

1、新建一个Vue工程

vue init webpack hello-vue

2、components 目录下存放自己编写的组件

3、定义一个 Content.vue 的组件

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

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

4、安装路由,在 src 目录下,新建一个文件夹: router ,专门存放路由

import Vue from 'vue'
// 导入路由插件
import Router from 'vue-router'
// 导入上面定义的组件
import Content from '../components/Content'
import Main from '../components/main'
// 安装路由
Vue.use(Router)
// 配置路由
export default new Router({
    routes: [
        {
            // 路由路径
            path: '/content',
            // 路由名称
            name: 'Content',
            // 跳转到组件
            component: Content
        },
        {
            // 路由路径
            path: '/main',
            // 路由名称
            name: 'Main',
            // 跳转到组件
            component: Main
        }
    ]
});

5、在 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/>'
});

6、在 App.vue 中使用路由

<template>
	<div id='app'>
        <h1>Vue-Router</h1>
        <!-- 设置跳转路径 -->
        <router-link to="/main">首页</router-link>
        <router-link to="/content">内容页</router-link>
        <!-- 展示内容 -->
        <router-view></router-view>
    </div>
</template>

<script>
    export default {
        name: 'App'
    }
</script>

<style>
    #app {
        ...
    }    
</style>

12、快速上手

结合 ElementUI 组件库,实战模拟

创建工程

注意:命令行要在管理员模式运行

1、创建一个名为 hello-vue 的工程

vue init webpack hello-vue

2、安装依赖,需要安装 vue-routerelement-uisass-loadernode-sass 四个插件

# 进入目录
cd hello-vue
# 安装 vue-router
npm install vue-router --save-dev
# 安装 element-ui
npm i element-ui -S
# 安装依赖
npm install
# 安装 SASS 加载器
cnpm install sass-loader node-sass --save-dev
# 启动测试
npm run dev

指令解释:

image-20221130172354316

3、创建登录页面 ,其中 el-* 为 ElementUI组件

<template>
  <div>
    <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-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'}
          ],
          password: [
            {required: true, message: " 密码不可为空 ", trigger: 'blur'}
          ]
        },
        //对话框显示和隐藏
        dialogVisible: false
      }
    },
    methods: {
      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;
  }

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

4、配置路由

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

import Main from '../views/Main'
import Login from '../views/Login'

Vue.use(Router);

export default new Router({
    routes: [
        {
            path: '/main',
            component: Main
        },
        {
            path: '/login',
            component: Login
        }
    ]
});

13、路由嵌套

import Vue from 'vue'
import VueRouter 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 Telephone from '../views/user/Telephone'
 
Vue.use(VueRouter)
 
export default new VueRouter({
  routes: [
    {
      path: '/main',
      component: Main,
      children: [ // 嵌套路由
        {path: '/user/profile', component: UserProfile},
        {path: '/user/list', component: UserList},
        {path: '/user/telephone', component: Telephone}
      ]
    },
    {
      path: '/login',
      component: Login
    }
  ]
})

14、参数传递及重定向

方式一:

// 传递 
<!--name-传组件名 params传递参数,需要对象: v-bind-->
 <router-link :to="{name: 'UserProfile', params: {id: 1}}">个人信息</router-link>
 
 
// 接收
import Vue from 'vue'
import VueRouter 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 Telephone from '../views/user/Telephone'
 
Vue.use(VueRouter)
 
export default new VueRouter({
  routes: [
    {
      path: '/main',
      component: Main,
      children: [ // 嵌套路由
        {path: '/user/profile:id', name: 'UserProfile', component: UserProfile},
        {path: '/user/list', component: UserList},
        {path: '/user/telephone', component: Telephone}
      ]
    },
    {
      path: '/login',
      component: Login
    }
  ]
})
 
// 展示
<template>
  <div>
    <h1>个人信息</h1>
    {{$route.params.id}}
  </div>
</template>
 
<script>
export default {
  name: "UserProfile"
}
</script>
 
<style scoped>
 
</style>

方式二:

// 设置props
import Vue from 'vue'
import VueRouter 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 Telephone from '../views/user/Telephone'
 
Vue.use(VueRouter)
 
export default new VueRouter({
  routes: [
    {
      path: '/main',
      component: Main,
      children: [ // 嵌套路由
        {path: '/user/profile:id', name: 'UserProfile', component: UserProfile, props: true},
        {path: '/user/list', component: UserList},
        {path: '/user/telephone', component: Telephone}
      ]
    },
    {
      path: '/login',
      component: Login
    }
  ]
})
 
// 绑定id
<template>
  <div>
    <h1>个人信息</h1>
    {{$route.params.id}}<br/>
    {{id}}
  </div>
</template>
 
<script>
export default {
  props: ['id'],
  name: "UserProfile"
}
</script>
 
<style scoped>
 
</style>
 
posted @ 2022-12-01 16:15  柯文先生  阅读(36)  评论(0)    收藏  举报