Vue.js

发布于 2021-03-16  139 次阅读


一. 介绍

Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。

使用前导入:
<!-- 开发环境版本,包含了有帮助的命令行警告 --> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
或者:
<!-- 生产环境版本,优化了尺寸和速度 --> <script src="https://cdn.jsdelivr.net/npm/vue"></script>

代码:
<body>
    <div id="app">
        {{message}}
    </div>
    <hr/>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        var app = new Vue({
            el: '#app',
            data:{
                message : 'ni hao',
            }
        })
    </script>
   
v-bind:绑定元素属性<br/>
   <div id="app2">
       <span v-bind:title="message">
           鼠标悬停观看效果
       </span>
   </div>
   <hr/>
   <script>
       var app2=new Vue({
           el: '#app2',
           data:{
               message:'页面加载于'+new Date().toLocaleString()
           }
       })
   </script>

v-if:切换一个元素是否显示<br/>
   <div id="app3">
       <p v-if="seen">你看到我了</p>
   </div>
   <hr/>
   <script>
       var app3=new Vue({
           el:'#app3',
           data:{
               seen:true
           }
       })
   </script>

v-for:可以绑定数组的数据来渲染一个项目列表<br/>
   <div id="app4">
       <ol>
           <li v-for="todo in todos">
               {{todo.text}}
           </li>
       </ol>
   </div><hr/>
   <script>
       var app4=new Vue({
           el:'#app4',
           data:{
               todos:[
                   { text: '学习 JavaScript'},
                   { text: '学习 Vue'},
               ]
           }
       })
   </script>

v-on:添加一个事件监听器<br/>
   <div id="app5">
       <p>{{message}}</p>
       <button v-on:click="reverseMessage">反转消息</button>
   </div><hr/>
   <script>
       var app5=new Vue({
           el:'#app5',
           data:{
               message:'Hello, Vue.js!'
           },
           methods:{
               reverseMessage:function(){
                   this.message=this.message.split('').reverse().join('')
                   //spilt(','):将字符串通过','划分为数组
                   //reverse():将数组反序
                   //join(separator):将数组的所有元素放在一个字符串中,separator可选。指定要使用的分隔符。如果省略该参数,则使用逗号作为分隔
               }
           }
       })
   </script>

   v-model : 表单输入和应用状态之间的双向绑定
   <div id="app6">
       <p>{{message}}</p>
       <input v-model="message">
   </div><hr>
   <script>
       var app6=new Vue({
           el:'#app6',
           data:{
               message:'Hello,Vue!'
           }
       });
   </script>

<script>
    //定义一个名为todo-item的组件
    Vue.component('todo-item',{
        props:['todo'],
        template:'<li>{{todo.text}}</li>'
    });
  </script>
   定义一个组件
   <div id="app7">
    <ol>
        <todo-item
        v-for="item in groceryList"
        v-bind:todo="item"
        v-bind:key="item.id"
        ></todo-item>
    </ol>
   </div>
   <script>
    var app7 = new Vue({
        el:'#app7',
        data:{
            groceryList:[
                {id:0,text:'蔬菜'},
                {id:1,text:'奶酪'},
                {id:2,text:'othor'}
            ]
        }
    })
</script>
</body>

代码演示在这里

二. 实例

