VUE从0到1

139 阅读2分钟

VUE学习

1. Vue.js

  • 渐进式

    ​ Vue被设计成自底向上逐层应用(模块组合式)

  • 核心库

    ​ 只关心视图层:(HTML+CSS+JS):给用户看和刷新后台给的数据

  • 第三方库

    ​ 网络通信(axios(实现ajax))、页面跳转(router)、状态管理(vuex)

  • vue-ui

    ​ element-ui、iview

  • WebPack

    ​ 模块打包器,打包,压缩,合并及顺序加载。

2. MVVM 模式

image-20211120103622228

3. 单向绑定v-bind

使用v-bind进行单向绑定,同时可以使用:作为v-bind的简写

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        <!-- v-开头的都是指令,有vue提供的特殊属性 -->
        <!-- 绑定标签使用v-bind,非标签使用{{message}} -->
        <span v-bind:title = "message"> 
            <!-- 注意v-bind是单项绑定 -->
            鼠标停在这儿看看动态绑定的提示信息
        </span>
        <!-- v-bind的简写格式 -->
        <input type="text" :value="message">
    </div>
    <script>
        let vm = new Vue(
            {
                el:"#app",
                data:{
                    message:"hello1",
                }
            }
        );
    </script>
</body>
</html>

4.双向绑定

使用v-model进行双向绑定

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        <!-- v-开头的都是指令,有vue提供的特殊属性 -->
        <!-- 绑定标签使用v-bind,非标签使用{{message}} -->
        <span v-bind:title = "message"> 
            <!-- 注意v-bind是单项绑定 -->
            鼠标停在这儿看看动态绑定的提示信息
        </span>
        <input type="text" v-model="message">
    </div>
    <script>
        let vm = new Vue(
            {
                el:"#app",
                data:{
                    message:"hello1",
                }
            }
        );
    </script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
    <div id="app">
       <!-- v-model 双向绑定,案例演示 -->
       <!-- v-model的相关属性 .lazy失去焦点时有反应, .number只留数字, .trim去除首尾空格 -->
       <input type="text" v-model.lazy="message_1">
       <h3>{{message_1}}</h3>
        <p>爱好
            <input type="checkbox" v-model="message_2" value="篮球"/> 篮球
            <input type="checkbox" v-model="message_2" value="羽毛球"/> 羽毛球
            <input type="checkbox" v-model="message_2" value="排球"/> 排球
        </p>
        {{message_2}}

        <p>最喜欢哪个?
            <input type="radio" v-model="message_3" value="篮球"/> 篮球
            <input type="radio" v-model="message_3" value="羽毛球"/> 羽毛球
            <input type="radio" v-model="message_3" value="排球"/> 排球
        </p>
        {{message_3}}
    </div>
    <script>
        let vm = new Vue(
            {
                el:"#app",
                data:{
                    message_1:"hello",
                    message_2:[],
                    message_3:"",
                }
            }
        );
    </script>
</body>
</html>

5. 事件绑定

​ 使用v-on 绑定事件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
    <div id="app">
       <!-- 使用v-on 绑定事件 -->
        <button v-on:click="clickMe">点击我</button>
    </div>
    <script>
        let vm = new Vue(
            {
                el:"#app",
                data:{
                    num: 1
                },
                methods: {
                    clickMe: function(){
                        this.num+=1;
                        alert(this.num)
                    }
                },
            }
        );
    </script>
</body>
</html>

6. v-show v-if v-html 功能演示

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        <!-- v-html中的内容会当作时html代码进行执行 -->
        <div v-html='url'></div>
        <!-- v-show的div中的内容会一直存在,但是false时不显示 -->
        <div v-show= 'isShow'>看到我了?</div>
        <!-- v-if的div中的内容不会一直存在,当为true时才会生成 -->
        <div v-if= 'isHave'>看到我了?</div>
        <!-- 使用v-on 绑定事件 -->
        <button v-on:click="clickMe">点击我</button>
    </div>
    <script>
        let vm = new Vue(
            {
                el:"#app",
                data:{
                    url:"<h1>Hello<h1>",
                    num: 1,
                    isShow: false,
                    isHave: false
                },
                methods: {
                    clickMe: function(){
                        this.isShow = !this.isShow;
                        this.isHave = !this.isHave;
                    }
                },
            }
        );
    </script>
