前端框架之Vue的初步学习

什么是vue?

官方解释:一套构建用户界面的渐进式框架。
只关注视图层,采用自底向上增量开发的设计。
它的目标是通过尽可能简单的API,去实现响应数据绑定和组合的视图组件。

vue的使用之前,我们要先引入一个vue的js文件,
两种方式:

模板引擎

  • 得到数据(用户产生,后续提供)
  • 将数据进行动态组装
  • 将组装好的内容添加到页面的指定元素中
    vue做的事情简单的说,就是将data和template相结合,最后添加到挂载点上 ,再渲染到页面

1、创建一个简单的 vue实例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>使用vue</title>
    <!-- 引入vue框架文件 -->
    <!-- <script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script> -->
</head>
<body>
    <div id="app"></div>
    <script>
        new Vue({
            //  el 指定的挂载点(使用id具有唯一性,灵活性,便于识别和开发)
            el: "#app",

            // template 模板(最终形成UI的原始结构)
            template:`<h1>{{title}}</h1>`,
            
            // 也可以添加img标签到模板中
            // template: `<img src="images/v.jpg"/>`,

            //  data 数据
            data: {
                title: "我是第一个大标题"
            }
        });
        // 执行后,页面div中即添加了一个标题内容为"我是第一个大标题"的h1标签
    </script>
</body>
</html>

2、vue挂载
使用vue需要挂载点,但有些情况是一开始不需要它,是在后面再添加上来的,称为延迟挂载

 <!--挂载元素-->
 <div id="app"></div>
 <!--使用class名称的挂载点元素-->
 <!--<div class="app"></div>-->
    <script>
        let app = new Vue({
            // 开始就注明挂载点
            // el: "#app",
            /* el:".app",  
            使用class名也可以,但是calss可以重复出现并使用,如果页面元素很多、
            布局复杂,就可能会出现class混用的情况,那class就不太适用了。
            使用id的好处:一方面是它具有唯一性,不会出现混淆的情况;
            还有就是它的灵活性。如果是循环或者嵌套循环等场景,可以动态设置和获取id。*/
            
            template: `<div id="app">
                          <h1>什么是延迟挂载</h1>
                       </div>`
        });
        console.log(app);

        // vue实例中,开始没有注明挂载点时,需要实例来调用$mount()去指定挂载点
        app.$mount("#app");
    </script>

注意:

  • el 挂载点不能是body和html
    vue挂载点不能是html或body

  • 当实例被挂载以后,实例对象上会有一个$el的属性(属性中存的内容就是挂载的元素)
    截图节选部分如下:vue实例被挂载后

  • vue实例上的内置属性都是以$或者_开头的
    截图节选部分如下:在这里插入图片描述

3、vue渲染页面
(1)template渲染
实际上vue是先把template模板内容加载到虚拟DOM中,再对虚拟DOM操作数据,然后将数据渲染到页面。
template模板-->虚拟DOM-->html页面

看看下面的例子:

  <!--挂载点元素-->
  <div id="app">
     <p>app是我大哥</p>
  </div>
    <script>
        new Vue({
            // 挂载点
            el:"#app",
            // 生成模板,会替换掉原来的挂载点元素
            template:`<div id="app">
               <h1>app是我老板</h1>
               <img src="images/v.jpg"/>
            </div>`,

            //如下写法,会报错: 
            //Component template should contain exactly one root element 提示模板只能有一个根节点
            // template:`<div id="app">
            //    <h1>标题1</h1>
            //    <img src="images/v.jpg"/>
            // </div>
            // <div id="app">
            //    <h1>标题2</h1>
            //    <span>我是span标签</span>
            // </div>`,
            data:{}
        });  
    </script>

如果vue实例中只有挂载点与data,没有template的情况:

   <div id="app">
        <p>{{name}}</p>
        <p>{{sex}}</p>
        <p>{{age}}</p>
    </div>
    <script>
        // 响应数据的变化-->数据驱动视图
        // 数据的变化会自动更新视图-->自动重新渲染模板
        let app = new Vue({
            el: "#app",
            data: {
                name: "布朗",
                sex: "男",
                age: 20
            }
        });
        console.log(app);
    </script>

在浏览器控制台上修改data中的数据,vue会自动重新渲染模板,对应的视图会更新,如下:
vue更新视图-数据驱动视图
Vue实例对象中有一个 d a t a 属 性 , 在 浏 览 器 控 制 台 中 修 改 数 据 后 , 视 图 也 会 更 新 。 比 如 修 改 a p p . data属性,在浏览器控制台中修改数据后,视图也会更新。 比如修改 app. dataapp.data.name=“约翰”,会把data中name的值以属性的形式添加到app中,如下图:
在这里插入图片描述

注意:

  • outerHTML:设置或获取对象及其内容的html
    innerHTML: 设置或获取对象的起始与结束标签内的html
  • 模板生成后,会替换掉挂载点el指定的元素
  • 每一个独立的模板有且只有一个顶级的根节点
  • 如果指定了el挂载点,却没有template,那么挂载点中的outerHTML将作为template;
    如果有template,会优先选择template中的内容