创建vue都是这样开始的:
var vm = new Vue({
// 选项
})
当一个 Vue 实例被创建时,它将 data 对象中的所有的 property(属性) 加入到 Vue 的响应式系统中。当这些 property 的值发生改变时,视图将会产生“响应”,即匹配更新为新的值。
js创建的键值对关系 var data={a:1,b:2} 与vm.a 值是一样的(为1)改变一个另一个也是同样的改变 vm.a=2,则data.a=2;但如果先在js定义的键值对关系中没有的属性,而后又在vue中定义是不会出现的,如 var data={a:1} vm.b=2,则vm.b=2,而data.b = underfined;因此如果你知道你会在晚些时候需要一个 property,但是一开始它为空或不存在,那么你仅需要设置一些初始值。比如:
data: {
newTodoText: '',
visitCount: 0,
hideCompletedTodos: false,
todos: [],
error: null }
这里唯一的例外是使用 Object.freeze(),这会阻止修改现有的 property,也意味着响应系统无法再追踪变化。
除了数据 property,Vue 实例还有一些有用的实例 property 与方法。它们都有前缀 $,以便与用户定义的 property 区分开来。vm.$data===data; vm.$el===document.getElementbyId(''); vm.$watch('a', function (newValue, oldValue) { // 这个回调将在 `vm.a` 改变后调用 })

每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等。同时在这个过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会。created钩子在创建的时候调用
new Vue({
el:'#app5',
data:{
a:1
},
created:function (){
console.log("创建时的钩子:"+this.a)
}
})
输出:创建时的钩子:1。
也有一些其它的钩子,在实例生命周期的不同阶段被调用,如 mountedupdated 和 destroyed。生命周期钩子的 this 上下文指向调用它的 Vue 实例。
不要在选项 property 或回调上使用箭头函数,比如 created: () => console.log(this.a) 或 vm.$watch('a', newValue => this.myMethod())。因为箭头函数并没有 thisthis 会作为变量一直向上级词法作用域查找,直至找到为止,经常导致 Uncaught TypeError: Cannot read property of undefined 或 Uncaught TypeError: this.myMethod is not a function 之类的错误。

生命周期示意图:

代码:

<body>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        var data={a:1,b:2};
        console.log("data.a:"+data.a);
        var vm = new Vue({
            data:data
        })
        console.log("vm.a:"+vm.a);
        console.log("data.a等于vm.a吗?"+(vm.a==data.a));
        data.a=2;
        console.log("vm.a:"+vm.a);
        console.log("data.a改变过后data.a还等于vm.a吗?"+(vm.a==data.a));
</script>

这里的foo不会更新
<div id="app">
    <p>{{foo}}</p>
    <button v-on:click="foo='baz'">Change it</button>
</div>
<script>
        //使用freeze(obj)将会停止属性的改变
        var obj={foo:'bar'};
        Object.freeze(obj);//这样就会报错
        new Vue({
            el:'#app',
            data:obj
        })
    </script>

<div id="example">打开控制面板</div>
<script>
    var data={a:1};
    var vm = new Vue({
        el:'#example',
        data:data
    })
    vm.$data.a=2;//测试vm.$data能改变data。a的值吗?
    console.log(data.a);
    console.log(vm.$data===data);
    console.log(vm.$el===document.getElementById("example"));

    //$watch
    vm.$watch('a',function (newValue,oldValue){
        //这个回调函数将在vm.a改变后调用
        alert("newValue="+newValue+",oldValue="+oldValue);
    })
    vm.a=2;
    vm.b=2;
    console.log("vm.b="+vm.b);
    console.log("data.b="+data.b);
</script>

//生命周期钩子函数
<div id="app5">{{a}}</div>
<script>
    new Vue({
        el:'#app5',
        data:{
            a:1
        },
        created:function (){
            console.log("创建时的钩子:"+this.a)
        }
    })
</script>
</body>

代码演示在这里

三. 模板语法

  1. v-once 指令,能执行一次性地插值,当数据改变时,插值处的内容不会更新。但请留心这会影响到该节点上的其它数据绑定.
    <span v-once>这个将不会改变: {{ msg }}</span>
    v-once是让一个节点不能改变值,freeze(obj)将会停止属性的改变

2. 双大括号会将数据解释为普通文本,而非 HTML 代码。为了输出真正的 HTML,你需要使用 v-html 指令
<p>Using mustaches: {{ rawHtml }}</p>
<p>Using v-html directive: <span v-html="rawHtml"></span></p>

3. Mustache 语法 (普通的用{{msg}}的语法) 不能作用在 HTML attribute 上,遇到这种情况应该使用 v-bind 指令
<div v-bind:id="dynamicId"></div>

4. 在{{msg}}中不仅直接使用property也可以用JavaScript表达式,如:
{{ number + 1 }}
{{ ok ? 'YES' : 'NO' }}
{{ message.split('').reverse().join('') }}
<div v-bind:id="'list-' + id"></div>
这些表达式会在所属 Vue 实例的数据作用域下作为 JavaScript 被解析。有个限制就是,每个绑定都只能包含单个表达式,所以下面的例子都不会生效。
<!-- 这是语句,不是表达式 --> {{ var a = 1 }}
<!-- 流控制也不会生效,请使用三元表达式 -->
{{ if (ok) { return message } }}

5.

一些指令能够接收一个“参数”,在指令名称之后以冒号表示。例如,v-bind 指令可以用于响应式地更新 HTML attribute:

<a v-bind:href="url">...</a>

在这里 href 是参数,告知 v-bind 指令将该元素的 href attribute 与表达式 url 的值绑定。

另一个例子是 v-on 指令,它用于监听 DOM 事件:

<a v-on:click="doSomething">...</a>

并且可以缩写
v-bind 的缩写:
<!-- 完整语法 -->
<a v-bind:href="url">...</a>
<!-- 缩写 --> <a :href="url">...</a>
<!-- 动态参数的缩写 (2.6.0+) -->
<a :[key]="url"> ... </a>

v-on 的缩写
<!-- 完整语法 -->
<a v-on:click="doSomething">...</a>
<!-- 缩写 --> <a @click="doSomething">...</a>
<!-- 动态参数的缩写 (2.6.0+) -->
<a @[event]="doSomething"> ... </a>

从 2.6.0 开始,可以用方括号括起来的 JavaScript 表达式作为一个指令的参数:

<!--
注意,参数表达式的写法存在一些约束,如之后的“对动态参数表达式的约束”章节所述。
-->
<a v-bind:[attributeName]="url"> ... </a>

这里的 attributeName 会被作为一个 JavaScript 表达式进行动态求值,求得的值将会作为最终的参数来使用。例如,如果你的 Vue 实例有一个 data property attributeName,其值为 "href",那么这个绑定将等价于 v-bind:href。但要注意在[]不能有空格和引号,因为他们是不能被识别的,并且会被强制转换为小写.


一沙一世界,一花一天堂。君掌盛无边,刹那成永恒。