Vue前端开发

1. Vue

1.1 概念

1.1.1 vue是什么?

Vue.js------ 渐进式框架。与其他重量级框架不同的是,Vue 采用自底向上增量开发的设计。Vue 的核心库只关注视图层,并且非常容易学习,非常容易与其它库或已有项目整合。另一方面,Vue 完全有能力驱动采用单文件组件Vue生态系统支持开发复杂单页应用。

  • 渐进式:从核心到完备的全家桶
  • 增量:从少到多,从一页到多页,从简单到复杂
  • 单文件组件: 一个文件描述一个组件
  • 单页应用: 经过打包生成一个单页的html文件和一些js文件vue对象与HTML关系

Vue对象与html关系

在这里插入图片描述

1.1.2 vue优缺点
  • Vue 不缺入门教程,可是很缺乏高阶教程与文档
  • Vue不支持IE8
  • 量级问题(angular和react)
1.1.3 一个vue页面(在html中)以及插值表达式

按照Vue的语法 {{}}: 插值表达式
插值表达式: 根据表达式的内容 找到’对应的Vue对象’ 的 参数自定义的地方(一般是data),里面 获取对应参数值, 替换 — 运算 -->

引入vue.js最好放在head部分引入(避免页面抖屏)

执行过程:

  1. 创建了一个Vue对象(根据Vue语法)
  2. 这个Vue对象一旦创建, 会立即检查 它的el属性
  3. 他会根据el属性找到一个对应id的html代码
  4. 如果找到了, 把找到的html代码所对应的作用域 和 这个Vue对象’绑定起来’
  5. 这个html代码所对应的作用域 就不在仅仅是html代码作用域, 还是这个Vue对象作用域
  6. 这个作用域代码 会重新, 按照Vue语法再解析一遍
  7. el data: Vue固有属性

3\18 Lesson5
01_index2.html

下面很重要,入门理解

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./vue.js"></script>
</head>
<body>
	
	dom解析:是一个从上而下的过程
	1, div被解析,{{msg}}只是一个普通的文本,没有任何别的特殊的地方
	2, script被解析,创建了一个对象,这个对象是vue对象
	3, {{msg}}按照vue语法, 就不再是单纯的文本, 而是叫插值表达式
			插值表达式: 是个可以做运算的式子, 参数是在对应的vue对象中取出来的
			一般是在对应的vue对象 的data中取出的
    <div id="root">
<!--       插值表达式-->
        {{msg}}

<!--        双向绑定-->
        <input v-model="msg">
    </div>
    <script>
        // 创建一个vue对象
        dom解析从上而下,解析到这个创建对象的时候
        1, 检查这个vue对象的el属性,它会根据el属性所指向的内容,查找对应的html元素
        2, 如果找到了这个id相同的html标签/结点/元素, 建立绑定关系(这个vue对象和对应的html域)
        3, 那么, 对应html域就不在是单纯的html语法域, 而是vue+html语法域
		4, 这个曾经被解析过的html标签域, 会按照vue语法重新再解析一遍
        new Vue({
            el:"#root",
            data: {// 我们自定义一些属性
                msg: "123"
            }
        })

    </script>



</body>
</html>

Note:

绑定的vue对象和html域分别是
		html域:<div>标签包裹的部分,即插值表达式msg和input标签
		<div id="root">
        	{{msg}}
			<input v-model="msg">
    	</div>

		new Vue({
            el:"#root",
            data: {
                msg: "123"
            }
        })

遇到错误,第一步是打开浏览器的控制台

上面很重要,入门理解

3\19 Lesson1
最最常用的2个微指令:单向绑定和双向绑定

1.2 V指令(vue最核心的语法)

前端程序员最常用的3个东西(习惯):index、root、app

V-bind:单向绑定(可简化为:)

用来绑定数据和属性以及表达式

可以简化为一个冒号: 如下等价

<img v-bind:src="msg">
<img :src="msg">
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../vue.js"></script>
</head>
<body>

    //Vue对象的作用域就是外层div标签内的部分
    <div id="root" >
        <img src="1111.png">

<!--        单向绑定: 把html中的一些属性,绑定一个值(在vue对象中定义的值/参数)-->
<!--        单向: src 依赖于 url这个参数-->
<!--        <img src="url">是不可以的-->
        <img v-bind:src="url">
