vue3 基础概念 (含与 vue2.6 的对比)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vue3 基础概念 (含与 vue2.6 的对比)相关的知识,希望对你有一定的参考价值。

参考技术A

计算属性是基于它们的响应式依赖进行缓存的。只在相关响应式依赖发生改变时它们才会重新求值。这就意味着只要 message 还没有发生改变,多次访问 reversedMessage 计算属性会立即返回之前的计算结果,而不必再次执行函数。
相比之下,每当触发重新渲染时,调用方法将总会再次执行函数。
通常更好的做法是使用计算属性而不是命令式的 watch 回调。

Vue 将被侦听的数组的变更方法进行了包裹,所以它们也将会触发视图更新。这些被包裹过的方法包括: push() 、 pop() 、 shift() 、 unshift() 、 splice() 、 sort() 、 reverse()

同时绑定多个事件

不同于组件和 prop ,事件名不存在任何自动化的大小写转换。因为 html 是大小写不敏感的,因此推荐你始终使用 kebab-case 的事件名。

使用场景:由于 vue 有 $parent 属性可以让子组件访问父组件。但孙组件想要访问祖先组件就比较困难。通过 provide / inject 可以轻松实现跨级访问祖先组件的数据。
provide:Object | () => Object
inject:Array<string> | [key: string]: string | Symbol | Object

提示: provide 和 inject 绑定并不是可响应的。然而,如果你传入了一个可监听的对象,那么其对象的属性还是可响应的。

动态组件:

异步组件:

混入 mixin 提供了一种非常灵活的方式,来分发 Vue 组件中的可复用功能。一个混入对象可以包含任意组件选项。当组件使用混入对象时,所有混入对象的选项将被“混合”进入该组件本身的选项。

将插槽内容传送至指定位置,接受一个 to 的属性,它接受一个 css query selector 作为参数,这就是代表要把这个组件渲染到哪个 dom 元素中

Suspense 组件用于在等待某个异步组件解析时显示后备内容。

AsyncShow.vue

index.vue

vue初学:基础概念

一、vue使用步骤:
  1.引包vue.js
  2.html中写要操作的DOM节点
  3.创建vue对象:new Vue({options});
  4.配置options:el:(要操作的对象,用选择器,同jquery),
        emplate:(模板,指定要插入的内容:{{插值表达式}},注:必须只有一个根节点),
        data(function(){return key:emplate中要操作的数据}),
        methods:{函数名:function(){函数体,(this.xxx调用data中定义的数据)(this.xxxMethods调用methods中的方法)}}
        components:{‘在emplate中要使用的标签名‘:要声明的子组件名}

二、vue基础概念:
  1.插值表达式可以是:data中定义的数据;{{ ‘字符串‘ }};三元表达式;布尔值;对象{{ {key:value} }}
  2.指令:形如"v-xxx",用于更简便的操作页面和数据。

