一、vue介绍

声明式渲染, 可以通过简单的模板语法来声明式地将数据渲染

  1. 第一个vue应用:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    </head>
    
    <body>
        <div id="app">
            {{ message }}
        </div>
    </body>
    
    <script>
        var app = new Vue({
            el: '#app',
            data: {
                message: '第一个应用: Hello Vue!'
            }
        })
    </script>
    </html>
    
  2. 第二个应用:除了文本插值,我们还可以像这样来绑定元素 attribute:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    </head>
    
    <body>
        <div id="app-2">
          <span v-bind:title="message">
            鼠标悬停几秒钟查看此处动态绑定的提示信息!
          </span>
        </div>
    </body>
    
    <script>
        var app2 = new Vue({
            el: '#app-2',
            data: {
                message: '页面加载于 ' + new Date().toLocaleString()
            }
        })
    </script>
    </html>
    

    效果如下:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DJyU1kSp-1616393400550)(C:\Users\HP\AppData\Roaming\Typora\typora-user-images\image-20210322103556455.png)]

条件与循环, 控制切换一个元素

  1. 第三个vue应用:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    </head>
    
    <body>
        <div id="app-3">
            <p v-if="seen">现在你看到我了</p>
        </div>
    
    </body>
    
    <script>
        var app3 = new Vue({
            el: '#app-3',
            data: {
                seen: true
            }
        })
    
    </script>
    </html>
    

    效果如下:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VBQPnhiL-1616393400553)(C:\Users\HP\AppData\Roaming\Typora\typora-user-images\image-20210322104348767.png)]

  2. 第四个vue应用:使用v-for:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    </head>
    
    <body>
        <div id="app-4">
            <ol>
                <li v-for="todo in todos">
                    {{ todo.text }}
                </li>
            </ol>
        </div>
    
    </body>
    
    <script>
        var app4 = new Vue({
            el: '#app-4',
            data: {
                todos: [
                    { text: '学习 JavaScript' },
                    { text: '学习 Vue' },
                    { text: '整个牛项目' }
                ]
            }
        })
    
    </script>
    </html>
    

    效果如下:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PISeKTKM-1616393400555)(C:\Users\HP\AppData\Roaming\Typora\typora-user-images\image-20210322110146247.png)]

    在控制台里,输入 app4.todos.push({ text: '新项目' }),你会发现列表最后添加了一个新项目。

处理用户输入

​ 5.第五个vue应用:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>

<body>
    <div id="app-5">
        <p>{{ message }}</p>
        <button v-on:click="reverseMessage">反转消息</button>
    </div>

</body>

<script>
    var app5 = new Vue({
        el: '#app-5',
        data: {
            message: 'Hello Vue.js!'
        },
        methods: {
            reverseMessage: function () {
                this.message = this.message.split('').reverse().join('')
            }
        }
    })

</script>
</html>

效果如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-27MMqrjE-1616393400557)(C:\Users\HP\AppData\Roaming\Typora\typora-user-images\image-20210322111131192.png)]

​ 6.第六个应用:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>

<body>
    <div id="app-5">
        <p>{{ message }}</p>
        <button v-on:click="reverseMessage">反转消息</button>
    </div>

</body>

<script>
    var app5 = new Vue({
        el: '#app-5',
        data: {
            message: 'Hello Vue.js!'
        },
        methods: {
            reverseMessage: function () {
                this.message = this.message.split('').reverse().join('')
            }
        }
    })

</script>
</html>

效果如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gCMAamS0-1616393400558)(C:\Users\HP\AppData\Roaming\Typora\typora-user-images\image-20210322111512098.png)]