<!--        相当于, 从vue对象中取出url的参数, 赋值给这个src属性-->
<!--        另外, 如果vue对对象中这个url参数一旦改变, 这个src指向内容会跟着改变 -->


        <!--        单向: title 依赖于 msg这个参数-->
        <div v-bind:title="msg">
            div
        </div>
    </div>


    <script>
        new Vue({
            el: "#root",
            data: {
                msg: "zs",
                url: '1111.png'
            }
        })

    </script>

</body>
</html>

在这里插入图片描述
注:移动到div上面会显示zs

V-model:双向数据绑定(可省略 :value)

双向绑定: 是在单向绑定的基础上, 双向/相互影响
只能用于表单元素的value上
如下等价: (原因是双向绑定只能绑定表单元素的value值)

<input v-model:value="msg">
<input v-model ="msg">

03_双向绑定.html

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

    <div id="root" >
       {{msg}}
<!--        输入1111.png则显示图片。输入框写图片路径很奇怪。-->
<!--        因为双向绑定,msg值改变,所有引用msg值的都会跟着改变。-->
        <img v-bind:src="msg">


<!--        value 和 msg 相互影响 -->
<!--        输入导致value改变,value改变则msg改变,msg改变则插值表达式改变-->


        <input v-model:value="msg">
    </div>
    <script>
        new Vue({
            el: "#root",
            data: {
                msg: "zs"
            }
        })

    </script>


</body>
</html>

在这里插入图片描述

03_双向绑定2.html

<body>
<!--    3个表单元素:input、textarea、select-option-->
    <div id="root" >
       {{msg}}
        <img v-bind:src="msg">
        <img :src="msg">

<!--        value 和 msg 相互影响 -->
        <input v-model:value="msg">
<!--        只能绑定value值,所以可以不写-->
        <input v-model ="msg">

        <textarea  v-model ="msg"></textarea>

        <select v-model="msg">
            <option value="1">1</option>
            <option value="2">2</option>
            <option value="3">3</option>
            <option value="4">4</option>
        </select>

    </div>
    <script>
        new Vue({
            el: "#root",
            data: {
                msg: "3"
            }
        })

    </script>


</body>

在这里插入图片描述

V-text,V-html:类似更新元素的innerText、innerHtml

类似于innertext innerhtml

<body>

    <div id="root">
        <div>
            {{msg}}
        </div>
        <hr>
<!--        不会解析-->
        <div v-text="msg"></div>
<!--        会解析-->
        <div v-html="msg"></div>

        <hr>
        <div v-text="obj.name"></div>

        <div v-text="obj.age"></div>


        <div v-html="obj.name"></div>

        <div v-html="obj.age"></div>


    </div>
    <script>
        new  Vue({
            el: "#root",
            data: {
                msg: "<b>zs</b>",

                obj:{
                    name: "<b>zs</b>",
                    age: 18
                }
            }
        })
    </script>

</body>

在这里插入图片描述

V-show:标签控制隐藏(display设置none)

隐藏和显示
对于v-show而言, 无论显示与否, 都要加载到dom上
面试前端必问题,java面试中的hashmap

<body>

<div id="root">
    <div v-show="bool1">
        123
    </div>

</div>
<script>
    new  Vue({
        el: "#root",
        data: {
            // true:控制台为display:none
            // 改为false则不显示,控制台无
            bool1: true
        }
    })
</script>

</body>
V-if:根据表达式的值的真假渲染元素

分支语句的隐藏和显示
对于v-if而言, 如果不显示, 不会加载到dom上(区别于V-show)

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

<div id="root">
    <div v-if="1 == 1">
        v-if
    </div>
    <div v-else-if="bool2">
        v-else-if
    </div>
    <div v-else>
        v-else
    </div>

</div>
<script>
    new  Vue({
        el: "#root",
        data: {
            bool1: false ,
            bool2: true
        }
    })
</script>

</body>
</html>

在这里插入图片描述

V-on:用于事件监听(可简化为@)
<button v-on:click="f">按钮</button>
<button @click="f">按钮</button>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../vue.js"></script>
</head>
<body>

<div id="root">

    <div>
        {{msg}}
    </div>

<!--    v-on监听了一个事件(click点击事件), 意味着button一旦被点击, 就会被(v-on)监听到
            监听之后触发, 触发到对应vue对象中去-->

