VUE的入门以及使用

为什么使用vue

大量的html css以及js文件难以管理

vue的招聘

介绍

简单来说,Vue是一套渲染UI的强大前端框架。

数据:响应式

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

vue特点

主要特性:

  • 学习曲线非常平缓,只要有html/css,js基础即可上手
  • 渐进式,可以在服务端项目中部分使用vue
  • 响应式的支持,让我们从传统的JQuery的面向DOM编程,转变为面向数据编程
  • 组件化,可以把页面分成很多组件,每个组件都有自己的html css以及js
  • 丰富的语法支持
  • 优雅的单文件组件
  • 完善的组件动画支持
  • 成熟的生态,比如vue-cli,VueRouter,Vuex等相关配套的工具

其中,最重要最核心的特性就是:响应式和组件化。

安装

  • 通过<script></script>引用

    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
    
  • 通过vue-cli安装全套开发环境,项目开发推荐

快速尝鲜

<head>
    <meta charset="UTF-8">
    <title>快速入门</title>
    <script src="./lib/vue.js"></script>
</head>
<body>
<div id="app">{{msg}}</div>
<script type="text/javascript">
        let vue = new Vue({
            el:"#app",
            data:{
                msg:"hello"
            }
        })
</script>
</body>

vue是响应式的,只要数据发生变化就会自动更新数据显示

vue指令

vue有很多指令可以实现数据和控件的绑定

指令带有前缀 v-,以表示它们是 Vue 提供的特殊特性。它们会在渲染的 DOM 上应用特殊的响应式行为

v-bind

<div id="app">
        <span v-bind:title="msg">鼠标悬浮</span>
        <input type="text" v-bind:value="msg">
    </div>
    <script type="text/javascript">
        let vue = new Vue({
            el:"#app",
            data:{
                msg:"hello"
            }
        })
    </script>

注意:v-bind:value可以简写为:value

v-model

v-model一般用在input textarea select中,实现输入框和应用状态的双向绑定

  • 不使用v-model的实现

    <!--普通实现-->
        <div>
            <input type="text" id="input" onkeyup="handKeyUp()"><br>
            span中显示内容<br>
            <span id="span"></span>
        </div>
    
        <script type="text/javascript">
            function handKeyUp(e) {
                //查找输入框控件
                let inputValue = document.getElementById('input').value
                //查找span控件
                let spanEle = document.getElementById('span')
                //设置span控件的值
                spanEle.innerText = inputValue
            }
        </script>
    
  • 使用v-model实现

    <div id="app">
            <input type="text" v-model="msg"><br>
            span中显示内容<br>
            <span>{{msg}}</span>
        </div>
    
        <script type="text/javascript">
            let vue = new Vue({
                el:"#app",
                data:{
                    msg:""
                }
            })
        </script>
    

    思考一下:v-bind能不能实现?

v-for

v-for 指令可以绑定数组的数据来渲染一个项目列表

  • 普通实现

    <div id="app">
            于谦的爱好:
            <ol id="ol">
            </ol>
        </div>
    
        <script type="text/javascript">
            //网络请求
            let hobbies = ['抽烟','喝酒','烫头']
            //获取列表的控件
            let olEle = document.getElementById('ol')
            //定义innerhtml属性
            let inHtml = ''
            //循环数组
            hobbies.forEach((item,index,arr)=>{
                inHtml += '<li>'+item+'</li>'
            })
            //设置里面的html
            olEle.innerHTML = inHtml
        </script>
    
  • v-for实现

    <div id="app">
        于谦的爱好:
        <ol>
            <li v-for="item in hobbies">{{item}}</li>
        </ol>
    </div>
    
    <script type="text/javascript">
        let vue = new Vue({
            el:"#app",
            data:{
                hobbies:['抽烟','喝酒','烫头']
            }
        })
    </script>
    

v-if

条件判断

<div id="app">
    <div v-if="isShow">控制显示或者隐藏</div>
    <button @click="isShow = !isShow">切换显示状态</button>
</div>