</body>
</html>

7. v-if 条件判断

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        <h3 v-if="type==='L'">L</h3>
        <h3 v-else-if="type==='XL'">XL</h3>
        <h3 v-else>XXXL</h3>
    </div>
    <script>
        let vm = new Vue(
            {
                el:"#app",
                data:{
                    type:'xXL',
                    url:"<h1>Hello<h1>",
                    num: 1,
                    isShow: false,
                    isHave: false
                },
                methods: {
                    clickMe: function(){
                        this.isShow = !this.isShow;
                        this.isHave = !this.isHave;
                    }
                },
            }
        );
    </script>
</body>
</html>

8.v-for

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        <h3 v-if="type==='L'">L</h3>
        <h3 v-else-if="type==='XL'">XL</h3>
        <h3 v-else>XXXL</h3>
        <li v-for="(item, index) in items">
            {{item}}
        </li>
    </div>
    <script>
        let vm = new Vue(
            {
                el:"#app",
                data:{
                    type:'xXL',
                    url:"<h1>Hello<h1>",
                    num: 1,
                    isShow: false,
                    isHave: false,
                    items: [1,2,3]
                },
                methods: {
                    clickMe: function(){
                        this.isShow = !this.isShow;
                        this.isHave = !this.isHave;
                    }
                },
            }
        );
    </script>
</body>
</html>

9. axios 网络请求

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/axios@0.12.0/dist/axios.min.js"></script>
</head>
<body>
    <div id="app">
        <h3 v-if="type==='L'">L</h3>
        <h3 v-else-if="type==='XL'">XL</h3>
        <h3 v-else>XXXL</h3>
        <li v-for="(item, index) in items">
            {{item}}
        </li>
        <h3>我的年龄是{{age}}</h3>
    </div>
    <script>
        let vm = new Vue(
            {
                el:"#app",
                data:{
                    type:'xXL',
                    url:"<h1>Hello<h1>",
                    num: 1,
                    isShow: false,
                    isHave: false,
                    items: [1,2,3],
                    age:0
                },
                methods: {
                    clickMe: function(){
                        this.isShow = !this.isShow;
                        this.isHave = !this.isHave;
                    }
                },
                 <!-- mounted是钩子函数(生命周期中的函数) 自动调用-->
                mounted() {
                    axios.get('/data.json').then(
                        response=>{
                            console.log(response.data)
                            this.age = response.data.age
                        }
                    );
                },
            }
        );
    </script>
</body>
</html>

10.vue 生命周期

一个完整的生命周期:

(1)开始创建

(2)初始化数据

(3)编译模板

(4)挂载DOM

(5)渲染

(6)更新

(7)卸载

Vue 实例生命周期

11. 计算属性

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/axios@0.12.0/dist/axios.min.js"></script>
</head>
<body>
    <div id="app">
        <h3 v-if="type==='L'">L</h3>
        <h3 v-else-if="type==='XL'">XL</h3>
        <h3 v-else>XXXL</h3>
        <li v-for="(item, index) in items">
            {{item}}
        </li>
        <h3>我的年龄是{{age}}</h3>
        <h3>当前时间{{getTime}}</h3>
    </div>
    <script>
        let vm = new Vue(
            {
                el:"#app",
                data:{
                    type:'xXL',
                    url:"<h1>Hello<h1>",
                    num: 1,
                    isShow: false,
                    isHave: false,
                    items: [1,2,3],
                    age:0
                },
                methods: {
                    clickMe: function(){
                        this.isShow = !this.isShow;
                        this.isHave = !this.isHave;
                    }
                },
                mounted() {
                    axios.get('/data.json').then(
                        response=>{
                            console.log(response.data)
                            this.age = response.data.age
                        }
                    );
                },
                // 计算属性,重复调用内容不会改变,调用方式,直接使用属性名不需要加上()
                computed:{
                    getTime:function(){
                        this.num;
                        return Date.now()
                    }
                },
            }
        );
    </script>