<!--    Vue写法是把onclick的on去掉,改为click-->
    <button v-on:click="f">按钮</button>
    <button @click="f">按钮</button>
<!--    <button οnclick="f()">按钮</button>-->
</div>
<script>
    new  Vue({
        el: "#root",
        data: {// 存储vue我们自定义的数据
            msg: "zs"
        },

        // 我们希望把方法创建到里面,来改变msg的值
        methods: {// 写我们自定义方法

            //f这么写
            f:function () {
                // 一定要加this(不加访问不到), 这个this代指这个vue对象
                // 语法规定可以直接找到,不用this.data.msg
               this.msg = "ls"
            }
        }
    })

    // function f() {
    //     alert(123)
    // }
</script>

</body>
</html>

在这里插入图片描述

vue的核心(环状结构)(以后感受)

在这里插入图片描述


作业:Dom实现改为使用vue实现

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        div{
            width: 100px;
            height: 100px;
            line-height: 100px;
            text-align: center;
            background: red;
            margin: 0 auto;
            font-size: 35px;
            color: white;
        }
        .div2{
            width: 100px;
            height: 100px;
            line-height: 100px;
            text-align: center;
            margin: 0 auto;
            background: none;
        }
    </style>
    <script src="../vue.js"></script>
</head>
<body>

    <div id="root">
        <div id="div1">
            {{msg}}
        </div>
        <div class="div2">
            <button v-on:click="getname">点名</button>
        </div>

    </div>


    <script>
        new Vue({
            el: "#root",
            data: {
                list : ['zs', 'ls', 'wu', 'zl'],
                mid : -1,
                msg: "zs"
            },
            methods: {
                getname: function () {
                    var index = Math.floor(Math.random()*this.list.length)
                    while (index == this.mid){
                        index = Math.floor(Math.random()*this.list.length)
                    }
                    this.mid = index

                   this.msg = this.list[this.mid]
                }
            }
        })

    </script>

</body>
</html>

在这里插入图片描述

V-pre:阻止预编译
<body>

<div id="root">
<!--    不会再被解析-->
    <div v-pre>
        {{msg}}
    </div>

</div>
<script>
    new  Vue({
        el: "#root",
        data: {

        }
    })

</script>

</body>

在这里插入图片描述

V-once:只编译一次
<body>

<div id="root">

<!--    需求:希望插值表达式的值不要跟着改变(即input输入改变导致data中msg改变后)-->
<!--    只编译一次:插值表达式替换为zs的时候编译一次-->
    <div v-once>
        {{msg}}
    </div>
    <input v-model="msg">

</div>
<script>
    new  Vue({
        el: "#root",
        data: {
            msg: 'zs'
        }
    })

</script>

</body>

在这里插入图片描述

V-cloak:延迟加载
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../vue.js"></script>
    <style>
        /*属性选择器*/
        [v-clock]{
            /*隐藏*/
            display: none;
            /*font-size: 100px;*/
        }
    </style>
</head>
<body>

    <div id="root">
<!--       在div自定义了一个属性, v-clock ,  -->
<!--       3s后,当html代码按照vue语法重新解释的时候, 遇到v-clock会把这个属性立马删除-->
        <div v-clock>
            {{msg}}
        </div>

    </div>
    <script>

        // 定时器: 3秒之后, 执行 f方法
        setTimeout('f()', 3000)
        function f() {
            // 3秒之后,才触发f方法,才创建Vue对象,才建立绑定关系,才按照vue语法解释上面的域,即msg
            new Vue({
                el:"#root",
                data: {
                    msg: 123
                }
            })
        }

    </script>

</body>
</html>

在这里插入图片描述

V-for:基于源数据多次渲染元素或模板块(循环渲染元素)

注意1:
v-for: 写在那个标签上, 循环遍历的就是那个标签

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

    <div id="root">

<!--        无序列表:ul-li-->
        <ul>
<!--            <li>{{list[0]}}</li>-->
<!--            <li>{{list[1]}}</li>-->
<!--            <li>{{list[2]}}</li>-->
<!--            <li>{{list[3]}}</li>-->
<!--            v-for是一个循环, 写在那个标签上循环渲染出多个这样的标签 -->
            <li v-for="aaaa in list">
            	{{aaaa}}
            </li>


        </ul>
        <input v-model="str"><button v-on:click="addli">添加</button>

    </div>
    <script>
        new Vue({
            el: "#root",
            data: {
                list: ["zs", "ls", "wu", "zl"],
                str: ''
            },
            methods: {
                addli: function () {
                    this.list.push(this.str)
                    this.str = ''
                }
            }

        })
    </script>