<script type="text/javascript">
    let vue = new Vue({
        el:"#app",
        data:{
            isShow:true
        }
    })
</script>

注意:v-on:click可以简写为@click

  • v-on:click

    vue处理点击事件

    简写@click

    <button v-on:click="shouldShow = !shouldShow">显示或者隐藏</button>
            <button @click="shouldShow = !shouldShow">显示或者隐藏</button>
    

v-once

一次性插值

<div id="app">
    <span v-once>{{msg}}</span>
</div>
<script type="text/javascript">
    let data = {
        msg: "hello world"
    }
    let vue = new Vue({
        el: "#app",
        data: data
    })
</script>

vue实例

每个 Vue 应用都是通过用 Vue 函数创建一个新的 Vue 实例开始的

<script type="text/javascript">
    let vm = new Vue({
      // 选项
    })
</script>

MVC模式

在这里插入图片描述
MVP模式

在这里插入图片描述

MVVM模式

在这里插入图片描述

数据和方法

<div id="app">
    <span>{{msg}}</span><br>
    <button @click="handClick">按钮</button>
</div>
<script type="text/javascript">
    let data = {
        msg: "hello world"
    }
    let vue = new Vue({
        el: "#app",
        data: data,
        methods:{
            handClick(){
                this.msg = "你好 世界"
            }
        }
    })
</script>

生命周期钩子

生命周期钩子其实就是生命周期的回调函数.Vue实例从初始化,创建,显示,更新以及销毁的整个过程,而生命周期钩子指的是每个过程都有一个回调函数,Vue中把回调函数称为钩子。

在这里插入图片描述

  • beforeCreate : 开始创建实例
  • created : 实例创建出来了,vue的实例基本上被初始化
  • beforeMount : 模版与数据相结合,页面渲染之前,执行的函数
  • mounted: 模版和数据结合完成,会将Vue实例挂载到dom树上
  • beforeDestroy : 实例要被回收的时候执行
  • destroyed : 实例回收完成的时候调用
  • beforeUpdate: 数据发生改变,还没有渲染之前
  • updated : 渲染完成

模板语法

<div id="app">
</div>
<script type="text/javascript">
    let data = {
        msg: "hello world"
    }
    let vue = new Vue({
        el: "#app",
        data: data,
        template:'<div>\n' +
        '    <span>{{msg}}</span><br>\n' +
        '    <button @click="handClick">按钮</button>\n' +
        '</div>',
        methods:{
            handClick(){
                this.msg = "你好 世界"
            }
        }
    })
</script>

计算属性

模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的。在模板中放入太多的逻辑会让模板过重且难以维护

  • 普通实现

    <div id="app">
        <span>{{fullName()}}</span>
    </div>
    <script type="text/javascript">
        let vue = new Vue({
            el: "#app",
            data: {
                firstName:'bill',
                lastName:'gates'
            },
            methods:{
                fullName(){
                    console.log('执行了')
                    return this.firstName+this.lastName
                }
            }
        })
    </script>
    
  • 计算属性

    <div id="app">
        <span>{{fullName}}</span>
    </div>
    <script type="text/javascript">
        let vue = new Vue({
            el: "#app",
            data: {
                firstName:'bill',
                lastName:'gates',
            },
            computed:{
                fullName(){
                    console.log('执行了')
                    return this.firstName+this.lastName
                }
            }
        })
    </script>
    
  • 计算属性和普通实现的区别

    页面元素发生变化时,普通方法会重新执行一遍,而计算属性有缓存不会重新计算

    计算属性不需要写函数()

侦听属性

观察和相应vue上的数据变动

<div id="app">
    <span>{{fullName}}</span>
    <span>{{msg}}</span>
</div>
<script type="text/javascript">
    let vue = new Vue({
        el: "#app",
        data: {
            firstName:'bill',
            lastName:'gates',
            fullName:'bill gates',
            msg:'哈哈'
        },
        watch:{
            firstName(newVal,oldVal){
                console.log('newVal='+newVal+'---oldVal='+oldVal)
            },
            lastName(newVal,oldVal){
                console.log('newVal='+newVal+'---oldVal='+oldVal)

            }
        }
    })
