Vue2入门_unpkg vue-程序员宅基地

技术标签: 前端框架  vue  前端  vue.js  前端学习笔记  javascript  

Vue.js

本文基于[email protected]

一、Vue概述

来看看官网的描述:

Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。

后端开发,常用MVC模式。

前端开发,也有一些人把这个模式搬到了前端。

做一个Web应用,View 和 Model是必要的,后端给前端提供Model, 这个数据要这么渲染到视图上呢?于是,出现了MVVM模式。

在这里插入图片描述

这个VM就是ViewModel,也就是关于视图的数据。

而Vue就是VM的实现

Vue的虚拟dom,比直接操作dom更快,加载页面更迅速,并且vue会自动响应数据的变化,我们不需要刷新页面也能让数据渲染到页面上。

二、Hello Vue

学习Vue最好的方式就是写代码,先来一个Hello Vue:

hello.html:

<!DOCTYPE html>
<html lang = "en">
<head>
    <meta charset = "UTF-8">
    <title>hello</title>
    <script src="https://unpkg.com/[email protected]/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        {
   { message }}
    </div>

    <script>
        let vm = new Vue({
      
            el:"#app",
            data: {
      
                message:"Hello Vue!"
            }
        });
    </script>
</body>
</html>

创建一个Vue实例,安装到指定id上,然后就可以在其中用 { {}} 取出data中的值。

三、基础指令、语法

3.1 v-once、v-html

v-onece指令可以一次性的插值,当数据改变时,插值处的内容不会更新:

<!DOCTYPE html>
<html lang = "en">
<head>
    <meta charset = "UTF-8">
    <title>v-once指令</title>
    <script src="https://unpkg.com/[email protected]/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        <p v-once>{
   { msg }}</p>
    </div>
    <script>
        const vm = new Vue({
      
            el:'#app',
            data:{
      
                msg:"666"
            }
        })
    </script>
</body>
</html>

即使数据改变,视图也不会变:

在这里插入图片描述

v-html指令可以插入html,而不是纯文本:

<!DOCTYPE html>
<html lang = "en">
<head>
    <meta charset = "UTF-8">
    <title>v-html指令</title>
    <script src="https://unpkg.com/[email protected]/dist/vue.js"></script>
</head>
<body>
<div id="app">
    <p>{
   { msg }}</p>
    <p v-html="msg">}</p>
</div>
<script>
    const vm = new Vue({
      
        el:'#app',
        data:{
      
            msg:"<h1>v-html指令</h1>"
        }
    })
</script>
</body>
</html>

效果:

在这里插入图片描述

3.2 v-bind

对于html标签的属性,双大括号的语法已经不起作用,这个时候应该使用v-bind指令:

<!DOCTYPE html>
<html lang = "en">
<head>
    <meta charset = "UTF-8">
    <title>Title</title>
    <script src="https://unpkg.com/[email protected]/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        <span v-bind:title="message">鼠标在这悬停一下</span>
    </div>

    <script>
        const vm = new Vue({
      
            el:'#app',
            data: {
      
                message:"页面加载于" + new Date().toLocaleString()
            }
        });
    </script>
</body>
</html>

效果:

在这里插入图片描述

<span v-bind:title="message">鼠标在这悬停一下</span>
<!-- 可缩写为 -->
<span :title="message">鼠标在这悬停一下</span>

3.3 v-if、v-else-if、v-else

<!DOCTYPE html>
<html lang = "en">
<head>
    <meta charset = "UTF-8">
    <title>判断</title>
    <script src="https://unpkg.com/[email protected]/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        <p v-if="ok === 1">OK!</p>
        <p v-else-if="ok === 2">NO!</p>
        <p v-else>ERROR!</p>
    </div>

    <script>
        const vm = new Vue({
      
            el : '#app',
            data : {
      
                ok : 1
            }
        })
    </script>
</body>
</html>

和其他编程语言的判断是一样的道理。

3.4 v-for

可以遍历数组:

<!DOCTYPE html>
<html lang = "en">
<head>
    <meta charset = "UTF-8">
    <title>v-for指令</title>
    <script src="https://unpkg.com/[email protected]/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        <ul>
            <li v-for="el in array">
                {
   {el.text}}
            </li>
        </ul>
    </div>
    <script>
        const vm = new Vue({
      
            el : '#app',
            data : {
      
                array : [
                    {
      text : 'js'},
                    {
      text : 'vue'},
                    {
      text : 'java'}
                ]
            }
        });
    </script>
</body>
</html>

"el in array"意思就是将data中的array中的每个元素取出来作为el。

