一、写一个简单的Vue实例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vue入门e</title>
<script src="js/vue.js"></script><!-- 放在head头,避免页面出现抖屏的问题-->
</head>
<body>
<div id="root">{{msg}}</div>
<script>
new Vue({
el: "#root", //接管#root元素,与此DOM节点绑定
data: {
msg: "Hello world!"
}
});
</script>
</body>
</html>
二、挂载点、模板、实例
挂载点:上面的例子中,如下元素为vue实例的挂载点
<div id="root"></div>
模板:在挂载点内部的{{}}内容,为模板内容
<div id="root">{{msg}}</div>
也可以这样写:
<div id="root"></div>
<script>
new Vue({
el: "#root",
template: "<h1>{{msg}}</h1>",
data: {
msg: "Hello world!"
}
});
</script>
三、Vue实例中的数据、事件与方法
数据:
<div id="root">
<h1>{{num}}</h1><!--这叫插值表达式-->
<h2 v-text="num"></h2>
<h3 v-html="num"></h3>
</div>
<script>
new Vue({
el: "#root",
data: {
msg: "Hello world!",
num: "<i>123</i>"
}
});
</script>
事件:实现效果,点击hello后变成world
<body>
<div id="root">
<div v-on:click="handleClick">{{content}}</div>
</div>
<script>
new Vue({
el: "#root",
data: {
content:"hello"
},
methods:{
handleClick: function () {
//数据变化,vue会自动更新DOM
this.content = "world"
}
}
});
</script>
</body>
还可以简写为:
<div @click="handleClick">{{content}}</div>
四、Vue中的属性绑定和双向数据绑定
属性绑定:
<body>
<div id="root">
<div v-bind:title="title">hello world</div>
</div>
<script>
new Vue({
el: "#root",
data: {
title: "this is hello world"
}
});
</script>
</body>
还可以简写为:
<div :title="title">hello world</div>
双向数据绑定:
单向绑定:数据决定页面的显示,但是页面无法决定数据
<body>
<div id="root">
这是单向绑定:<input :value="content"><br>
这是双向向绑定:<input v-model="content">
<div>{{content}}</div>
</div>
<script>
new Vue({
el: "#root",
data: {
content: "this is content"
}
});
</script>
</body>
五、Vue中的计算属性和侦听器
<body>
<div id="root">
姓:<input v-model="firstName">
名:<input v-model="lastName">
<div>{{firstName}}{{lastName}}</div>
</div>
<script>
new Vue({
el: "#root",
data: {
firstName: "",
lastName: ""
}
});
</script>
</body>
计算属性:
<body>
<div id="root">
姓:<input v-model="firstName">
名:<input v-model="lastName">
<div>{{fullName}}</div>
</div>
<script>
new Vue({
el: "#root",
data: {
firstName: "",
lastName: ""
},
computed:{
fullName: function () {
//只有数据发送变化时才会重新计算,如果数据未变化,会利用缓存
return this.firstName+' '+this.lastName;
}
}
});
</script>
</body>
侦听器:
场景:对姓名做任意变更,数字加1
<body>
<div id="root">
姓:<input v-model="firstName">
名:<input v-model="lastName">
<div>{{fullName}}</div>
<div>{{count}}</div>
</div>
<script>
new Vue({
el: "#root",
data: {
firstName: "",
lastName: "",
count: 0
},
computed: {
fullName: function () {
//只有数据发送变化时才会重新计算
return this.firstName+' '+this.lastName;
}
},
//侦听器
watch: {
fullName: function () {
this.count++;
}
}
});
</script>
</body>
六、v-if, v-show与v-for指令
v-if:修改DOM结构,如果里面的值是false,会直接从DOM中删除该节点
<body>
<div id="root">
<div v-if="show">hello world</div>
<button @click="handleClick">toggle</button>
</div>
<script>
new Vue({
el: "#root",
data: {
show: true
},
methods: {
handleClick: function () {
this.show=!this.show;
}
}
});
</script>
</body>
v-show:使用display控制,因此使用v-show性能更好
<body>
<div id="root">
<div v-show="show">hello world</div>
<button @click="handleClick">toggle</button>
</div>
<script>
new Vue({
el: "#root",
data: {
show: true
},
methods: {
handleClick: function () {
this.show=!this.show;
}
}
});
</script>
</body>
v-for:
<body>
<div id="root">
<ul>
<li v-for="item of list">{{item}}</li>
<li v-for="item of list" :key="item">{{item}}</li><!--key属性,要求每一项的数值都不能相同,会提升每一项渲染的性能-->
<li v-for="(item , index) of list" :key="index">{{item}}</li><!--可以修改为下标-->
</ul>
</div>
<script>
new Vue({
el: "#root",
data: {
list: [1,2,3]
}
});
</script>
</body>
七、一个最简单的todolist功能开发
<body>
<div id="root">
<div>
<input v-model="inputValue">
<button @click="handleClick">提交</button>
</div>
<ul>
<li v-for="(item, index) of list" :key="index">{{item}}</li>
</ul>
</div>
<script>
new Vue({
el: "#root",
data: {
inputValue: "",
list: []
},
methods: {
handleClick: function () {
this.list.push(this.inputValue);
//清空input框
this.inputValue='';//双向绑定
}
}
});
</script>
</body>
八、todolist组件拆分
组件:简单理解,页面上的某一部分
假如li标签里的内容很多,将它拆分为一个组件。
如何创建组件?
<body>
<div id="root">
<div>
<input v-model="inputValue">
<button @click="handleClick">提交</button>
</div>
<ul>
<todo-item
v-for="(item, index) of list"
:key="index"
:content="item"
></todo-item> <!--content属性用来给组件传参-->
</ul>
</div>
<script>
//全局组件
Vue.component('todo-item',{
props: ['content'],
template: '<li>TODO: {{content}}</li>'
});
new Vue({
el: "#root",
data: {
inputValue: "",
list: []
},
methods: {
handleClick: function () {
this.list.push(this.inputValue);
//清空input框
this.inputValue='';//双向绑定
}
}
});
</script>
</body>
//局部组件
var TodoItem={
template: "<li>item</li>"
};
new Vue({
el: "#root",
components: {
'todo-item': TodoItem
}
});
每一个Vue组件,其实也是一个Vue实例。
Vue.component('todo-item',{
props: ['content'],
template: '<li @click="handleClick">TODO: {{content}}</li>',
methods: {
handleClick: function () {
alert('clicked');
}
}
});
九、实现删除功能(组件间的交互)
<body>
<div id="root">
<div>
<input v-model="inputValue">
<button @click="handleClick">提交</button>
</div>
<ul>
<todo-item
v-for="(item, index) of list"
:key="index"
:content="item"
:index="index"
@delete="handleDelete"
></todo-item>
</ul>
</div>
<script>
Vue.component('todo-item',{
props: ['content','index'],//从父组件接收参数
template: '<li @click="handleClick">{{content}}</li>',
methods: {
handleClick: function () {
//组件向外触发delete事件,同时传入index值
this.$emit('delete',this.index);
}
}
});
new Vue({
el: "#root",
data: {
inputValue: "",
list: []
},
methods: {
handleClick: function () {
this.list.push(this.inputValue);
//清空input框
this.inputValue='';//双向绑定
},
handleDelete: function (index) {
this.list.splice(index,1);
}
}
});
</script>
</body>
十、 Vue-cli的简介与使用
vue-cli这个构建工具大大降低了webpack的使用难度,支持热更新,有webpack-dev-server的支持,相当于启动了一个请求服务器,给你搭建了一个测试环境,只关注开发即可。
全局安装vue-cli:
npm install -g vue-cli
创建一个基于webpack模块的新项目:
vue init webpack my-project
进入项目目录,启动项目:
npm run dev
项目目录结构:
使用vue-cli开发上面的TodoList:
src/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 TodoList from './TodoList'
Vue.config.productionTip = false;
/* eslint-disable no-new */
new Vue({
el: '#app',
components: { TodoList },
template: '<TodoList/>'
});
src/TodoList.vue:
<template>
<div><!--template下必须有一个大标签包裹所有的标签-->
<div>
<input v-model="inputValue"/>
<button @click="handleClick">提交</button>
</div>
<ul>
<todo-item
v-for="(item,index) of list"
:key="index"
:content="item"
:index="index"
@delete="handleDelete"
></todo-item>
</ul>
</div>
</template>
<script>
import TodoItem from './components/TodoItem';
export default {
components: {
'todo-item': TodoItem
},
data() {
return {
inputValue: '',
list: []
}
},
methods: {
handleClick(){
this.list.push(this.inputValue);
this.inputValue='';
},
handleDelete(index){
this.list.splice(index,1);
}
}
}
</script>
<style>
</style>
src/components/TodoItem:
<template>
<li @click="handleClick">{{content}}</li>
</template>
<script>
export default {
props: ['content','index'],
methods: {
handleClick(){
this.$emit('delete',this.index);
}
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>
十一、全局样式与局部样式
<style scoped>
.item{
color: green;
}
</style>
scoped的作用是只有当前组件里的模板才会对里面的样式生效,即一个组件的样式只对当前组件有效。