</script>

开发中尽量使用:计算属性>侦听器>普通属性

class的动态绑定

<head>
    <meta charset="UTF-8">
    <title>class的动态绑定</title>
    <script src="./lib/vue.js"></script>
    <style>
        .c1 {
            background: red;
        }

        .c1-ac {
            font-size: 40px;
        }
    </style>
</head>
<body>
<div id="app">
    <!--<div :class="isActive ? cls : ''" @click="handClick">动态显示样式的条目</div>-->
    <div class="c1" :class="{'c1-ac':isActive}" @click="handClick">动态显示样式的条目</div>
    <div :class="cls">固定显示样式的条目</div>
</div>
</body>
<script type="text/javascript">
    let vm = new Vue({
        el: "#app",
        data: {
            isActive: false,
            cls: ['c1', 'c1-ac']
        },
        methods: {
            handClick() {
                console.log('点击事件')
                this.isActive = !this.isActive
                console.log(this.isActived)
            }
        }
    })
</script>

条件渲染

  • v-if

    v-if显示的文本
  • v-if v-else-if v-else

    <div>
            <input type="number" v-model="age">
            <div v-if="age>90">老年人</div>
            <div v-else-if="age>60">中年人</div>
            <div v-else>少年</div>
        </div>
    
  • v-if和v-show

    <div v-show="show">v-show显示的文本</div>
    <div v-if="show">v-if显示的文本</div>
    <button @click="show = !show">显示或隐藏</button>
    

    v-if不显示时就从DOM中移除,v-show还在DOM中

    开发中尽量使用v-show

列表渲染

  • 数组渲染

      <body>
    <div id="app">
        <!--数组不带角标-->
        <div>数组不带角标:</div>
        <ul>
            <li v-for="item in hobbies">{{item}}</li>
        </ul>
    
        <!--数组带角标-->
        <div>数组带角标:</div>
        <ul>
            <li v-for="item,index in hobbies">{{item}} {{index}}</li>
        </ul>
    </div>
    </body>
    <script type="text/javascript">
        let vm = new Vue({
            el: "#app",
            data: {
                hobbies:['抽烟','喝酒','烫头']
            },
            methods: {}
        })
    </script>
    
  • 对象渲染

    <div id="app">
        <div>对象不带属性名:</div>
        <ul>
            <li v-for="ele in person">{{ele}}</li>
        </ul>
    
        <div>对象带属性名:</div>
        <ul>
            <li v-for="ele,name in person">{{ele}} {{name}}</li>
        </ul>
    
        <div>对象带属性名和角标:</div>
        <ul>
            <li v-for="ele,name,index in person">{{ele}} {{name}} {{index}}</li>
        </ul>
    </div>
    </body>
    <script type="text/javascript">
        let vm = new Vue({
            el: "#app",
            data: {
                person:{
                    'name':'张三',
                    age:20,
                    phone:'13354234567'
                }
            },
            methods: {}
        })
    </script>
    
  • 数组列表增加和删除条目

    <div id="app">
        <input type="text" v-model="input"><button @click="add">添加</button><br>
        <ul>
            <li v-for="item,index in hobbies">{{item}} {{index}}</li>
        </ul>
        <input type="number" v-model="index"><button @click="deleteItem">删除</button>
    </div>
    </body>
    <script type="text/javascript">
        let vm = new Vue({
            el: "#app",
            data: {
                hobbies:['抽烟','喝酒','烫头'],
                input:'',
                index:0
            },
            methods: {
                add(){
                    //不会更新
                    // this.hobbies[this.hobbies.length] = this.input
                    //用push方法
                    this.hobbies.push(this.input)
                },
                deleteItem(){
                    this.hobbies.splice(this.index,1)
                }
            }
        })
    </script>
    
  • 注意:对象渲染列表如果增加一个属性是不会刷新的需要通过set方法

    <body>
    <div id="app">
        <input type="text" v-model="input"><button @click="add">添加</button><br>
        <ul>
            <li v-for="item,index in person">{{item}}</li>
        </ul>
        <input type="number" v-model="index"><button @click="deleteItem">删除</button>
    </div>
    </body>
    <script type="text/javascript">
        let vm = new Vue({
            el: "#app",
            data: {
                person:{
                    'name':'bill',
                    age:20,
                    phone:'1234455'
                },
                input:'',
                index:0
            },
            methods: {
                add(){
                    //这种方式不行
                    // this.person.email = this.input
                    //通过set方法是响应式的
                    Vue.set(this.person,'email',this.input)
                },
                deleteItem(){
                    // this.hobbies.splice(this.index,1)
                }
            }
        })
    </script>
    
  • 当我们去使用v-for的时候,最好去给它指定一个唯一的key值,这样的会方便vue复用dom节点,从而提高性能