三、 常用vue指令:
  1.v-text
  2.v-html
  3.v-if
  4.v-else-if
  5.v-else
  6.v-show
  7.v-bind 给属性绑定值,语法:v-bind:属性名="常量||变量名"(常量要写引号),简写 :属性名="常量||变量名"
  8.v-on 绑定事件 语法:v-on:事件名="函数名||表达式",简写 @事件名="函数名||表达式"
  9.v-if和v-show的区别:
    v-if和v-show都是用来控制元素的渲染。v-if判断是否加载,可以减轻服务器的压力,在需要时加载,但有更高的切换开销;v-show调整DOM元素的CSS的dispaly属性,可以使客户端操作更加流畅,但有更高的初始渲染开销。如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。
  10.v-bind和v-model区别:
    v-bind可设置所有属性的属性值,但只能单向读取vue中的数据;
    v-model只可设置value属性值,属于双向数据流
  11.v-for 遍历数组或对象,语法:v-for="item in arr/obj"
    扩展知识点:
    数组:v-for="(item,index) in arr"
    对象:v-for="(value,key,index) in obj"

  附demo:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>vue第一个页面</title>
        <script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
        <style>
            .a{
                background-color: #ccc;
            }
            .b{
                background-color: pink;
            }
        </style>
    </head>
    <body>
        <div id="zl"></div>
        
    <script type="text/javascript">
        new Vue({
            el : "#zl",
            template : `<div>  
                    <div v-text="myText"></div>  
                    <hr/>  
                    <div v-html="myHtml"></div>  
                    <h4 v-if="isExit">v-if控制是否存在</h4>
                    <h4 v-show="isShow">v-show控制是否显示</h4>
                    <!-- 以下三个指令,需结合使用 -->
                    <button v-if="num == 1" >测试v-if</button>
                    <button v-else-if="num == 2" >测试v-else-if</button>
                    <button v-else >测试v-else</button> 
                    
                    <input type="text" v-bind:value="myBind" :file=" ‘XXX‘ "></input>
                    <button v-on:click="myBind=‘aaa‘">用v-on修改vue中数据</button>
                    <button @click="myBind=‘bbb‘">用v-on简写修改vue中数据</button>
                    <!-- 双向绑定 -->
                    <hr/>
                    <i>当用户输入“同意”时显示按钮:</i>
                    <input type="text" v-model="myModel"/>
                    <button type="submit" v-show="myModel==‘同意‘ ">提交</button>
                    <!-- v-for -->
                    <hr/>
                    <ul>
                        <li v-for="item in stud" :class="item.class">{{item.name}}</li>
                    </ul>
                    <!-- methods -->
                    <button v-on:click="toggleCont">{{name}}</button>  <!-- 可缩写为@:click -->
                </div>`,
            data : function(){
                return {
                    name : "点我!",
                    myText : "<h1>我是myText的内容</h1>",
                    myHtml : "<h1>我是myHtml的内容</h1>",
                    isExit : true,
                    isShow : true,
                    num : 4,
                    myBind : "v-bind测试",
                    myModel : "v-model测试",
                    stud : [{name:张三,class:a},{name:李四,class:b},{name:王五,class:a}]
                }
            },
            methods : {
                toggleCont : function(){
                    this.name = "听话"
                }
            }
        });
        
    </script>
    </body>
</html>

 


四、组件化:
  1.局部组件使用步骤:1.创建子---2.声明子---3.使用子
    创建子组件:var 子组件名称(首字母大写)={
            template:‘子模板‘.....跟new Vue(){}中的内容一样
          }
    父组件components中声明子组件:components:{‘在emplate中要使用的标签名‘:要声明的子组件名}
    父组件template中使用子组件:template:‘<标签名></标签名>‘
  2.注册全局组件步骤:Vue.component(‘组件名‘,{.....})

五、 父组件向子组件传递数据:
  步骤:1.父传数据(属性)---2.声明数据---3.使用数据
    父组件template中,用v-bind将要传递的数据绑定到子组件标签属性中;
    子组件中props:[‘属性名‘]声明此数据;
    子组件template中{{属性名}}使用此数据

附demo:(用的Hbuild对es6的支持不是特别好,字符串拼接,忍。。。)

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>vue组件练习</title>
        <script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
    </head>
    <body>
        <div id="app"></div>
        <script type="text/javascript">
            //注册全局组件
            Vue.component(my-btn,{
                template : <button style="background-color:red;color:#fff;">红色的按钮</button>
            })
            //局部子组件
            var Mytop = {
                data : function(){
                    return {
                        myText : <i>测试v-text</i>,
                        myHtml : <i>测试v-html</i>,
                        myValue : 单/双向数据流...,
                        stud : {
                            name : jack,
                            sex : ,
                            age : 26    
                        },
                        studs : [张三,李四,王五]
                    }
                },
                props : [myTest],
                template : <div><h5>我是头部</h5>+<p v-text="myText"></p>+
                        <p v-html="myHtml"></p>+<p v-if=""></p><hr/>+
                        单向v-bind:<input type="text" :value="myValue"/>+
                        双向v-model:<input type="text" v-model="myValue">+
                        <p>这里输出v-model中双向绑定的数据:{{myValue}}</p><hr/>+
                        v-for循环对象:<ul><li v-for="(val,key,i) in stud">{{key}}:{{val}}:{{i}}</li></ul>+
                        v-for循环数组:<ul><li v-for="item in studs">{{item}}</li></ul><hr/>+
                        <b>接收到父组件的数据为:{{myTest}}</b><hr/>+
                        <my-btn/></div>
                        
            }
            var Mybody = {
                data : function(){
                    return {
                        isShow : true,
                        isExit : true
                    }
                },
                template : <div><p v-show="isShow">我是中部v-show测试</p>+
                        <p v-if="isExit">v-if测试</p>+
                        <button @click="myToggle">点我显示或隐藏</button>+
                        <my-btn/></div>,
                methods : {
                    myToggle : function(){
                        this.isShow = !this.isShow;
                        this.isExit = !this.isExit;
                    }
                }
            }
            //入口组件
            var App = {
                components : {
                    mytop : Mytop,
                    mybody : Mybody,
                    
                },
                data : function(){
                    return {
                        myTest : 我是父向子传递的数据
                    }
                },
                template : <div><h3>我是入口</h3>+<mytop :myTest="myTest"></mytop>+<mybody/>+
                        <my-btn/></div>,
            }
            new Vue({
                el : "#app",
                components : {
                    app : App
                },
                template : <app/>
            })
        </script>
    </body>