效果:

在这里插入图片描述

3.5 v-on

v-on可以监听事件,从而调用某个函数做某些参数,例如单击按钮增加单击次数:

<!DOCTYPE html>
<html lang = "en">
<head>
    <meta charset = "UTF-8">
    <title>v-on事件监听</title>
    <script src="https://unpkg.com/[email protected]/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        <button v-on:click="count">
            点击 {
   { counts }} 次
        </button>
    </div>
    <script>
        const vm = new Vue({
      
            el:'#app',
            data:{
      
                counts : 0
            },
            methods:{
      
                count:function () {
      
                    this.counts++;
                }
            }
        })
    </script>
</body>
</html>

v-on也可以缩写:

<button @click="count">
    点击 {
   { counts }} 次
</button>

<!-- @ 就相当于 v-on: -->

3.6 v-model

v-model指令可以让视图和数据双向绑定:

例如我在文本框中输入内容,则data中的message就会改变,message改变,那么p标签的视图就会改变。

<!DOCTYPE html>
<html lang = "en">
<head>
    <meta charset = "UTF-8">
    <title>数据绑定</title>
    <script src="https://unpkg.com/[email protected]/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        <input type="text" v-model="message">
        <p> {
   { message }} </p>
    </div>
    
    <script>
        const vm = new Vue({
      
            el:'#app',
            data:{
      
                message : "v-model双向绑定"
            }
        })
    </script>
</body>
</html>

又或是多选框:

<!DOCTYPE html>
<html lang = "en">
<head>
    <meta charset = "UTF-8">
    <title>practise</title>
    <script src="https://unpkg.com/[email protected]/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        <label>
            <input type="checkbox" name="hobbies" v-model="hobbies" value="篮球">
            篮球
        </label>
        <label>
            <input type="checkbox" name="hobbies" v-model="hobbies" value="健身">
            健身
        </label>
        <label>
            <input type="checkbox" name="hobbies" v-model="hobbies" value="数学">
            数学
        </label>
        <p>你的爱好是: {
   { hobbies }}</p>
    </div>
    <script>
        const vm = new Vue({
      
            el:'#app',
            data:{
      
                hobbies:[]
            }
        })
    </script>
</body>
</html>

多选框的值改变,那么data中的hobbies会改变,Vue又将hobbies渲染到p标签内。

或是下拉列表:

<!DOCTYPE html>
<html lang = "en">
<head>
    <meta charset = "UTF-8">
    <title>practise</title>
    <script src="https://unpkg.com/[email protected]/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        <select v-model="checked">
            <option value="" disabled selected>---- 请选择 ----</option>
            <option>A</option>
            <option>B</option>
            <option>C</option>
            <option>D</option>
        </select>
        <p>你的选择:{
   { checked }}</p>
    </div>
    
    <script>
        const vm = new Vue({
      
            el:'#app',
            data:{
      
                checked:""
            }
        })
    </script>
</body>
</html>

一样的道理。

四、组件

4.1 组件基础

组件是可复用的Vue实例。

先来个例子:

<!DOCTYPE html>
<html lang = "en">
<head>
    <meta charset = "UTF-8">
    <title>组件案例</title>
    <script src="https://unpkg.com/[email protected]/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        <click-test></click-test>
        <click-test></click-test>
        <click-test></click-test>
        <click-test></click-test>
        <click-test></click-test>
        <click-test></click-test>
    </div>
    <script>
        Vue.component('click-test', {
      
            template:"<button @click='count++'>{
      { count }}</button>",
            data:function (){
      
                return {
      count:0};
            }
        })
        new Vue({
       el:'#app' })
    </script>
</body>
</html>

实现了组件复用,一个注意点就是,data要通过函数来返回数据,不然大家共享一个count就会造成很多错误,并且最后别忘了注册组件(new一个Vue)。

再来个稍微复杂点的例子:

<!DOCTYPE html>
<html lang = "en">
<head>
    <meta charset = "UTF-8">
    <title>综合</title>
    <script src="https://unpkg.com/[email protected]/dist/vue.js"></script>
</head>
<body>
<div id="app">
    <try v-for="item in items" :el="item"></try>
</div>
<script>
    Vue.component('try', {
      
        props:['el'],
        template:`<ul>
<li>{
       { el }}</li>
</ul>`
    })
    new Vue({
      
        el:'#app',
        data:{
      
            items : ["vue", 666, '组件']
        }
    })
</script>
</body>
</html>

props给组件增加属性,在这个例子中相当于要接收的参数,我们将item传给它。