组件化构建应用: 在 Vue 里,一个组件本质上是一个拥有预定义选项的一个 Vue 实例

  1. 第七个vue实例:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    </head>
    <body>
        <div id="app-7">
            <ol>
                <!--  创建一个todo-item组件的实例
    
                  现在我们为每个 todo-item 提供 todo 对象
                  todo 对象是变量,即其内容可以是动态的。
                  我们也需要为每个组件提供一个“key”,稍后再
                  作详细解释。
                -->
                <todo-item
                        v-for="item in groceryList"
                        v-bind:todo="item"
                        v-bind:key="item.id"
                ></todo-item>
            </ol>
        </div>
    </body>
    <script>
        Vue.component('todo-item', {
            // todo-item 组件现在接受一个
            // "prop",类似于一个自定义 attribute。
            // 这个 prop 名为 todo。
            props: ['todo'],
            template: '<li>{{ todo.text }}</li>'
        })
    
        var app7 = new Vue({
            el: '#app-7',
            data: {
                groceryList: [
                    { id: 0, text: '蔬菜' },
                    { id: 1, text: '奶酪' },
                    { id: 2, text: '随便其它什么人吃的东西' }
                ]
            }
        })
    
    </script>
    </html>
    

    效果如下:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7bKqePL5-1616393400559)(C:\Users\HP\AppData\Roaming\Typora\typora-user-images\image-20210322114502542.png)]

二、Vue实例

  1. 创建第一个Vue实例, 在文档中经常会使用 vm (ViewModel 的缩写) 这个变量名表示 Vue 实例。

一、实例声明周期钩子

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

    比如create钩子可以采用在第一个实例被创建之后执行代码:,,生命周期钩子的 this 上下文指向调用它的 Vue 实例。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    </head>
    <body>
        <div id="app-7">
    
        </div>
    </body>
    <script>
        new Vue({
            data: {
                a: 1
            },
            created: function () {
                // `this` 指向 vm 实例
                console.log('a is: ' + this.a)
            }
        })
    </script>
    </html>
    

    控制台输出效果如下:
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xCx4MOa4-1616393400560)(C:\Users\HP\AppData\Roaming\Typora\typora-user-images\image-20210322115917227.png)]

二、模板语法

三、列表渲染,使用v-for把一个数组对应为一组元素

  1. 可以用 v-for 指令基于一个数组来渲染一个列表v-for 指令需要使用 item in items 形式的特殊语法,其中 items 是源数据数组,而 item 则是被迭代的数组元素的别名
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
    <div>
        <ul id="example-1">
            <li v-for="item in items" :key="item.message">
                {{ item.message }}
            </li>
        </ul>
    </div>

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

</body>
<script>
    var example1 = new Vue({
        el: '#example-1',
        data: {
            items: [
                { message: 'Foo' },
                { message: 'Bar' }
            ]
        }
    })

    var example2 = new Vue({
        el: '#example-2',
        data: {
            parentMessage: 'Parent',
            items: [
                { message: 'Foo' },
                { message: 'Bar' }
            ]
        }
    })
</script>
</html>

效果如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7VLIEcqQ-1616393400560)(C:\Users\HP\AppData\Roaming\Typora\typora-user-images\image-20210322135832989.png)]

2、在v-for里面使用对象, 你也可以用 v-for 来遍历一个对象的 property。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
    <div>
        <ul id="v-for-object" class="demo">
            <li v-for="value in object">
                {{ value }}
            </li>
        </ul>
    </div>
</body>
<script>
    new Vue({
        el: '#v-for-object',
        data: {
            object: {
                title: 'How to do lists in Vue',
                author: 'Jane Doe',
                publishedAt: '2016-04-10'
            }
        }
    })
</script>
</html>

​ 效果如图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3dkmXGQy-1616393400561)(C:\Users\HP\AppData\Roaming\Typora\typora-user-images\image-20210322140302596.png)]

​ 也可以使用提供的第二个的参数为property名字(也就是键名),如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
    <ul id="v-for-object" class="demo">
        <li v-for="(value, name) in object">
            {{name}} : {{ value }}
        </li>
    </ul>
</body>
<script>
    new Vue({
        el: '#v-for-object',
        data: {
            object: {
                title: 'How to do lists in Vue',
                author: 'Jane Doe',
                publishedAt: '2016-04-10'
            }
        }
    })