</body>
</html>

在这里插入图片描述

注意2:
对于v-for遍历 in/of 都可以, 没有什么区别

注意3:

在vue中如果使用v-for这个指令, 那么必须给每一个v-for指令所遍历出的元素/标签, 加一个:key=”唯一值” key不可重复
Key是一个底层标记(给底层代码用的): 不是给我们(程序员)用的

方式1:

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

    <div id="root">
        <ul>
<!--            v-for是一个循环, 写在那个标签上循环渲染出多个这样的标签 -->
<!--            in/of  都可以用来遍历, 没有区别   -->


<!--            <li v-for="aaaa of list">{{aaaa}}</li>-->
<!--            不正确-->

<!--            对于v-for: 如果要做循环遍历, 必须要有key, 并且key要唯一 -->
<!--            :是双向绑定的缩写-->

<!--            <li v-for="aaaa of list"  :key="aaaa">{{aaaa}}</li>-->
<!--            key绑定下标tag,这不是最终手段-->
            <li v-for="(aaaa, tag) of list"  :key="tag">{{aaaa}}--{{tag}}</li>


        </ul>
        <input v-model="str"><button v-on:click="addli">添加</button>

    </div>
    <script>
        new Vue({
            el: "#root",
            data: {
                list: ["zs", "ls", "wu", "zl"],
                str: ''
            },
            methods: {
                addli: function () {
                    this.list.push(this.str)
                    this.str = ''
                }
            }

        })
    </script>

</body>
</html>


PM Lesson

方式2:

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

    <div id="root">
        <ul>
<!--            v-for是一个循环, 写在那个标签上循环渲染出多个这样的标签 -->
<!--            in/of  都可以用来遍历, 没有区别   -->
<!--            对于v-for: 如果要做循环遍历,
                    必须要有key, 并且key要唯一 (这个key不是给程序员使用的), 底层-->
<!--            <li v-for="aaaa of list"  :key="aaaa">{{aaaa}}</li>-->
            <li v-for="aaaa of list"  :key="aaaa.id">{{aaaa.name}}</li>

<!--            只想显示name,就写aaaa.name。否则就是对象-->


        </ul>
        <input v-model="str"><button v-on:click="addli">添加</button>

    </div>
    <script>
        new Vue({
            el: "#root",

            // 对象数组,上面遍历出来的是对象,用id来充当key即key="aaaa.id",这才是常见的写法
            data: {
                list: [{
                   id: 1,
                   name: 'zs'
                }, {
                    id: 2,
                    name: 'zs'
                }, {
                    id: 3,
                    name: 'ls'
                }],
                str: ''
            },
            methods: {
                addli: function () {
                    this.list.push(this.str)
                    this.str = ''
                }
            }

        })
    </script>

</body>
</html>

方式3:(向列表中添加元素,点击某个元素,就删除某个元素)

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

    <div id="root">
        <ul>
<!--            v-for是一个循环, 写在那个标签上循环渲染出多个这样的标签 -->
<!--            in/of  都可以用来遍历, 没有区别   -->
<!--            对于v-for: 如果要做循环遍历, 必须要有key, 并且key要唯一 -->
<!--            <li v-for="aaaa of list"  :key="aaaa">{{aaaa}}</li>-->
            <li v-for="(aaaa, tag) of list"
                :key="tag"
<!--                tag为要删除的下标-->
                @click="deleteli(tag)"
            >{{aaaa}}--{{tag}}</li>


        </ul>
        <input v-model="str"><button v-on:click="addli">添加</button>

    </div>
    <script>
        new Vue({
            el: "#root",
            data: {
                list: ["zs", "ls", "wu", "zl"],
                str: ''
            },
            methods: {
                addli: function () {
                    this.list.push(this.str)
                    this.str = ''
                },
                deleteli: function (index) {
                    this.list.splice(index, 1)
                }
            }

        })
    </script>

</body>
</html>

在这里插入图片描述

1.3 计算属性computed :指一个属性通过其他属性计算而来