4.2 插槽

在第一个例子中,能记录鼠标点击的次数。但是只有一个数字,假如我们要在数字之前插入数据,这样写是不行的:

<click-test>click times:</click-test>

这个时候,我们应该给这些数据留个插槽(<slot></slot>标签):

Vue.component('click-test', {
    
    template:"<button @click='count++'><slot></slot>{
    { count }}</button>",
    data:function (){
    
        return {
    count:0};
    }
})

效果:

在这里插入图片描述

后备内容:

就是给slot赋一个默认值,如:

<!DOCTYPE html>
<html lang = "en">
<head>
    <meta charset = "UTF-8">
    <title>组件案例</title>
    <script src="https://unpkg.com/[email protected]/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        <click-test></click-test>
    </div>
    <script>
        Vue.component('click-test', {
      
            template:"<button @click='count++'><slot>hello:</slot>{
      { count }}</button>",
            data:function (){
      
                return {
      count:0};
            }
        })
        new Vue({
       el:'#app' })
    </script>
</body>
</html>

效果:

在这里插入图片描述

如果改成:

<click-test>click times:</click-test>

效果:

在这里插入图片描述

具名插槽:

假如现在想在 次数后面添加东西,也就是再加一个插槽,我们可以通过给插槽取名字来区别插槽:

<!DOCTYPE html>
<html lang = "en">
<head>
    <meta charset = "UTF-8">
    <title>组件案例</title>
    <script src="https://unpkg.com/[email protected]/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        <click-test>
            <template v-slot:pre>
                click times:
            </template>
            <template v-slot:next></template>
        </click-test>
    </div>
    <script>
        Vue.component('click-test', {
      
            template:"<button @click='count++'><slot name='pre'>hello:</slot>{
      { count }}<slot name='next'>hi</slot></button>",
            data:function (){
      
                return {
      count:0};
            }
        })
        new Vue({
       el:'#app' })
    </script>
</body>
</html>

用name给插槽取名字后,在template标签中使用v-slot指令来指定插入哪里。

综合案例:

<!DOCTYPE html>
<html lang = "en">
<head>
    <meta charset = "UTF-8">
    <title>综合</title>
    <script src="https://unpkg.com/[email protected]/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        <todo>
            <template v-slot:todo-title>
                <my-title></my-title>
            </template>
            <template v-slot:list-items>
                <my-list v-for="item in items" :item="item"></my-list>
            </template>
        </todo>
    </div>
    <script>
        Vue.component('todo', {
      
            template:`<div>
<slot name="todo-title"></slot>
<ul>
<slot name="list-items"></slot>
</ul>
</div>`
        });
        Vue.component('my-title', {
      
            template: `<h3>Vue如此简单</h3>`
        })
        Vue.component('my-list', {
      
            props:['item'],
            template:`<li> {
       { item }} </li>`
        })
        Vue.component('')
        const vm = new Vue({
      
            el:'#app',
            data() {
      
                return {
      
                    items:["Vue", "js", "simple"]
                }
            }
        });
    </script>
</body>
</html>

效果:

在这里插入图片描述

v-slot也有简写,可以将v-slot:简写为#:

<div id="app">
    <todo>
        <template #todo-title>
            <my-title></my-title>
        </template>
        <template #list-items>
            <my-list v-for="item in items" :item="item"></my-list>
        </template>
    </todo>
</div>

五、生命周期

在这里插入图片描述

每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等。同时在这个过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会。

来试试在created和updated的时候添加代码:

<!DOCTYPE html>
<html lang = "en">
<head>
    <meta charset = "UTF-8">
    <title>lifecycle</title>
    <script src="https://unpkg.com/[email protected]/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        <button @click="msg++">{
   { msg }}</button>
    </div>

    <script>
        new Vue({
      
            el:'#app',
            data:{
      
                msg:0
            },
            created:function () {
      
                alert("Vue实例创建了!")
            },
            updated:function () {
      
                alert("数据变化了")
            }
        })
    </script>
</body>
</html>

我们在进入页面的时候会弹出:

在这里插入图片描述

单击按钮,会弹出:

在这里插入图片描述

六、Axios

Axios 是一个基于 promise 网络请求库,作用于node.js 和浏览器中。 它是 isomorphic 的(即同一套代码可以运行在浏览器和node.js中)。在服务端它使用原生 node.js http 模块, 而在客户端 (浏览端) 则使用 XMLHttpRequests。

因为Vue的作者(尤雨溪)注重SoC(关注点分离)原则,关注点在视图层,所以Vue不包含ajax通信功能。官方建议使用axios来通信。