组件

组件是可复用的 Vue 实例,它与 new Vue 接收相同的选项,例如 datacomputedwatchmethods 以及生命周期钩子等。仅有的例外是像 el这样根实例特有的选项。

全局组件

  • 定义和使用全局组件

    <div id="app">
        <title-bar></title-bar>
        <div>内容</div>
        <bottom-bar></bottom-bar>
    </div>
    </body>
    <script type="text/javascript">
        <!--全局组件-->
        Vue.component('title-bar',{
            template:'<div>标题</div>'
        })
    
        Vue.component('bottom-bar',{
            template:'<div>底部菜单</div>'
        })
    
    
        let vm = new Vue({
            el: "#app",
            data: {
    
            },
            methods: {
    
            }
        })
    </script>
    
  • 组件的data

    一个组件的 data 选项必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝

    Vue.component('title-bar', {
            template: '<div>{{msg}}</div>',
            data() {
                return {
                    msg: '我是标题'
                }
            }
        })
    

局部组件

<div id="app">
    <title-bar></title-bar>
    <div>内容</div>
    <bottom-bar></bottom-bar>
</div>
</body>
<script type="text/javascript">


    let TitleBar = {
        name:'title-bar',
        template:'<div>{{msg}}</div>',
        data(){
            return{
                msg:'从data中获取标题'
            }
        }
    }

    let BottomBar={
        name:'bottom-bar',
        template:'<div>底部栏目</div>'
    }

    let vm = new Vue({
        el: "#app",
        data: {

        },
        methods: {

        },
        components:{
            TitleBar,
            BottomBar
        }
    })
</script>

父子组件之间的通信

父组件传递数据给子组件

<body>
<div id="app">
    <title-bar :mytitle="msg"></title-bar>
    <div>内容</div>
    <bottom-bar></bottom-bar>
</div>
</body>
<script type="text/javascript">

    let TitleBar = {
        name:'title-bar',
        template:'<div>{{mytitle}}</div>',
        props:['mytitle'],
        data(){
            return{

            }
        }
    }

由于直接传递数据,子组件不能修改所以可以通过参数来接收父组件传递的数据

let TitleBar = {
        name:'title-bar',
        template:'<div>{{msg}}</div>',
        props:['mytitle'],
        data(){
            return{
                msg:this.mytitle
            }
        }
    }

子组件传递数据给父组件

子控件需要先处理事件并把事件通过this.$emit分发出去

<body>
<div id="app">
    <title-bar :mytitle="msg" @child-click="handClick"></title-bar>
    <div>内容</div>
    <bottom-bar></bottom-bar>
</div>
</body>
<script type="text/javascript">

    let TitleBar = {
        name:'title-bar',
        template:'<div>{{mytitle}} <button @click="handClick">返回</button></div>',
        props:['mytitle'],
        data(){
            return{
                translateMsg:'子组件传递给父组件'
            }
        },
        methods:{
            handClick(){
                console.log('子控件点击事件')
                this.$emit('child-click',this.translateMsg)
            }
        }
    }

    let BottomBar={
        name:'bottom-bar',
        template:'<div>底部栏目</div>'
    }

    let vm = new Vue({
        el: "#app",
        data: {
            msg:'父组件中传递的消息标题'
        },
        methods: {
            handClick(msg){
                console.log('点击了子控件的button')
            }
        },
        components:{
            TitleBar,
            BottomBar
        }
    })