计算属性, 首先是一个属性(外在表现), 这个属性是通过别的属性计算来的(依赖于别的属性而存在)

方式1:用方法来计算比较麻烦:

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

    <div id="root">
        {{sum}}
        <br>
        值1:<input v-model="input1" V-on:change="getsum"><br>
        值2:<input v-model="input2" @change="getsum">

    </div>
    <script>
        new Vue({
            el: "#root",
            data: {
                sum: 0,
                input1: '',
                input2: ''
            },
            methods: {
                getsum: function () {
                    this.sum = parseInt(this.input1) + parseInt(this.input2)
                }
            },
            computed: { // 表示的是计算属性

            }
        })
    </script>

</body>
</html>

方式2:改为使用计算属性来写:

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

    <div id="root">
<!--        找值,data找, 如果在data里面找不到, 去计算属性找 -->
        {{sum}}<br>
<!--        双向绑定:value和input1相互影响-->
        值1:<input v-model:value="input1" ><br>


        <!--        注意:这里是双向绑定的省略写法。只能绑定value值,所以可以不写。-->
        <!--        值1:<input v-model="input1" ><br>-->
        值2:<input v-model="input2" >

    </div>
    <script>
        new Vue({
            el: "#root",
            data: {
                input1: '',
                input2: ''
            },
            computed: { // 表示的是计算属性
                
                // 计算属性, 首先是一个属性,
                // 这个属性是通过别的属性计算来的(依赖于别的属性而存在)
                // 方法名, 这个计算属性的属性名sum
                sum: function () {
                    // 不要在这里面写过多的逻辑(必要的逻辑是可以的)
                    return parseInt(this.input1) + parseInt(this.input2)
                }
            }
        })
    </script>

</body>
</html>

1.4 侦听器watch:监听一个属性改变触发一个事件

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

    <div id="root">

        {{sum}}<br>
        值1:<input v-model="input1" ><br>
        值2:<input v-model="input2" >

    </div>
    <script>
        new Vue({
            el: "#root",
            data: {
                sum: 0,
                input1: '',
                input2: ''
            },
            computed: {
                sum1: function () {
                    return parseInt(this.input1) + parseInt(this.input2)
                }
            },
            watch: {// 侦听器, 侦听一个属性的改变

                // // 侦听input1的改变, input1一旦改变就会触发这个方法
                // input1: function () {
                //     this.sum = parseInt(this.input1) + parseInt(this.input2)
                // },
                //
                // input2: function () {
                //     this.sum = parseInt(this.input1) + parseInt(this.input2)
                // },


                // 也可以侦听计算属性sum1:计算属性当做属性来看待
                sum1: function () {
                    this.sum = this.sum1
                }

            }
        })
    </script>

</body>
</html>

在这里插入图片描述

2. 模板和组件

vue核心3个
微指令、模板(组件的补充)和组件(核心)

2.1 模板

模板的好处: 以后只需要在html留一个入口, 一切的内容都可以转移到vue对象中去

<div id="root"></div>

先基础性地理解模板

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

<!--    这里的div会被忽略,即被下面的模板替换-->
    <div id="root">
        {{msg}} 123
    </div>

    <script>
        //template:
            //一个字符串模板作为 Vue 实例的标识使用。
            //模板将会 替换 挂载的元素。挂载元素的内容都将被忽略.

            // 所谓挂载:  html解析生成dom结点, 和dom树建立联系(对象引用关系)
        new Vue({
            el: "#root",
            data: {
                msg: 123
            },
            template: "<div>aaaa</div>"

        })
    </script>

</body>
</html>

模板的好处: 以后只需要在html留一个入口, 一切的内容都可以转移到vue对象中去

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

    <div id="root"></div>


    <script>
        // 模板的好处: 以后只需要在html留一个入口, 一切的内容都可以转移到vue对象中去
        // 解耦:


        // 所谓挂载:  html解析生成dom结点, 和dom树建立联系(对象引用关系)
        //template:
            //一个字符串模板作为 Vue 实例的标识使用。
            //模板将会 替换 挂载的元素。挂载元素的内容都将被忽略.
        new Vue({
            el: "#root",
            data: {
                msg: 123
            },
            template: "<div>    <div @click='f'>{{msg}}</div>   <input v-model='msg'>   </div>",
            methods: {
                f: function () {
                    alert(123)
                }
            }
        })
    </script>