axios有以下特性:

  • 从浏览器创建 XMLHttpRequests
  • 从 node.js 创建 http 请求
  • 支持 Promise API
  • 拦截请求和响应
  • 转换请求和响应数据
  • 取消请求
  • 自动转换JSON数据
  • 客户端支持防御XSRF

理论生涩,直接敲码:

现在有这么一个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/"
  }
  ]
}

html:

<!DOCTYPE html>
<html lang = "en">
<head>
    <meta charset = "UTF-8">
    <title>Title</title>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <script src="https://unpkg.com/[email protected]/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        <li v-for="item in message.links">{
   { item }}</li>
    </div>
    <script>
        const vm = new Vue({
      
            el:'#app',
            data:{
      
                message:null
            },
            created:function () {
      
                axios.get('/data.json').then(response=>(this.message = response.data))
            }
        })
    </script>
</body>
</html>

我们在Vue实例创建时向/data.json发送一个GET请求,成功后接收返回信息response,通过response.data取出数据并赋值到message中。

data(){return(message:null)} 和 data:{message:null}的区别:

第一种大家都调用同一个函数,但返回的对象是不同的对象。

第二种大家都公用这一个对象,可能造成数据污染。

效果:

在这里插入图片描述

七、计算属性

模板内可以写逻辑,比如:

<div id="example">
  {
   { message.split('').reverse().join('') }}
</div>

一处两处还好,如果大量使用,则难以维护,于是,Vue提供了计算属性

我将计算属性理解为一个名词,可以被计算的属性,这个属性的值通过函数的返回值赋予:

<!DOCTYPE html>
<html lang = "en">
<head>
    <meta charset = "UTF-8">
    <title>computed</title>
    <script src="https://unpkg.com/[email protected]/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        <input type="text" v-model="message">
        <p>{
   { reverseMessage }}</p>
    </div>
    <script>
        const vm = new Vue({
      
            el:'#app',
            data() {
      
                return {
      
                    message:"hello"
                }
            },
            computed:{
      
                reverseMessage:function () {
      
                    return this.message.split("").reverse().join("");
                }
            }
        })
    </script>
</body>
</html>

细节:

计算属性名和methods名不能重复,不然计算属性无效,和data中也不能重复。

计算属性被赋值后,值就会被保存在缓存中,只有在相关的data改变时,它才会改变。

计算属性看起来很像methods,但methods无论是否有相关的data变化,只要data变化,就会重新调用,在某些时候浪费内存。

如:

<!DOCTYPE html>
<html lang = "en">
<head>
    <meta charset = "UTF-8">
    <title>和methods的区别</title>
    <script src="https://unpkg.com/[email protected]/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        <input type="text" v-model="message">
        <p>{
   { time1() }}</p>
        <p>{
   { time2 }}</p>
    </div>

    <script>
        const vm = new Vue({
      
            el:'#app',
            data() {
      
                return {
      
                    message:"methods and computed"
                }
            },
            methods:{
      
                time1:function () {
      
                    return Date.now();
                }
            },
            computed:{
      
                time2:function () {
      
                    // this.message;
                    return Date.now();
                }
            }
        })
    </script>
</body>
</html>

我们将第30行左右的 this.message 注释掉,无论message如何变化,time2始终不变,而time1却一直在变,如果将它打开,那么time1和time2都会在message变化时变化。

八、自定义事件

<!DOCTYPE html>
<html lang = "en">
<head>
    <meta charset = "UTF-8">
    <title>综合</title>
    <script src="https://unpkg.com/[email protected]/dist/vue.js"></script>
</head>
<body>
   <div id="app">
        <todo>
            <template #todo-title>
                <my-title :title="title"></my-title>
            </template>
            <template #list-items>
                <my-list v-for="(item, index) in items" :item="item" :index="index" @delete="remove(index)"></my-list>
            </template>
        </todo>
    </div>
    <script>
        Vue.component('todo', {
      
            template:`<div>
<slot name="todo-title"></slot>
<ul>
<slot name="list-items"></slot>
</ul>
</div>`
        });
        Vue.component('my-title', {
      
            props: ['title'],
            template: `<h3>{
       { title }}</h3>`
        })
        Vue.component('my-list', {
      
            props:{
      
                item:null,
                index:null
            },
            template:`<li> {
       { index }} === {
       { item }} <button>remove</button></li>`,
            methods: {
      
               
            }
        })
        Vue.component('')
        const vm = new Vue({
      
            el:'#app',
            data() {
      
                return {
      
                    items:["Vue", "js", "simple"],
                    title:"Vue如此简单"
                }
            },
            methods:{
      
              
            }
        });
    </script>