</body>
</html>

image-20211120230907792

12. 组件

image-20211121225959806

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/axios@0.12.0/dist/axios.min.js"></script>
</head>
<body>
    <div id="app">
        <abar></abar>
    </div>
    <script>
        Vue.component(
            'commonchild',{
                template:`<div><h3>commonChild</h3></div>`
            }
        );
        //组件的声明和vue的创建是齐平的
        Vue.component(
            'abar',{
                template:`
                    <div>
                        <h1>abar</h1>
                        <button v-on:click="clickMe">点击我</button>
                        <commonchild></commonchild>
                        <abarchild></abarchild>
                    </div>
                `,
                data() { //这里的data不能写属性
                    return {
                        
                    }
                },
                methods: {
                    clickMe(){
                        alert("abar")
                    }
                },
                components:{ // 局部定义子组件,只能在父组件中进行调用
                    'abarchild':{
                        template:`<div><h2>hello abarchild</h2></div>`
                    }
                }
            }
        )

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

                },
                methods: {
                    
                },
            }
        );
    </script>
</body>
</html>

13. 父组件传递数据到子组件

使用组件中的props属性

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/axios@0.12.0/dist/axios.min.js"></script>
</head>
<body>
    <div id="app">
        <abar thename = '主页' :show='true'></abar>
        <abar thename = '个人' :show='false'></abar>
    </div>
    <script>
        Vue.component(
            'commonchild',{
                template:`<div><h3>commonChild</h3></div>`
            }
        );
        //组件的声明和vue的创建是齐平的
        Vue.component(
            'abar',{
                template:`
                    <div>
                        <h1>{{thename}}</h1>
                        <button v-if='show' v-on:click="clickMe">点击我</button>
                        <commonchild></commonchild>
                        <abarchild></abarchild>
                    </div>
                `,
                data() { //这里的data不能写属性
                    return {
                        
                    }
                },
                methods: {
                    clickMe(){
                        alert("abar")

                    }
                },
                props:{ // 接受父组件传进来的属性
                    thename:String,
                    show:Boolean,
                },
                components:{ // 局部定义子组件,只能在父组件中进行调用
                    'abarchild':{
                        template:`<div><h2>hello abarchild</h2></div>`
                    }
                }
            }
        )

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

                },
                methods: {
                    
                },
            }
        );
    </script>
</body>
</html>

14.子组件传递数据到父组件

使用emit内置函数,子组件可以将数据传送到父组件中

image-20211121234053248

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/axios@0.12.0/dist/axios.min.js"></script>
</head>
<body>
    <div id="app">
        <abar thename = '主页' :show='true' @b_event='receive($event)'></abar>
        <abar thename = '个人' :show='false'></abar>
        {{show}}
    </div>
    <script>
        Vue.component(
            'commonchild',{
                template:`<div><h3>commonChild</h3></div>`
            }
        );
        //组件的声明和vue的创建是齐平的
        Vue.component(
            'abar',{
                template:`
                    <div>
                        <h1>{{thename}}</h1>
                        <button v-if='show' v-on:click="clickMe">点击我</button>
                        <commonchild></commonchild>
                        <abarchild></abarchild>
                    </div>
                `,
                data() { //这里的data不能写属性
                    return {
                        
                    }
                },
                methods: {
                    clickMe(){
                        alert("abar")
                        // 使用emit 传递消息
                        this.$emit('b_event', 'Hello')
                    }
                },
                props:{ // 接受父组件传进来的属性
                    thename:String,
                    show:Boolean,
                },
                components:{ // 局部定义子组件,只能在父组件中进行调用
                    'abarchild':{
                        template:`<div><h2>hello abarchild</h2></div>`
                    }
                }
            }
        )

        let vm =  new Vue(
            {
                el: "#app",
                data:{
                    show:[],
                },
                methods: {
                    // 定义一个接收消息的方法
                    receive(e){
                        this.show.push(`父组件收到消息${e}`)
                    }
                },
            }
        );
    </script>