</html>

 


六、 过滤器filter||filters:
  作用:用于A数据到B数据的产出
  局部过滤器filters:
    1.在局部组件中定义filters:{‘过滤器名‘,function(原数据形参,参数1){....return...}}
    2.使用:template中数据输出:{{原数据实参(指明针对谁进行操作) | 过滤器名(实参1)}}
  全局过滤器filter:
    1.Vue.filter(‘过滤器名‘,function(参数){...})
    2.使用与局部过滤器相同

附demo:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>过滤器filter || filters</title>
        <script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
    </head>
    <body>
        <div id="app">
            
        </div>
        <script type="text/javascript">
            Vue.filter(myTest,function(data){
                return 我是全局过滤器的内容,+data;
            })
            var App = {
                template :<div><h5>请输入内容,查看内容是否被反转:</h5>+
                    <input type="text" v-model="myText"/><p>{{myText | reverse("英文版")}}</p><hr/>+
                    <h5>全局过滤器:</h5><p>{{mydata | myTest}}</p></div>,
                data : function(){
                    return {
                        myText : ‘‘,
                        mydata : 123
                    }
                },
                filters : {
                    reverse : function(str,lang){
                        return lang + ":" + str.split(‘‘).reverse().join(‘‘);
                    }
                }
            }
            new Vue({
                el : "#app",
                components : {
                    app : App
                },
                template : <app/>
            })
        </script>
    </body>
</html>

 


七、watch监视器:
  基本数据类型简单监视,复杂数据类型(obj/arr)深度监视
  用法:watch : {
      要监视的data数据 : function(newV,oldV){...},
      要监视的obj/arr数据 : {
        deep : true,
        handler : function(newV,oldV){...}
      }
    }

附demo:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>监视watch</title>
        <script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
    </head>
    <body>
        <div id="app">
            
        </div>
        <script type="text/javascript">
            var App = {
                data : function(){
                    return {
                        myText : 111,
                        stus : [{name : jack}]
                    }
                },
                template : <div><input type="text" v-model="myText" />+
                            <button @click="stus[0].name= ‘rose‘ ">深度监视stus[0].name</button></div>,
                watch : {
                    myText : function(newV,oldV){
                        if(newV == I love you){
                            alert(oldV +  too);
                        }
                    },
                    stus : {
                        deep : true,//深度监视
                        handler : function(newV,oldV){
                            console.log(监控成功);
                        }
                    }    
                }
            }
            new Vue({
                el : #app,
                components : {
                    app : App
                },
                template : <app/>
            })
        </script>
    </body>
</html>

 


八、computed群体监视器:
  用法:computed : {
      监视器名称 : function(){//(监视器名称接收此函数return出去的数据)
        return this.xxx;//(this.xxx为本组件中data定义的数据)
      }
    }

附demo:

 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="utf-8" />
 5         <meta name="viewport" content="width=device-width, initial-scale=1">
 6         <title>computed群体监视</title>
 7         <script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
 8     </head>
 9     <body>
10         <div id="app">
11             
12         </div>
13         <script type="text/javascript">
14             var App = {
15                 data : function(){
16                     return {
17                         value01 : 0,
18                         value02 : 0,
19                         rate : 0
20                     }
21                 },
22                 template : <div><p>计算(a+b)*c的值:</p>a:<input type="text" v-model="value01"/>+
23                 b:<input type="text" v-model="value02"/><br/>c:<input type="text" v-model="rate"/>+
24                 <p>{{result}}</p></div>,
25                 computed : {
26                     result : function(){
27                         return (parseFloat(this.value01)+parseFloat(this.value02))*parseFloat(this.rate);
28                     }
29                 }
30             }
31             new Vue({
32                 el : #app,
33                 components : {
34                     app : App
35                 },
36                 template : <app/>
37                 
38             })
39         </script>
40     </body>
41 </html>

 