</body>
</html>

现在有这么一个组件化的Vue页面,我们如何才能删除其中的元素呢?

在这里插入图片描述

都想的到,给remove按钮增加一个事件,然后调用methods里面的方法删除元素。

但是,组件里的方法怎么才能删掉Vue实例里面的data呢?

这个时候自定义事件就有用了:

<!DOCTYPE html>
<html lang = "en">
<head>
    <meta charset = "UTF-8">
    <title>综合</title>
    <script src="https://unpkg.com/[email protected]/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        <todo>
            <template #todo-title>
                <my-title :title="title"></my-title>
            </template>
            <template #list-items>
                <my-list v-for="(item, index) in items" :item="item" :index="index" @delete="remove(index)"></my-list>
            </template>
        </todo>
    </div>
    <script>
        Vue.component('todo', {
      
            template:`<div>
<slot name="todo-title"></slot>
<ul>
<slot name="list-items"></slot>
</ul>
</div>`
        });
        Vue.component('my-title', {
      
            props: ['title'],
            template: `<h3>{
       { title }}</h3>`
        })
        Vue.component('my-list', {
      
            props:{
      
                item:null,
                index:null
            },
            template:`<li> {
       { index }} === {
       { item }} <button @click="event">remove</button></li>`,
            methods: {
      
                event:function () {
      
                    this.$emit('delete')
                }
            }
        })
        Vue.component('')
        const vm = new Vue({
      
            el:'#app',
            data() {
      
                return {
      
                    items:["Vue", "js", "simple"],
                    title:"Vue如此简单"
                }
            },
            methods:{
      
                remove:function (index){
      
                    this.items.splice(index, 1);
                }
            }
        });
    </script>
</body>
</html>

我们通过this.$emit('delete')定义一个名为delete的事件并触发,在鼠标点击按钮时,调用event方法创建这个事件,并触发。

触发了前端的delete事件后,调用Vue实例的remove方法,就删除了该数据。

九、Vue-cli

Vue-cli是一个Vue.js的标准开发工具。

9.1 第一个Vue-cli程序

首先需要node环境,可以去node官网下载。

有了node的环境后,就可以把vue-cli下载下来:

npm install vue-cli -g

可以通过vue list命令查看可以选择的模板:

在这里插入图片描述

然后在想要创建的目录下输入以下命令(基于webpack模板):

vue init webpack myvue

表示创建一个名为myvue的项目。

接下来他会提示我们设置项目的名字,描述等等,一些选择我选择no,因为想要体验自己创建的感觉。

在这里插入图片描述

然后 cd 到刚刚创建的项目下:

npm install

依赖安装完成后,就可以运行了:

npm run dev

然后就可以访问这个url进入项目:

在这里插入图片描述

这就是我们的第一个vue-cli程序:

在这里插入图片描述

十、 webpack

webpack是一款模块加载器兼打包工具,能把各种资源(JS、JSX、ES6、SASS、LESS、Jpg……)作为模块来处理使用。

10.1 安装webpack

# 安装webpack
npm install webpack -g
# 安装webpack客户端
npm install webpack-cli -g

安装完成后可以用webpack -v来检查是否安装成功。

10.2 使用webpack

  1. 创建一个项目(创建一个文件夹)

  2. 在项目中创建一个modules文件夹

  3. modules中写几个js文件:

    • hello.js:

      exports.sayHi = function () {
              
          document.write("<h1>hello world!</h1>>")
      }
      

      表示暴露这个方法,在其他文件里面可以引入此方法

    • main.js:

      var say = require("./hello");
      
      say.sayHi();
      

      引入hello模块,然后就可以调用刚刚暴露的方法。

  4. 根目录下创建webpack配置文件

    webpack.config.js:

    module.exports = {
          
        entry:'./modules/main.js',
        output:{
          
            filename:"./js/bundle.js"
        }
    }
    
  5. 在终端执行webpack命令打包项目

  6. 创建一个index.html测试:

    <!DOCTYPE html>
    <html lang = "en">
    <head>
        <meta charset = "UTF-8">
        <title>Title</title>
        <script src="dist/js/bundle.js"></script>
    </head>
    <body>
    
    </body>
    </html>
    

    效果:

    在这里插入图片描述

十一、vue-router