</body>
</html>

15. ref 组件

ref组件一般来说,可以理解为对元素的重命名,通过他可以获取标签节点或者组件对象

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/axios@0.12.0/dist/axios.min.js"></script>
</head>
<body>
    <div id="app">
        <!-- ref 放在标签上,获取的是原生节点 -->
        <input type="text" ref="bar_ref" />
        <button v-on:click="clickMe">父组件</button>
        <!-- ref放组件上,拿到的是组件对象 -->
        <abar ref="abar_ref"></abar>
    </div>
    <script>
        
        //创建组件
        Vue.component(
            "abar",{
                template:`
                <div>
                <button v-on:click="clickMe">点击我</button>
                </div>`,
                methods:{
                    clickMe(){
                        console.log(this)
                    }
                },
                data(){
                    return{
                        message:"123"
                    }
                }       
            }
        )


        let vm  = new Vue(
            {
                el:"#app",
                data() {
                    return {
                        message:"123"
                    }
                },
                methods: {
                    clickMe(){
                        // 通过$refs直接获取标签节点
                        console.log(this.$refs.bar_ref.value)
                        // 通过$refs直接获取组件对象
                        console.log(this.$refs.abar_ref.message)
                    }
                },
            }
        );
    </script>
</body>
</html>

16. 事件总线

image-20211122104025558

17.动态组件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/axios@0.12.0/dist/axios.min.js"></script>
</head>
<body>
    <div id="app">
        <ul>
            <li><a @click="who='home'">首页</a></li>
            <li><a @click="who='news'">新闻</a></li>
            <li><a @click="who='blog'">博客</a></li>
        </ul>
        <!-- keep-alive是用来保存组件的状态 -->
        <keep-alive>
            <!-- 切换组件 -->
            <component :is="who"></component>
        </keep-alive>
    </div>
    <script>
        let vm = new Vue({
            el:"#app",
            data() {
                return {
                    who:'home'
                }
            },
            components:{
                'home':{
                    template:'<h1>这是首页</h1>'
                },
                'news':{
                    template:'<h1>这是新闻</h1>'
                },
                'blog':{
                    template:'<h1>这是博客</h1>'
                }
            }
        });
    </script>
</body>
</html>

18. slot 插槽

(1)slot基础

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/axios@0.12.0/dist/axios.min.js"></script>
</head>
<body>
    <div id="app">
        <abar>
            <!-- 组件中的html的代码是不起作用的,要想起作用 -->
            <div><h1>abar</h1></div>
        </abar>
    </div>
    <script>
        Vue.component('abar',{
            template:`
                <div>
                    <slot></slot>
                    <h1>上面是插槽</h1>
                </div>
            `
        });
        let vm = new Vue({
            el:"#app",
            data() {
                return {
                    
                }
            }
        });
    </script>
</body>
</html>

(2) 有名插槽

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/axios@0.12.0/dist/axios.min.js"></script>
</head>
<body>
    <div id="app">
        <abar>
            <!-- 有名插槽-->
            <div slot="slot1"><h1>abar</h1></div>
            <div slot="slot2"><h1>slot2</h1></div>
        </abar>
    </div>
    <script>
        Vue.component('abar',{
            template:`
                <div>
                    <slot name="slot1"></slot>
                    <h1>上面是插槽</h1>
                    <slot name="slot2"></slot>
                </div>
            `
        });
        let vm = new Vue({
            el:"#app",
            data() {
                return {
                    
                }
            }
        });
    </script>
</body>
</html>

(3) 插槽的嵌套和传参

19.vue-cli