Vue.js是什么?
Vue.js(读音 /vjuː/,类似于 view 的读音)是一套构建用户界面(user interface)的渐进式框架。与其他重量级框架不同的是,Vue 从根本上采用最小成本、渐进增量(incrementally adoptable)的设计。Vue 的核心库只专注于视图层,并且很容易与其他第三方库或现有项目集成。另一方面,当与单文件组件和 Vue 生态系统支持的库结合使用时,Vue 也完全能够为复杂的单页应用程序提供有力驱动。
起步
在本地创建一个 index.html
文件,然后通过如下方式引入 Vue:
<!-- 开发版本,包含有用的控制台警告 --> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
或
<!-- 生成版本,对于体积和速度进行优化 --> <script src="https://cdn.jsdelivr.net/npm/vue"></script>
声明式渲染
Vue.js 的核心是,可以采用简洁的模板语法来声明式的将数据渲染为 DOM:
<body> <div id="app"> {{message}} </div> <script src="https://cdn.jsdelivr.net/npm/vue"></script> <script> var app = new Vue({ el: '#app', data: { message: 'Hello Vue!' } }) </script> </body>
所有的数据和 DOM 都是响应式的。打开你的浏览器的 JavaScript 控制台(现在,就在当前页面打开),然后设置 app.message
的值,你将看到上面的示例所渲染的 DOM 元素会相应地更新。
除了文本插值(text interpolation),我们还可以采用这样的方式绑定 DOM 元素属性:
<body> <div id="app-2"> <span v-bind:title="message"> 鼠标悬停此处几秒,可以看到此处动态绑定的title! </span> </div> <script src="https://cdn.jsdelivr.net/npm/vue"></script> <script> var app2 = new Vue({ el: '#app-2', data: { message: '页面加载于 ' + new Date().toLocaleString() } }) </script> </body>
你看到的 v-bind
属性被称为指令。指令带有前缀 v-
,表示是由 Vue 提供的专用属性。可能你已经猜到了,它们会在渲染的 DOM 上产生专门的响应式行为。简而言之,这里该指令的作用就是:“将此元素的 title
属性与 Vue 实例的 message
属性保持关联更新”。
如果你再次打开浏览器的 JavaScript 控制台,并输入 app2.message = '一些新的 message'
,就会再次看到,绑定了 title
属性的 HTML 已经进行了更新。
条件与循环
控制切换一个元素的显示也很简单:
<body> <div id="app-3"> <span v-if="seen">现在你可以看到我</span> </div> <script src="https://cdn.jsdelivr.net/npm/vue"></script> <script> var app3 = new Vue({ el: '#app-3', data: { seen: true } }) </script> </body>
继续在控制台输入 app3.seen = false
,你应该会看到 span 消失。
v-for
指令,可以使用数组中的数据来展示一个项目列表:
<body> <div id="app-4"> <ol> <li v-for="todo in todos"> {{todo.text}} </li> </ol> </div> <script src="https://cdn.jsdelivr.net/npm/vue"></script> <script> var app4 = new Vue({ el: '#app-4', data: { todos: [ {text: '学习JavaScript'}, {text: '学习Vue'}, {text: '创建激动人心的代码'} ] } }) </script> </body>
在控制台,输入app4.todos.push({ text: '新的 item' })
,你会看到列表中追加了一个新的 item。
处理用户输入
使用 v-on
指令 来增加事件监听器,触发事件后会调用 Vue 实例中 methods 下定义的方法:
<body> <div id="app-5"> <p>{{message}}</p> <button v-on:click="reverseMessage">翻转message</button> </div> <script src="https://cdn.jsdelivr.net/npm/vue"></script> <script> var app5 = new Vue({ el: '#app-5', data: { message: 'Hello Vue.js!' }, methods: { reverseMessage: function () { this.message = this.message.split('').reverse().join('') } } }) </script> </body>
点击按钮
Vue 还提供了 v-model
指令,使得表单输入和应用程序状态之间的双向绑定变得轻而易举:
<body> <div id="app-6"> <p>{{message}}</p> <input v-model="message"> </div> <script src="https://cdn.jsdelivr.net/npm/vue"></script> <script> var app6 = new Vue({ el: '#app-6', data: { message: 'Hello Vue!' } }) </script> </body>
修改输入的内容,输入框上面也会跟着同步
由组件组合而成的应用程序
组件系统是 Vue 的另一个重要概念,因为它是一种抽象,可以让我们使用小型、自成体系和通常可复用的组件,把这些组合来构建大型应用程序。仔细想想,几乎任意类型的应用程序界面,都可以抽象为一个组件树:
在 Vue 中,一个组件本质上是一个被预先定义选项的 Vue 实例,在 Vue 中注册组件很简单:
// 定义一个被命名为todo-item的新组件
Vue.component('todo-item',{
template: '<li>这是一个todo项</li>'
})
现在你可以在另一个组件模板中组合使用它:
<ol> <!--创建一个todo-item组件的实例--> <todo-item></todo-item> </ol>
但是这样会将每个 todo 项都为渲染相同的文本,这看起来并不炫酷。我们应该要将数据从父作用域传到子组件。让我们来修改下组件的定义,使它可以接受一个 prop:
Vue.component('todo-item',{ // todo-item组件现在接受一个“prop”, // 类似于一个自定义属性。 // 此prop名为todo。 props: ['todo'], template: '<li>{{todo.text}}</li>' })
现在,我们可以使用 v-bind
指令将 todo 传入每个重复的组件中:
<body> <div id="app-7"> <ol> <!--现在我们为每个todo-item提供了todo对象, 其中它的内容是动态的。 我们需要为每个组件提供一个“key”, 这将在之后详细解释。--> <todo-item v-for="item in groceryList" v-bind: todo="item" v-bind: key="item.id"> </todo-item> </ol> </div> <script src="https://cdn.jsdelivr.net/npm/vue"></script> <script> Vue.component('todo-item', { props: ['todo'], template: '<li>{{ todo.text }}</li>' }); var app7 = new Vue({ el: '#app-7', data: { groceryList: [ {id: 0, text: '蔬菜'}, {id: 1, text: '奶酪'}, {id: 2, text: '其他人类事物'} ] } }) </script> </body>