Vue Router 是 Vue.js 的官方路由。它与 Vue.js 核心深度集成,让用 Vue.js 构建单页应用变得轻而易举。功能包括:

  • 嵌套路由映射
  • 动态路由选择
  • 模块化、基于组件的路由配置
  • 路由参数、查询、通配符
  • 展示由 Vue.js 的过渡系统提供的过渡效果
  • 细致的导航控制
  • 自动激活 CSS 类的链接
  • HTML5 history 模式或 hash 模式
  • 可定制的滚动行为
  • URL 的正确编码

说起来吓人,我们先来看看基础用法:

先用vue-cli创建一个vue项目,如果没有安装vue-router的话,就安装:

npm install vue-router@3

因为是vue2.x版本所以对应vue-router3.x版本。

然后就可以开始了:

  1. 在components下写个组件:

    <template>
      <h2>终于搞懂路由了</h2>
    </template>
    
    <script>
    export default {
            
      name: "yang"
    }
    </script>
    
    <style scoped>
    
    </style>
    
  2. 在src目录下创建router目录,在router目录下创建路由配置文件index.js:

    import Vue from 'vue';
    import VueRouter from "vue-router";
    
    import yang from "../components/yang";
    
    Vue.use(VueRouter);
    
    export default new VueRouter({
          
      routes: [
        {
          
          path:'/yang',
          component:yang
        }
      ]
    });
    

    关键:引入vue、vue-router以及需要路由到的组件。

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

    导入文件夹就可以了,会自动扫描配置文件。

  4. 到App.vue中使用:

    <template>
      <div id="app">
        <h1>Vue-router</h1>
        <router-link to="/yang">点我</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>
    

    router-link和router-view缺一不可,router-link表示跳转到哪个组件,router-view表示这个组件的视图显示的位置。

  5. 效果:

    在这里插入图片描述

    当然,还可以配置多个路由,只需要添加组件、在index.js中配置路由、在App.vue中使用就完事了。

十二、Element UI

Element-UI和Vue配合可以快速写出好看的页面。

  1. 创建vue项目

  2. 安装依赖

    npm install
    
  3. 安装vue-router

    npm install vue-router
    
  4. 安装element-ui

    npm i element-ui -S
    
  5. 安装sass

    npm install sass-loader node-sass
    

准备完毕,就可以开始使用了:

  1. 创建首页的组件Main

    <template>
      <h1>首页</h1>
    </template>
    
    <script>
    export default {
            
      name: "Main"
    }
    </script>
    
    <style scoped>
    
    </style>
    
  2. 到element-ui中复制一个登录组件稍作修改:

    <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>
    
  3. 在src下创建router目录,在router下创建index.js配置文件:

    import Vue from 'vue';
    import VueRouter from "vue-router";
    import Main from "../components/Main";
    import Login from "../components/Login";
    
    Vue.use(VueRouter);
    
    export default new VueRouter({
          
      routes:[
        {
          
          path:'/main',
          component:Main
        },
        {
          
          path:'/login',
          component:Login
        }
      ]
    })
    
  4. 在main.js中引入需要使用的模块:

    import Vue from 'vue'
    import App from './App'
    import router from "./router"
    import ElementUI from 'element-ui'
    import 'element-ui/lib/theme-chalk/index.css'
    
    Vue.config.productionTip = false
    
    Vue.use(router)
    Vue.use(ElementUI)
    
    new Vue({
          
      el: '#app',
      router,
      render:h => h(App)
    })
    
  5. 在App.vue中使用:

    <template>
      <div id="app">
    
        <router-view></router-view>
    
      </div>
    </template>
    
    <script>
    
    export default {
      name: 'App'
    }
    </script>
    
    <style>
    
    </style>
    
  6. 启动项目,访问/login:

    npm run dev
    

    在这里插入图片描述

    可以尝试输入点什么或是不输入,有不同的提示哦。

十三、参数传递、重定向

13.1 接收参数两种方式

传递参数有多种方式,这里说两种。

  1. 第一种,通过绑定to,to传递参数对象给组件,组件取出参数:

Main.vue中的关键改动:

<router-link :to="{name:'UserProfile', params:{id: 1}}">
    <el-menu-item index="1-1">
 	 个人信息
	</el-menu-item>
</router-link>

index.js:

{
    
  path:'/user/profile/:id',
  name:'UserProfile',
  component:UserProfile
}

profile.vue取值:

<template>
  <div>
    <h1>个人信息</h1>
    {
   { $route.params.id }}
  </div>