</body>
</html>

在这里插入图片描述

2.2组件

一个Vue对象就叫一个Vue组件

组件.html

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

    <div id="root">
<!--        重新解析的时候,可以识别自定义标签aaaa,aaaa代表一个test1的对象-->
<!--        这个对象有模板,模板<div>123</div>替换挂载的元素<aaaa></aaaa>-->
            <aaaa></aaaa>
    </div>
    <script>

        // 普普通通的js对象
        var test1 = {
            template: "<div>123</div>"
        }


        // component
        new Vue({
            el: "#root",
            data: {},
            components: {// 导入子组件, 导入子Vue对象\
                // 别名:  原对象名
                aaaa: test1
                // 上面的js对象test1导入进来,和vue语法建立联系,就成为vue对象

            }
        })
    </script>

</body>
</html>

组件2.html:详细分析整个过程

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
<!--    step1:加载Vue语法-->
    <script src="vue.js"></script>
</head>
<body>

<!--    step2:普通的div和div下面普通的aaaa标签-->
    <div id="root">
<!--        step4:发现这不是html语法,在子组件中检查有没有定义aaaa标签。有,对应test1就是Vue的子对象了,也就是一个Vue对象了-->
<!--        这里的内容就变成test1的所有内容,检查有没有模板;有模板,<div><div @click='f'>{{msg}}<div></div>替换<aaaa></aaaa>-->
            <aaaa></aaaa>

<!--        使用了才会有显示-->
            <bbbb></bbbb>
    </div>


    <script>

        // step3:普普通通的js对象
        var test1 = {
            template: "<div><div @click='f'>{{msg}}<div></div>",

            // msg引发到这里了
            data(){
                return{
                    msg: 222
                }
            },
            // 点击触发到这里
            methods: {
                f: function () {
                    alert(123)
                }
            }
        }

        // 可以有多个Vue对象,再注册一个test2就可以
        var test2 = {
            template: "<div><div @click='f'>{{msg}}<div></div>",
            data(){
                return{
                    msg: 3333
                }
            },
            methods: {
                f: function () {
                    alert(123)
                }
            }
        }

        // step3:创建Vue对象,检查el,重新解析step2中的Vue域

        // component
        new Vue({
            el: "#root",
            data: {
                msg: 123
            },



            // 在这里注册之后,上面的才成为Vue


            components: {// 导入子组件, 导入子Vue对象\
                // 别名:  原对象名
                aaaa: test1,
                bbbb: test2
            }
        })
    </script>

</body>
</html>

在这里插入图片描述

组件3.html: (上面的清空,这里加一个模板,显示的结果同上)

在这里插入图片描述

模板和组件加在一起构建出Vue的一个核心理论:把页面拆分成很多Vue对象,每一个Vue对象管控一小 片区域,Vue对象间通过父子的Vue对象,构建引用关系,最终汇合成一个页面。(这就是Vue的本质的东西)


3/19 PM Lesson2

2.3 生命周期(2创建 + 2挂载 + 2修改 + 2销毁)

重要程度和组件与模板不在一个量级上面

beforeCreate
Created

beforeMount
Mounted

beforeUpdtae
Updated

beforeDestroy
destoryed

创建对象的时候触发2个方法

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

    <div id="root">
<!--        执行创建和挂载的4个-->
        {{msg}}

<!--        修改msg,beforeUpdate和updated-->
        <input v-model="msg">
    </div>
    <script>
        var  root = new Vue({
            el: "#root",
            data: {
                msg: 123
            },
            beforeCreate:function () {
                console.log("控制台打印:beforeCreate")
            },
            created:function () {
                // 请求
                // 获得后端数据
                // 赋值给data数据
                // 就可以显示了
                console.log("控制台打印:created")
            },
            beforeMount:function () {
                //页面还未被渲染
                console.log(this.$el),
                    console.log("控制台打印:beforeMount")
            },
            mounted:function () {
                //页面渲染完成
                console.log(this.$el),
                    console.log("控制台打印:mounted")
            },
            beforeUpdate:function () {
                console.log("控制台打印:beforeUpdate")
            },
            updated:function () {
                console.log("控制台打印:updated")
            },
            beforeDestroy:function () {
                console.log("控制台打印:beforeDestory")
            },
            destroyed:function () {
                console.log("控制台打印:destroyed")
            }
        })
    </script>