九、 watch和v-model的区别
  v-model : 只用于对数据的双向绑定及展示。是对单个数据的监视
  watch : 可用于对数据的双向绑定、展示,以及一些复杂的行为。也是对单个数据的监视
  computed : 用于群体监视

十、内置组件slot:

  父组件传递的DOM结构 

附demo:

 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="utf-8" />
 5         <meta name="viewport" content="width=device-width, initial-scale=1">
 6         <title>slot内置组件</title>
 7         <script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
 8         <style type="text/css">
 9             li {
10                 list-style: none;
11                 float: left;
12                 width: 33%;
13                 height: 50px;
14                 background-color: aqua;
15                 border: 1px solid black;
16             }
17         </style>
18     </head>
19     <body>
20         <div id="app"></div>
21         <script type="text/javascript">
22             Vue.component(myLi,{
23                 template : <li><slot></slot></li>
24             })
25             var App = {
26                 template : <div><ul><myLi><h4>111</h4></myLi>+
27                     <myLi><button>222</button><b>222</b></myLi>+
28                     <myLi><input type="text" value="333"/></myLi>+
29                     <myLi>444</myLi><myLi>555</myLi><myLi>666</myLi>+
30                     <myLi>777</myLi><myLi>888</myLi><myLi>999</myLi></ul></div>
31             }
32             new Vue({
33                 el : #app,
34                 components : {
35                     app : App
36                 },
37                 template : <app/>
38             })
39         </script>
40     </body>
41 </html>

 

十一、组件生命周期:
  beforeCreate : 组件创建之前(不可获取到组件中的数据)
  created : 组件创建之后
  beforeMount : vue启动前的DOM
  mounted : vue启动后的DOM
  //beforeUpdate/updated在DOM发生更新时才会被触发
  beforeUpdate : 更新前DOM
  updated : 更新后DOM
  beforeDestory : 本组件销毁之前
  destroyed : 本组件销毁之后
  //对于组件的频繁创建和销毁是不对的,内置组件<keep-alive></keep-alive>包裹后的v-if表示激活或停用该组件
  alivated : 组件被激活
  dealivated : 组件被停用
附demo:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>组件生命周期</title>
        <script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
        <script src="js/组件生命周期.js" type="text/javascript" charset="utf-8"></script>
    </head>
    <body>
        <div id="app">
            
        </div>
    </body>
</html>
 1 window.onload = function(){
 2     var MyTest = {
 3         data : function(){
 4             return {
 5                 myText : ‘111‘
 6             }
 7         },
 8         template : ‘<h3>{{myText}}</h3>‘
 9     }
10     var App = {
11         data : function(){
12             return {
13                 myText : ‘aaa‘,
14                 isExit : true
15             }
16         },
17         components : {
18             ‘myTest‘ : MyTest
19         },
20         template : ‘<div><h5>{{myText}}</h5><button @click="myText+=1 ">更改DOM数据</button>‘+
21             ‘<hr/><myTest v-if="isExit"></myTest><button @click="isExit = !isExit">创建及销毁MyTest子组件</button></div>‘,
22         beforeCreate : function(){
23             //组件创建之前
24             console.log(this.myText);
25         },
26         created : function(){
27             //组件创建之后
28             console.log(this.myText);
29         },
30         beforeMount : function(){
31             //vue启动前的DOM
32             console.log(document.body.innerHTML);
33         },
34         mounted : function(){
35             //vue启动后的DOM
36             console.log(document.body.innerHTML);
37         },
38         //beforeUpdate/updated在DOM发生更新时才会被触发
39         beforeUpdate : function(){
40             //更新前DOM
41             console.log(document.body.innerHTML);
42         },
43         updated : function(){
44             //更新后DOM
45             console.log(document.body.innerHTML);
46         }
47     }
48     new Vue({
49         el : ‘#app‘,
50         components : {
51             ‘app‘ : App
52         },
53         template : ‘<app/>‘
54     })
55 }

 
























































































以上是关于vue3 基础概念 (含与 vue2.6 的对比)的主要内容,如果未能解决你的问题,请参考以下文章

vue2和vue3的基础用法对比第二篇

Vue3 来了,Vue3 开源商城项目重构计划正式启动!

简单对比vue2.x与vue3.x响应式及新功能

如何在连接字符串中包含与号?

vue3对比vue2

vue3与vue2使用的一些对比