</template>
<script>
export default {
      
  name: "UserProfile"
}
</script>
<style scoped>
</style>
  1. 传递是一样的,这次可以通过props取值,不用再{ { $route.params.id }}这种方式

    只需要更改一下配置:

    {
          
      path:'/user/profile/:id',
      name:'UserProfile',
      component:UserProfile,
      props:true
    }
    

    然后再profile中这样取值:

    <template>
      <div>
        <h1>个人信息</h1>
        {
         { id }}
      </div>
    
    </template>
    <script>
    export default {
            
      props:['id'],
      name: "UserProfile"
    }
    </script>
    <style scoped>
    </style>
    

效果都是一样的:

在这里插入图片描述

13.2 重定向

配置一下redirect到哪就完事了:

增加一个返回首页的按钮:

<router-link to="/goHome">
<el-menu-item index="1-3">返回首页</el-menu-item>
</router-link>

配置 /goHome 重定向到 /main

{
    
  path:'/goHome',
  redirect:'/main'
}

成功

十四、添加404页面、路由钩子

  1. 添加404页面:

    也就是添加一个404的组件,然后在访问不存在的地址的时候展示:

    404.vue:

    <template>
      <div>
        <h1>404 not found</h1>
        <hr/>
      </div>
    </template>
    
    <script>
    export default {
            
      name: 'NotFound'
    }
    </script>
    
    <style scoped>
      div {
            
        text-align: center;
      }
    </style>
    

    配置:

    {
          
      path:'/*',
      component:NotFound
    }
    

    这样就可以在访问一些不存在的页面的时候展示404页面。

    我们可以注意到url上始终有个#号,我们只需要在配置中加上mode:"history"就ok:

    index.js

    export default new VueRouter({
          
      mode:"history",
      routes:[
        {
          
          path:'/main/:name',
          props:true,
          component:Main,
          children:[
            {
          
              path:'/user/profile/:id',
              name:'UserProfile',
              component:UserProfile,
              props:true
            },
            {
          
              path:'/user/list',
              component:UserList
            },
            {
          
              path:'/goHome',
              redirect:'/main'
            }
          ]
        },
        {
          
          path:'/',
          component:Login
        },
        {
          
          path:'/*',
          component:NotFound
        }
      ]
    })
    
  2. 路由钩子

    之前我们学习了很多生命周期钩子,路由也有钩子,我们可以在进入路由前或是离开路由前等等情况下添加操作,比如进入路由前使用axios请求数据:

    我们先模拟一个数据,放在static/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/"
      }
      ]
    }
    

    然后

    写一个axios请求该数据,并且输出在控制台的方法,然后在路由钩子中调用它:

    <template>
      <div>
        <h1>个人信息</h1>
        {
         { id }}
      </div>
    
    </template>
    <script>
    import axios from "axios";
    
    export default {
            
      props:['id'],
      name: "UserProfile",
      beforeRouteEnter:function (to, from, next) {
            
        console.log("进入路由前")
        next(vm => (vm.getData()))
      },
      beforeRouteLeave:function (to, from, next) {
            
        console.log("离开路由前")
        next()
      },
      methods:{
            
        getData:function () {
            
          axios.get("http://localhost:8080/static/mock/data.json").then(response=>(console.log(response.data)))
        }
      }
    }
    </script>
    <style scoped>
    </style>
    

    测试成功。

    既然能够在控制台输出,自然也能展示到页面上等等。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/yangsf_/article/details/124969608

智能推荐