</script>
</html>

效果如下:
在这里插入图片描述

事件处理:

  1. 监听事件: 可以用 v-on 指令监听 DOM 事件,并在触发时运行一些 JavaScript 代码。
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
    <div id="example-1">
        <button v-on:click="counter += 1">Add 1</button>
        <p>The button above has been clicked {{ counter }} times.</p>
    </div>
</body>
<script>
    var example1 = new Vue({
        el: '#example-1',
        data: {
            counter: 0
        }
    })
    
</script>
</html>

效果如下:
在这里插入图片描述
2.事件处理方法: 然而许多事件处理逻辑会更为复杂,所以直接把 JavaScript 代码写在 v-on 指令中是不可行的。因此 v-on 还可以接收一个需要调用的方法名称。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
    <div id="example-2">
        <!-- `greet` 是在下面定义的方法名 -->
        <button v-on:click="greet">Greet</button>
    </div>
</body>
<script>
    var example2 = new Vue({
        el: '#example-2',
        data: {
            name: 'Vue.js'
        },
        // 在 `methods` 对象中定义方法
        methods: {
            greet: function (event) {
                // `this` 在方法里指向当前 Vue 实例
                alert('Hello ' + this.name + '!')
                // `event` 是原生 DOM 事件
                if (event) {
                    alert(event.target.tagName)
                }
            }
        }
    })

</script>
</html>

在这里插入图片描述
在这里插入图片描述
3、内联处理器中的方法: 除了直接绑定到一个方法,也可以在内联 JavaScript 语句中调用方法。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
    <div id="example-3">
        <button v-on:click="say('hi')">Say hi</button>
        <button v-on:click="say('what')">Say what</button>
    </div>
</body>
<script>
    new Vue({
        el: '#example-3',
        methods: {
            say: function (message) {
                alert(message)
            }
        }
    })

</script>
</html>

效果如下:
在这里插入图片描述在这里插入图片描述
4、事件修饰符: Vue.js 为 v-on 提供了事件修饰符。之前提过,修饰符是由点开头的指令后缀来表示的。

  • .stop
  • .prevent
  • .capture
  • .self
  • .once
  • .passive
<!-- 阻止单击事件继续传播 -->
<a v-on:click.stop="doThis"></a>

<!-- 提交事件不再重载页面 -->
<form v-on:submit.prevent="onSubmit"></form>

<!-- 修饰符可以串联 -->
<a v-on:click.stop.prevent="doThat"></a>

<!-- 只有修饰符 -->
<form v-on:submit.prevent></form>

<!-- 添加事件监听器时使用事件捕获模式 -->
<!-- 即内部元素触发的事件先在此处理,然后才交由内部元素进行处理 -->
<div v-on:click.capture="doThis">...</div>

<!-- 只当在 event.target 是当前元素自身时触发处理函数 -->
<!-- 即事件不是从内部元素触发的 -->
<div v-on:click.self="doThat">...</div>

三、组件基础

1、基础示例, 我们先定义一个Vue组件实例

// 定义一个名为 button-counter 的新组件
Vue.component('button-counter', {
  data: function () {
    return {
      count: 0
    }
  },
  template: '<button v-on:click="count++">You clicked me {{ count }} times.</button>'
})

组件是可复用的 Vue 实例,且带有一个名字:在这个例子中是 。我们可以在一个通过 new Vue 创建的 Vue 根实例中,把这个组件作为自定义元素来使用:

<div id="components-demo">
  <button-counter></button-counter>
</div>

new Vue({ el: '#components-demo' })

完整代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
    <div id="components-demo">
        <button-counter></button-counter>
    </div>
</body>
<script>
    // 定义一个名为 button-counter 的新组件
    Vue.component('button-counter', {
        data: function () {
            return {
                count: 0
            }
        },
        template: '<button v-on:click="count++">You clicked me {{ count }} times.</button>'
    })

    new Vue({ el: '#components-demo' })
</script>
</html>