</body>
</html>

在这里插入图片描述

在这里插入图片描述

讲为什么created和mounted常用,先讲前后端分离

在这里插入图片描述

2.4 前后端分离

在这里插入图片描述

3. Vue项目(创建一个项目)

安装jdk(运行环境)   idea  通过idea创建project   写代码.java   编译打包发布

安装node(js运行环境)  vue-cli 通过vue-cli创建一个vue项目  写vue代码 编译打包发布 

3.1 创建一个vue项目

安装node

http://nodejs.cn/download/

默认安装(一直next)就可以
如下成功
在这里插入图片描述

安装cnmp

npm install -g cnpm --registry=https://registry.npm.taobao.org

npm: 命令
install 安装
-g:  全局安装
Cnpm : 安装的那个包
--registry=https://registry.npm.taobao.org:  去那个地方下载这个包

如下成功
在这里插入图片描述
在这里插入图片描述

安装vue-cli

安装脚手架工具
cnpm install -g @vue/cli
cnpm install -g @vue/cli-init

如下成功
vue -V (v必须大写)
在这里插入图片描述

Webpack(模块打包机)

cnpm install -g webpack

Java  war jar 
前端  html css js
上面都是在配置环境
***
创建项目
路径在哪里,项目就创建在哪里

比如想把项目创建在桌面,就在命令符窗口把路径切换到桌面desktop下

vue init webpack 项目名(不要大写)

vue init webpack vuetest

默认回车
y/n 统一选n 再回车
注意最后一步: 手动安装

切换路径到项目目录下(如vuetest下)
执行cnpm install安装包node_modules

如下成功
在这里插入图片描述

启动前端项目:nmp run dev

实际上启动的是一个前端服务器

在这里插入图片描述
前端服务器启动成功
在浏览器中输入

http://localhost:8080

如下成功
在这里插入图片描述


day 6 AM

给一个前端项目怎么启动(做项目的时候)(只需要做一件事情,如下)
1, 下载下来
2, 给它装包: node_modules
3, 启动: npm run dev

在这里插入图片描述

37 KB
在这里插入图片描述

cnpm install
只多了一个包node_modules

80 MB
在这里插入图片描述

3.2 要了解的配置文件

第一个:index.js
关于端口的设置,一般默认8080就可以
在这里插入图片描述

第二个:package.json
Vue项目下执行Cnpm install安装包(没写包名怎么知道安装哪个?)(安装下面package.json文件中的包)(都在node_modules文件下)

Cnpm install -g  @vue/cli

Cnpm install 

Npm run dev 启动的是一个前端服务器

在这里插入图片描述

启动一个项目不一定通过nmp run dev
在这里插入图片描述

第3个:index.html
整个项目的入口

index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <title>vuetest</title>
  </head>
  <body>
    <div id="app"></div>
    <!-- built files will be auto injected -->
  </body>
</html>

main.js

// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'

Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({
  el: '#app',
  components: { App },
  template: '<App/>'
})

App.vue
在这里插入图片描述

Q:显示123创建了几个vue对象?
A:2个。main.js中new的一个,其中还导入了一个App子对象


3.3 组件传值

3.3.1 父子组件传值
3.3.1.1 子组件向父组件传值

子组件抛出方法:

this.$emit("changeinput", this.inputstr)

父组件接受方法:

<left class="left" v-on:changeinput="appchange"></left>
3.3.1.2 父组件向子组件传值

父组件传递

<right class="right" v-bind:rightparame="str"></right>

子组件接收

props: ['rightparame']
props:等价看做data(一个区别, props里面的参数不可修改)
3.3.2 中央总线/bus

中转站

第一步: 创建bus文件

import Vue from 'vue' // 导入Vue语法

// 创建一个Vue对象
const bus = new Vue()

// 整个js文件, 默认向外界暴露只有一个bus对象
export  default  bus

第二步: 在main.js引入

import bus from './bus'
Vue.prototype.$bus = bus

第三步使用

3.3.3 使用第三方插件/包的步骤
1, 导入包, 或者引入配置文件
2, 在main.js配置
3, 使用
cnpm i element-ui --save
3.3.4 Axios

异步请求

3.3.5 补充
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Lacrimosa&L

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值