week1-01-复杂度1 最大子列和问题_给定k个整数组成的序列{ n 1 , n 2 , ..., n k },“连续子列”被定义为{ n -程序员宅基地

文章浏览阅读611次,点赞2次,收藏5次。给定K个整数组成的序列{ N 1 , N 2 , …, N K },“连续子列”被定义为{ N i, N i+1, …, N j},其中 1≤i≤j≤K。“最大子列和”则被定义为所有连续子列元素的和中最大者。例如给定序列{ -2, 11, -4, 13, -5, -2 },其连续子列{ 11, -4, 13 }有最大的和20。现要求你编写程序,计算给定整数序列的最大子列和。本题旨在测试各种不同的算法在各种数据情况下的表现。各组测试数据特点如下:本题旨在测试各种不同的算法在各种数据情况下的表现。各组测试数_给定k个整数组成的序列{ n 1 , n 2 , ..., n k },“连续子列”被定义为{ n i , n

高德地图画社区网格_地图数据网格化-程序员宅基地

文章浏览阅读369次。高德地图画网格区域_地图数据网格化

Lenovo Y50 (1080P) 安装 黑苹果 hackintosh macOS High Sierra 10.13.5 (17F77) 不适合双系统_mac os high sierra efi-程序员宅基地

文章浏览阅读1.2w次,点赞2次,收藏14次。Lenovo Y50 安装 黑苹果 macOS High Sierra 10.13.5 (17F77)1,黑苹果系统下载网站1,黑苹果系统下载网站提供黑苹果系统和驱动下载黑苹果系统下载【黑 Mac】..._mac os high sierra efi

图像去噪-深度学习之卷积神经网络-程序员宅基地

文章浏览阅读869次,点赞19次,收藏25次。卷积神经网络以其局部权值共享的特殊结构在语音识别和图像处理方面有着独特的优越性,其布局更接近于实际的生物神经网络,权值共享降低了网络的复杂性,特别是多维输入向量的图像可以直接输入网络这一特点避免了特征提取和分类过程中数据重建的复杂度。然后,当我们应用带有 3 个 5×5×3 的过滤器,以 1 的步幅进行处理时,我们也可以得到一个 32×32×3 的输出。对于每个2 * 2的窗口选出最大的数作为输出矩阵的相应元素的值,比如输入矩阵第一个2 * 2窗口中最大的数是6,那么输出矩阵的第一个元素就是6,如此类推。

Stable Diffusion从入门到卸载,一站式服务为你的AI绘画保驾护航!_stable diffusion怎么卸载-程序员宅基地

文章浏览阅读1k次。从入门到卸载,一站式服务,全程无忧!_stable diffusion怎么卸载

MATLAB APP开发的一些进阶技巧分享_matlab app设计-程序员宅基地

文章浏览阅读2.3k次,点赞5次,收藏13次。本文是专栏《有限单元法MATLAB程序设计》的“APP开发”部分,将从“主APP与子APP的并用”、“模态对话框的使用”、“操作提示的使用”及“利用中间文件传递信息”这四个部分来阐述笔者在个人APP开发过程中的技巧,及对“更友好的人机交互”的理解与应用。利用这套思路,可基本实现MATLAB APP“有程序即可移植”的快速移植法。_matlab app设计

随便推点

Linux中查看磁盘分区_linux查看boot分区-程序员宅基地

文章浏览阅读445次。Linux磁盘分区_linux查看boot分区

Python的魔法书:揭秘编程的基本咒语-程序员宅基地

文章浏览阅读348次,点赞7次,收藏5次。通过这些基础但强大的代码示例,你已经迈出了成为Python编程高手的第一步。变量让你能够存储和操作信息,运算符帮助你进行数学计算,字符串让你处理文本数据,而条件语句和循环则赋予你控制程序流程的能力。现在,拿起你的编程工具,开始你的Python探险之旅吧!在这条路上,无数的奥秘等着你去揭晓。

R语言入门_r语言y<-x[c(2,4)]-程序员宅基地

文章浏览阅读1.4k次,点赞5次,收藏19次。目录一、标量检验数据类型强制类型转换二、向量1.生成有规律的向量 2.使用seq(from,to,by)生成向量 3.rep(x,...) 生成满足条件的重复向量 4.逻辑向量的生成三、矩阵 矩阵的拉直 四、数组 五、数据框 六、因子 七、列表在R语言中赋值采用..._r语言y<-x[c(2,4)]

太阳高度角和太阳方位角-程序员宅基地

文章浏览阅读461次,点赞10次,收藏7次。关于12:00对称的时刻的太阳高度角相等,但是太阳方位角不相等,上午太阳方位角从90-180,下午太阳方位角从180-270。

Java图书管理系统(Java+MySQL)_图书管理系统java+mysql-程序员宅基地

文章浏览阅读478次。java图书管理系统_图书管理系统java+mysql

石英晶体振荡器【Multisim】【高频电子线路】_晶振在multisim中怎么找-程序员宅基地

文章浏览阅读3.8k次,点赞8次,收藏27次。5、实验内容5的测试结果表明:微调电容C2变化:C2由48%-50%-52%时,振荡频率基本不变,输出电压幅度先增大后减小。1、实验内容1的测试结果表明: 这是一个以石英晶体振荡器作为选频网络的反馈型振荡器,振荡频率=4.675MHz,输出电压幅度 = 8.865V。振荡频率基本不变,频率稳定度高。4、实验内容4的测试结果表明: R6变化时,振荡频率基本不变,输出电压幅度随R6增大而增大。3、实验内容3的测试结果表明: R2变化对振荡频率与输出电压幅度变化影响不大。4、掌握晶体震荡期频率稳定度高的特点。_晶振在multisim中怎么找

推荐文章

热门文章

相关标签