效果如下:
在这里插入图片描述

2、组件的复用, 在上面实例中在添加几个就可以使用组件复用啦,每个组件都会各自独立维护它的 count。因为你每用一次组件,就会有一个它的新实例被创建。

<div id="components-demo">
  <button-counter></button-counter>
  <button-counter></button-counter>
  <button-counter></button-counter>
</div>

完整代码如如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
    <div id="components-demo">
        <button-counter></button-counter>
        <button-counter></button-counter>
        <button-counter></button-counter>
    </div>
</body>
<script>
    // 定义一个名为 button-counter 的新组件
    Vue.component('button-counter', {
        data: function () {
            return {
                count: 0
            }
        },
        template: '<button v-on:click="count++">You clicked me {{ count }} times.</button>'
    })

    new Vue({ el: '#components-demo' })
</script>
</html>

效果如下:
在这里插入图片描述

2、组件的组织

3、通过Prop向子组件传递数据
Prop 是你可以在组件上注册的一些自定义 attribute。当一个值传递给一个 prop attribute 的时候,它就变成了那个组件实例的一个 property。为了给博文组件传递一个标题,我们可以用一个 props 选项将其包含在该组件可接受的 prop 列表中:

Vue.component('blog-post', {
  props: ['title'],
  template: '<h3>{{ title }}</h3>'
})

一个组件默认可以拥有任意数量的 prop,任何值都可以传递给任何 prop。在上述模板中,你会发现我们能够在组件实例中访问这个值,就像访问 data 中的值一样。

一个 prop 被注册之后,你就可以像这样把数据作为一个自定义 attribute 传递进来:

<blog-post title="My journey with Vue"></blog-post>
<blog-post title="Blogging with Vue"></blog-post>
<blog-post title="Why Vue is so fun"></blog-post>

完整代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
    <div id="components-demo">
        <blog-post title="My journey with Vue"></blog-post>
        <blog-post title="Blogging with Vue"></blog-post>
        <blog-post title="Why Vue is so fun"></blog-post>
    </div>
</body>
<script>
    // 定义一个名为 button-post 的组件
    Vue.component('blog-post', {
        props: ['title'],
        template: '<h3>{{ title }}</h3>'
    })

    new Vue({ el: '#components-demo' })
</script>
</html>

效果如下图:
在这里插入图片描述
然而在一个典型的应用中,你可能在 data 里有一个博文的数组:

new Vue({
  el: '#blog-post-demo',
  data: {
    posts: [
      { id: 1, title: 'My journey with Vue' },
      { id: 2, title: 'Blogging with Vue' },
      { id: 3, title: 'Why Vue is so fun' }
    ]
  }
})

并想要为每篇博文渲染一个组件:

<blog-post
  v-for="post in posts"
  v-bind:key="post.id"
  v-bind:title="post.title"
></blog-post>

完整代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
    <div id="components-demo">
        <blog-post title="My journey with Vue"></blog-post>
        <blog-post title="Blogging with Vue"></blog-post>
        <blog-post title="Why Vue is so fun"></blog-post>
    </div>
</body>
<script>
    // 定义一个名为 button-post 的组件
    Vue.component('blog-post', {
        props: ['title'],
        template: '<h3>{{ title }}</h3>'
    })

    new Vue({ el: '#components-demo' })
</script>
</html>

效果如下:
在这里插入图片描述

4、监听子组件事件

四、组件注册

1、组件名, 在注册一个组件的时候,我们始终需要给它一个名字。比如在全局注册的时候我们已经看到了。

Vue.component('my-component-name', { /* ... */ })

该组件名就是 Vue.component 的第一个参数。

2、全局注册:, 到目前为止,我们只用过 Vue.component 来创建组件:

Vue.component('my-component-name', {
  // ... 选项 ...
})

这些组件都是全局注册的。 也就是说它们在注册之后可以用在任何新创建的 Vue 根实例 (new Vue) 的模板中。比如:

Vue.component('component-a', { /* ... */ })
Vue.component('component-b', { /* ... */ })
Vue.component('component-c', { /* ... */ })
new Vue({ el: '#app' })
<div id="app">
  <component-a></component-a>
  <component-b></component-b>
  <component-c></component-c>
</div>

注意局部注册的组件在其子组件中不可用。例如,如果你希望 ComponentA 在 ComponentB 中可用,则你需要这样写:

var ComponentA = { /* ... */ }

var ComponentB = {
  components: {
    'component-a': ComponentA
  },
  // ...
}

3、在模块系统中局部注册:, 例如,在一个假设的 ComponentB.js 或 ComponentB.vue 文件中:

import ComponentA from './ComponentA'
import ComponentC from './ComponentC'

export default {
  components: {
    ComponentA,
    ComponentC
  },
  // ...
}

4、基础组件的自动化全局注册

import BaseButton from './BaseButton.vue'
import BaseIcon from './BaseIcon.vue'
import BaseInput from './BaseInput.vue'

export default {
  components: {
    BaseButton,
    BaseIcon,
    BaseInput
  }
}

五、Prop

1、Prop: prop的作用是父组件向子组件单向传递数据,这个过程是单向的。传递的属性可以是静态的,可以是动态的,可以是数字,可以是字符串,可以是数组,还可以是对象,甚至可以在传递数据的时候写一个校验函数进行校验。

类型 : props: [‘title’, ‘likes’, ‘isPublished’, ‘commentIds’, ‘author’]

可以以对象形式列出 prop,这些 property 的名称和值分别是 prop 各自的名称和类型:

props: {
  title: String,
  likes: Number,
  isPublished: Boolean,
  commentIds: Array,
  author: Object,
  callback: Function,
  contactsPromise: Promise // or any other constructor
}

2、传递静态或动态Prop

子组件:

<template>
  <div>
    <h1>{{ msg }}</h1>
  </div>
</template>

<script>
export default {
  props: ["msg"]
}
</script>

父组件:

<template>
  <div id="app">
    <HelloWorld msg="hello"/>
  </div>
</template>

<script>
import HelloWorld from "./components/HelloWorld.vue";

export default {
  components: {
    HelloWorld
  }
};
</script>

好了,这样就完成了一个最简单的使用prop接收父元素的值

3、传动态字符串

子组件:

<template>
  <div>
    <h1>{{ msg }}</h1>
  </div>
</template>

<script>
export default {
  props: ["msg"]
}
</script>

父组件:

<template>
  <div id="app">
    <HelloWorld :msg="hello"/>
  </div>
</template>

<script>
import HelloWorld from "./components/HelloWorld.vue";

export default {
  components: {
    HelloWorld
  },
  data() {
    return {
      hello: "hello world"
    }
  }
};
</script>

4、传动态数组

子组件:

<template>
  <div>
    <ul>
      <li v-for="item in msg" :key="item">
        {{ item }}
      </li>
    </ul>
  </div>
</template>

<script>
export default {
  props: ["msg"]
}
</script>

父组件:

<template>
  <div id="app">
    <HelloWorld :msg="hello"/>
  </div>
</template>

<script>
import HelloWorld from "./components/HelloWorld.vue";

export default {
  components: {
    HelloWorld
  },
  data() {
    return {
      hello: ["aa", "bb", "cc"]
    }
  }
};
</script>

5、传动态对象

子组件:

<template>
  <div>
    <h1>{{ msg.id }}</h1>
    <h2>{{ msg.name }}</h2>
  </div>
</template>

<script>
export default {
  props: ["msg"]
}
</script>

父组件:

<template>
  <div id="app">
    <HelloWorld :msg="hello"/>
  </div>
</template>

<script>
import HelloWorld from "./components/HelloWorld.vue";

export default {
  components: {
    HelloWorld
  },
  data() {
    return {
      hello: {
        id: 1,
        name: "hello dj"
      }
    }
  }
};
</script>

六、自定义事件

Logo

前往低代码交流专区

更多推荐