</script>

或者直接将事件分发出去:$emit('enlarge-text', 0.1)

组件绑定原生事件

如果我们在自定义组件上绑定事件是没有效果的,因为组件上定义的事件都是自定义的,想要触发需要我们在子组件内部调用$emit派发.但是这样做又很麻烦,所以当我们想使用点击事件,我们可以使用Vue提供的绑定原生事件方式,我们只需要使用

@click.native

<div id="app">
  <title-bar :mytitle="msg" @click.native="handClick"></title-bar>
  <div>内容</div>
  <bottom-bar></bottom-bar>
</div>

组件插槽

首先看一个例子

<body>
<div id="app">
    <child></child>
</div>
</body>
<script type="text/javascript">
    let Child = {
        name: 'child',
        template: `<div>
                        <div>标题</div>
                        <div>内容</div>
                        <div>底部</div>
                    </div>`,
        data() {
            return {}
        }
    }

    let vm = new Vue({
        el: "#app",
        data: {},
        components: {
            Child
        }
    })
</script>

一般页面的标题和底部都是一样的,但是内容是可变的,这样写的话就写死了,所以需要用的时候传内容

body>
<div id="app">
    <child :content="content"></child>
</div>
</body>
<script type="text/javascript">
/*但是内容是可变的,怎么办?*/
    let Child = {
        name: 'child',
        props:['content'],
        template: `<div>
                        <div>标题</div>
                        <div v-html="content"></div>
                        <div>底部</div>
                    </div>`,
        data() {
            return {

            }
        }
    }

    let vm = new Vue({
        el: "#app",
        data: {
            content:`<span>你好</span>`
        },
        components: {
            Child
        }
    })
</script>

这样的话就在vue实例里面传递html元素给子控件,但是这样写的话也不直观,我们希望的是能够直接在html里面添加自己的元素

但是能不能直接往自定义子控件里面添加元素呢?

<div id="app">
    <child>
        <span>我是span内容</span>
    </child>
</div>

这样是不行的,不识别,这时就需要组件插槽了

<body>
<div id="app">
    <child>
        <span>我是span内容</span>
    </child>
</div>
</body>
<script type="text/javascript">
/*但是内容是可变的,怎么办?*/
    let Child = {
        name: 'child',
        props:['content'],
        template: `<div>
                        <div>标题</div>
                        <slot></slot>
                        <div>底部</div>
                    </div>`,
        data() {
            return {

            }
        }
    }

具名插槽

多个插槽可以给每一个插槽指定名称

<body>
<div id="app">
    <child>
        <div slot="content">我是内容</div>
        <div slot="foot">我是底部</div>
    </child>
</div>
</body>
<script type="text/javascript">
/*但是内容是可变的,怎么办?*/
    let Child = {
        name: 'child',
        props:['content'],
        template: `<div>
                        <div>标题</div>
                        <slot name="content"></slot>
                        <slot name="foot"></slot>
                    </div>`,
        data() {
            return {

            }
        }
    }

动态组件

组件切换

<body>
<div id="app">
    <h1>标题栏</h1>

    <component :is="curcom"></component>

    <button @click="curcom='home'">首页</button>
    <br>
    <button @click="curcom='my'">我的</button>
    <br>
</div>
</body>
<script type="text/javascript">
    let Home = {
        name:'home',
        template:`<div>首页</div>`
    }

    let My = {
        name:'my',
        template:`<div>我的</div>`
    }

    let vm = new Vue({
        el: "#app",
        data: {
            curcom:'home'
        },
        components: {
            Home,
            My
        }
    })
</script>

猜你喜欢

转载自blog.csdn.net/www294993741/article/details/83241939