(2)vue中render()函数
vue中内置的render()函数,可以用js语言来创建DOM
因为vue中是使用虚拟DOM,因此template模板时也要转译成虚拟DOM的函数,
而用render函数创建DOM,vue就省掉了这个转译的过程。
所以,用render函数来渲染页面,灵活性更高 。

    <div id="app">
        <h1>今天天气好晴朗</h1>
        <div id="dvText">外出踏青</div>
    </div>
    <script>
        new Vue({
            el: "#app",
            // render()执行就会传入一个参数createElement,这个参数就是创建虚拟DOM的工具
            render(createElement) { 
                //传入参数,将h1中的内容替换掉
                // return createElement("h1","Good afternoon!");
               
                //传入参数,将div中的内容替换掉
                // return createElement("div",{id:"dvText"},"心情好,雨天也是晴天!");
                
                // createElement()函数:创建虚拟DOM,
                // 它的三个参数分别是:标签/元素、属性/样式、内容(里面还有子元素,如下写法)
                return createElement("div", {
                    attrs: {
                        id: 'app'
                    }
                },[createElement("p",{
                    attrs:{
                       id:'pEl'
                    }
                  },"Good afternoon")]);
             }
        });
    </script>

如下图:我们在id为app的div中创建一个p标签,并添加了条件文本内容,渲染到了页面上。
vue中的render函数创建虚拟DOM

  • 实际使用中我们不使用这种方法来渲染,上面的例子是来理解vue中render函数的作用与使用。
  • 正如前面所说,vue是通过template来渲染页面,更简单明了,便于开发。
  • 也可以使用原生js封装成函数 function createElement(tag,attrs,childrens){ //xx }; 不详说了

4、vue中的data
数据通过{{}}加载到模板中,模板加载到虚拟DOM中,
虚拟DOM会把它送到指定的挂载点元素上,从而渲染到页面上。

  • 在当前模板中,data不需要使用this等关键字,比如this.name,
    它可以直接使用,数据都是在挂载点上生效的
  • data中的数据命名,不需要使用$_开头,vue解析data后,
    会把当前的data中的数据加载到实例对象中
 <div id="app"></div>
    <script>
        let app = new Vue({
            el:"#app",
            // 双大括号,又称大胡子语法
            // 在vue中,我们是通过一对大括号把实例中的数据渲染到模板内容中
            // {{}}双花括号,括号内直接写数据的属性名,不需要写前缀,比如this.title
            template:`<div><p>{{action}}</p></div>`,
            data:{
               action:"与代码做斗争"
            }
        }); 
        console.log(app);
    </script>

5、数据劫持
当我们访问或设置对象的属性的时候,都会触发相对应的函数,
然后在这个函数里返回或设置属性的值。
我们可以在触发函数,数据发生改变时候,做点别的事情,这就是“劫持”。

在Vue中其实就是通过Object.defineProperty()来劫持对象属性的setter和getter操作,
起到一个监听器的作用,当数据发生变化的时候发出通知。

 <div id="app">
     <h1>{{name}}</h1>
 </div>
    <script>        
        // 手动方式更新视图
        let app = document.querySelector("#app");
        function render(){
            // 拼接另一个属性age
            app.innerHTML = obj.attr+"-"+obj.age;
        }
        let obj = {attr:"cool"};
        render();
        
        // 浏览器控制台修改数据,控制台数据修改了,但是页面上的数据没有实时更新 
        /* obj.attr="beautiful";
           "beautiful"
           obj.attr = 10;
           10 
        */
       
        // obj.attr = "beautiful";//手动更新一下数据
        // render();//再次渲染页面,页面数据更新了

        //再次在浏览器控制台修改数据,再调用render()方法后,页面数据更新了
        /* obj.attr="lovely";
           "lovely"
           render();
           undefined 
        */

        // vue的方式更新视图
        // vue就是通过监听,将这个数据手动修改与更新的过程自动化了
        // defineProperty()用来监听数据的属性(只能监听单个属性,新增属性监听不了,需要再写一次)

        let $data = {attr:"cool"};//$data替代obj
        // // let $data = obj;//会报错Maximum call stack size exceeded

        
        Object.defineProperty(obj,"attr",{
            set(newValue){
                // obj.attr = newValue;//这样写就成了死循环,attr永远跳不出来
                $data.attr = newValue;//每次修改的是冒充的对象$data
                render();
            },
            get(){
                return $data.attr;//获取时覆盖原来的值
            }
        });

        // 浏览器控制台修改数据,页面同时更新了
        /* obj.attr="instersting";
           "instersting" 
           obj.attr="cute";
           "cute"
        */
           
        // 比如如果有别的属性age,需要再写一次监听,不然会出现更新其中一个,另一个属性不会更新的问题
        Object.defineProperty(obj,"age",{
            set(newValue){
                $data.age = newValue;   
                render();
            },
            get(){
                return $data.age;
            }
        });

        /* obj.attr="tom"
           "tom"
           obj.age=20;
           20 */
    </script>

补充:

  • vue3.0加入了Proxy对象,去解决只能监听单一属性的问题,暂时没有使用文档

为了解决Object.defineProperty()只能监听单个属性的问题,vue中实例提供了一个set()方法
看一下案例

<div>
   <h1>name:{{obj.name}}</h1>
   <h1>age:{{obj.age}}</h1>
</div>
    <script>
        let app = new Vue({
            el:"#app",
            data:{
                obj:{name:"汤姆"}
            }
        });    
    </script>

修改obj的name属性值,页面会随之更新;而修改属性age的值,页面却没有变化。截图如下:
分析:因为data中我们只监听了name属性,而age没有被监听。
在这里插入图片描述
我们再次修改name的值,age修改后的值才会显示出来,就是说age是随着name的改变而变化的。而单独修改age值,页面不受影响,截图如下:
在这里插入图片描述

我们使用vue实例提供了方法$set(),这样就可以添加age属性,从而监听到age的值的变化

 <script>
        let app = new Vue({
            el:"#app",
            data:{
                obj:{name:"汤姆"}
            }
        });    
      // 使用$set()添加age   
      app.$set(app.obj,"age",20);
    </script>

调用$set()后,看看,age属性值也可以被监听到了,控制台做出修改,页面会实时更新了!
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值