1、vue介绍
1.1、入门案例
1.1.1安装vue
官网文档提供了 3 中安装方式:
- 直接 script 引入本地 vue 文件。需要通过官网下载 vue 文件。
- 通过 script 引入 CDN 代理。需要联网,生产环境可以使用这种方式。
- 通过 npm 安装。这种方式也是官网推荐的方式,需要 nodejs 环境。
# 最新稳定版
$ npm install vue
1.1.2、创建示例项目
- 新建文件夹 hello-vue,并使用 vscode 打开
- 使用 vscode 控制台,npm install -y,项目会生成 package-lock.json 文件,类似于 maven 项目的 pom.xml 文件。
- 使用 npm install vue,给项目安装 vue;项目下会多 node_modules 目录,并且在下面有 一个 vue 目录。
1.1.3、事件处理
v-xx:指令
1、创建vue实例,关联页面的模板,将自己的数据(data)渲染到关联的模板,响应式的
2、指令来简化对dom的一些操作。
3、声明方法来做更复杂的操作。methods里面可以封装方法。
v-on是按钮的单击事件:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./node_modules/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<input type="text" v-model="num">
<button v-on:click="num++">
点赞
</button>
<!-- 完整语法 -->
<button v-on:click="minus">取消</button>
<!-- 缩写 -->
<button @click="minus">取消</button>
<!-- 动态参数的缩写 -->
<button @[event]="minus">取消</button>
<h5>
{{name}},非常帅!!! 有{{num}}个人为他点赞
</h5>
</div>
</body>
<script>
let vm = new Vue({
el: "#app",
data: {
name: "张三",
num: 5,
event: "click"
},
methods: {
minus: function(){
this.num--
}
},
})
</script>
</html>
在VUE中el,data和vue的作用:
- el:用来绑定数据(是 element 的缩写,通过 id 选中要渲染的页面元素,本例中是一个 div);
- data:数据,数据是一个对象,里面有很多属性,都可以渲染到视图中;
- methods:用来封装方法,并且能够封装多个方法,如上面封装了minus方法。
1.2差值表达式
1.2.1花括号
格式:{{表达式}}
说明:
- 该表达式支持 JS 语法,可以调用 js 内置函数(必须有返回值)
- 表达式必须有返回结果。例如 1 + 1,没有结果的表达式不允许使用,如:let a = 1 + 1;
- 可以直接获取 Vue 实例中定义的数据或函数
1.2.2差值闪烁
使用{{}}方式在网速较慢时会出现问题。在数据未加载完成时,页面会显示出原始的{{}}
,
加载完毕后才显示正确数据,我们称为插值闪烁
1.2.3v-text 和 v-html
可以使用 v-text 和 v-html 指令来替代{{}}
说明:
-
v-text:将数据输出到元素内部,如果输出的数据有 HTML 代码,会作为普通文本输出
-
v-html:将数据输出到元素内部,如果输出的数据有 HTML 代码,会被渲染
**“v-html”**不会对于HTML标签进行转义,而是直接在浏览器上显示data所设置的内容;而“ v-text”会对html标签进行转义
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./node_modules/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<span v-text="showStr"></span>
<span v-html="showStr"></span>
</div>
</body>
<script>
let vm = new Vue({
el: "#app",
data: {
showStr: "<h1>html片段</h1>"
},
})
</script>
</html>
并且不会出现插值闪烁,当没有数据时,会显示空白或者默认数据。
2、指令
2.1、v-bind :单向绑定
html 属性不能使用双大括号形式绑定,我们使用 v-bind 指令给 HTML 标签属性绑定值;
而且在将 v-bind
用于 class
和 style
时,Vue.js 做了专门的增强。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<!-- 给html标签的属性绑定 -->
<div id="app">
<!-- 完整语法 -->
<a v-bind:href="link">gogogo</a>
<!-- 缩写 -->
<a :href="link">gogogo</a>
<!-- 动态参数的缩写 -->
<a :[key]="link">gogogo</a>
<!-- class,style {class名:加上?}-->
<span v-bind:class="{active:isActive,'text-danger':hasError}"
:style="{color: color1,fontSize: size}">你好</span>
</div>
<script src="../node_modules/vue/dist/vue.js"></script>
<script>
let vm = new Vue({
el:"#app",
data:{
link: "http://www.baidu.com",
isActive:true,
hasError:true,
color1:'red',
size:'36px',
key:'href'
}
})
</script>
</body>
</html>
上面所完成的任务就是给a标签绑定一个超链接。并且当“isActive”和“hasError”都是true的时候,将属性动态的绑定到,则绑定该“active”和 "text-danger"class。这样可以动态的调整属性的存在。
而且如果想要实现修改vm的"color1"和“size”, span元素的style也能够随之变化,则可以写作v-bind:style,也可以省略v-bind。
2.2、v-model双向绑定
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<!-- 表单项,自定义组件 -->
<div id="app">
精通的语言:
<input type="checkbox" v-model="language" value="Java"> java<br/>
<input type="checkbox" v-model="language" value="PHP"> PHP<br/>
<input type="checkbox" v-model="language" value="Python"> Python<br/>
选中了 {{language.join(",")}}
</div>
<script src="../node_modules/vue/dist/vue.js"></script>
<script>
let vm = new Vue({
el:"#app",
data:{
language: []
}
})
</script>
</body>
</html>
上面完成的功能就是通过“v-model”为输入框绑定多个值,能够实现选中的值,在data的language也在不断的发生着变化。通过“v-model”实现了页面发生了变化,则数据也发生变化,数据发生变化,则页面也发生变化,这样就实现了双向绑定。
双向绑定:
效果:我们修改表单项,num 会发生变化。我们修改 num,表单项也会发生变化。为了实
时观察到这个变化,我们将 num 输出到页面。
我们不需要关注他们为什么会建立起来关联,以及页面如何变化,我们只需要做好数据和
视图的关联即可(MVVM)
2.3、v-on为按钮绑定事件
参考1.1.3事件处理的demo,上面是为两个按钮绑定了单击事件,其中一个对于num进行自增,另外一个自减。
v-on:click也可以写作@click
2.3.1、事件修饰符
下面的这两个嵌套div中,如果点击了内层的div,则外层的div也会被触发;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./node_modules/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<!-- 事件修饰符 -->
<div style="border: 1px solid red;padding: 20px;" v-on:click="hello">
大div
<div style="border: 1px solid blue;padding: 20px;" @click="hello">
小div <br />
<!-- prevent 阻止事件的默认行为,例如这里阻止a标签跳转 -->
<!-- <a href="http://www.baidu.com" @click.prevent="hello">去百度</a> -->
<!-- stop 阻止事件冒泡,例如这里只会触发本身的点击事件弹出一个"lalala"然后跳转到baidu -->
<!-- <a href="http://www.baidu.com" @click.stop="hello">去百度</a> -->
<!-- 可以同时使用prevent和stop,同时阻止事件的默认行为和事件冒泡 -->
<a href="http://www.baidu.com" @click.prevent.stop="hello">去百度</a>
</div>
</div>
<!-- 非ctrl,alt,shift这三个组合键修饰符,keyup后面跟多个,按下其中一个即会触发 -->
<input type="text" v-on:keyup.65.66="keyA">
<input type="text" v-on:keyup.enter="keyA">
<input type="text" v-on:keyup.enter.65="keyA">
<!-- ctrl,alt,shift这三个组合键修饰符,keyup后面跟多个,要按下组合键才会触发 -->
<input type="text" v-on:keyup.alt.65="keyA">
</div>
<script>
let vm = new Vue({
el: "#app",
methods: {
hello(){
alert("lalala")
},
keyA(){
alert("按下了A")
}
},
})
</script>
</body>
</html>
关于事件修饰符:
在事件处理程序中调用 event.preventDefault()
或 event.stopPropagation()
是非常常见的 需求。尽管我们可以在方法中轻松实现这点,但更好的方式是:方法只有纯粹的数据逻辑, 而不是去处理 DOM 事件细节。
为了解决这个问题,Vue.js 为 v-on
提供了事件修饰符。修饰符是由点开头的指令后缀来
表示的。
.stop
:阻止事件冒泡到父元素.prevent
:阻止默认事件发生.capture
:使用事件捕获模式.self
:只有元素自身触发事件才执行。(冒泡或捕获的都不执行).once
:只执行一次
按键修饰符:
Vue 允许为 v-on
在监听键盘事件时添加按键修饰符,记住所有的 keyCode
比较困难,所以 Vue 为最常用的按键提供了别名:
.enter
.tab
.delete
(捕获“删除”和“退格”键).esc
.space
.up
.down
.left
.right
可以用如下修饰符来实现仅在按下相应按键时才触发鼠标或键盘事件的监听器。.ctrl
.alt
.shift
2.4、v-for遍历循环
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
<ul>
<li v-for="(user,index) in users" :key="user.name" v-if="user.gender == '女'">
<!-- 1、显示user信息:v-for="item in items" -->
当前索引:{{index}} ==> {{user.name}} ==> {{user.gender}} ==>{{user.age}} <br>
<!-- 2、获取数组下标:v-for="(item,index) in items" -->
<!-- 3、遍历对象:
v-for="value in object"
v-for="(value,key) in object"
v-for="(value,key,index) in object"
-->
对象信息:
<span v-for="(v,k,i) in user">{{k}}=={{v}}=={{i}};</span>
<!-- 4、遍历的时候都加上:key来区分不同数据,提高vue渲染效率 -->
</li>
</ul>
<ul>
<li v-for="(num,index) in nums" :key="index"></li>
</ul>
</div>
<script src="../node_modules/vue/dist/vue.js"></script>
<script>
let app = new Vue({
el: "#app",
data: {
users: [{ name: '柳岩', gender: '女', age: 21 },
{ name: '张三', gender: '男', age: 18 },
{ name: '范冰冰', gender: '女', age: 24 },
{ name: '刘亦菲', gender: '女', age: 18 },
{ name: '古力娜扎', gender: '女', age: 25 }],
nums: [1,2,3,4,4]
},
})
</script>
</body>
</html>
遍历的时候都加上:key来区分不同数据,提高vue渲染效率
最佳实践:
如果 items 是数组,可以使用 index 作为每个元素的唯一标识
如果 items 是对象数组,可以使用 item.id 作为每个元素的唯一标识
2.5、v-if和v-show
v-if,当得到结果为 true 时,所在的元素才会被渲染。
v-show,当得到结果为 true 时,所在的元素才会被显示。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<button v-on:click="show = !show">点我呀</button> <br>
<h1 v-if="show"> 看到我啦?! </h1>
<h1 v-show="show"> 看到我啦?!show </h1>
</div>
<script src="../node_modules/vue/dist/vue.js"></script>
<script type="text/javascript">
let app = new Vue({
el: "#app",
data: {
show: true
}
})
</script>
</body>
</html>
当 v-if 和 v-for 出现在一起时,v-for 优先级更高。也就是说,会先遍历,再判断条件,样例代码参考1.6。
3、计算属性和侦听器
3.1、计算属性
模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的。在模板中放入太多的逻辑会让模板过重且难以维护。
任何包含响应式数据的复杂逻辑,都应该使用计算属性
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<ul>
<li>西游记:价格{{xyjPrice}},数量: <input type="number" v-model="xyjNum"></li>
<li>水浒传:价格{{shzPrice}},数量: <input type="number" v-model="shzNum"></li>
<li>总价:{{totalPrice}}</li>
</ul>
</div>
<script src="../node_modules/vue/dist/vue.js"></script>
<script type="text/javascript">
let app = new Vue({
el: "#app",
data: {
xyjPrice: 56.73,
shzPrice: 47.98,
xyjNum: 1,
shzNum: 1
},
computed: {
totalPrice() {
return this.xyjPrice * this.xyjNum + this.shzPrice * this.shzNum;
}
},
})
</script>
</body>
</html>
Vue 知道 vm.totalPrice依赖于 this.xyjPrice * this.xyjNum + this.shzPrice * this.shzNum,因此当这几个变量 发生改变时,所有依赖 vm.publishedBookMessage 的绑定也会更新。
3.1.1、计算属性缓存 vs 方法
我们可以将同样的函数定义为一个方法,而不是一个计算属性。从最终结果来说,这两种实现方式确实是完全相同的。然而,不同的是计算属性将基于它们的响应依赖关系缓存。计算属性只会在相关响应式依赖发生改变时重新求值。这就意味着只要 this.xyjPrice * this.xyjNum + this.shzPrice * this.shzNum中的变量还没有发生改变,多次访问 totalPrice
时计算属性会立即返回之前的计算结果,而不必再次执行函数。
我们为什么需要缓存?假设我们有一个性能开销比较大的计算属性 list
,它需要遍历一个巨大的数组并做大量的计算。然后我们可能有其他的计算属性依赖于 list
。如果没有缓存,我们将不可避免的多次执行 list
的 getter!如果你不希望有缓存,请用 method
来替代。
3.2侦听器
虽然计算属性在大多数情况下更合适,但有时也需要一个自定义的侦听器。这就是为什么 Vue 通过 watch
选项提供了一个更通用的方法来响应数据的变化。当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<ul>
<li>西游记:价格{{xyjPrice}},数量: <input type="number" v-model="xyjNum"></li>
<li>水浒传:价格{{shzPrice}},数量: <input type="number" v-model="shzNum"></li>
<li>总价:{{totalPrice}}</li>
{{msg}}
</ul>
</div>
<script src="../node_modules/vue/dist/vue.js"></script>
<script type="text/javascript">
let app = new Vue({
el: "#app",
data: {
xyjPrice: 56.73,
shzPrice: 47.98,
xyjNum: 1,
shzNum: 1
},
computed: {
totalPrice() {
return this.xyjPrice * this.xyjNum + this.shzPrice * this.shzNum;
}
},
watch: {
xyjNum(newVal, oldVal) {
if (newVal >= 3) {
this.msg = "西游记没有更多库存了"; this.xyjNum = 3;
} else {
this.msg = "";
}
}
}
})
</script>
</body>
</html>
在这个示例中,使用 watch
选项允许我们执行异步操作 (访问一个 API),并设置一个执行该操作的条件。这些都是计算属性无法做到的。
除了 watch 选项之外,你还可以使用命令式的 vm.$watch API
3.3计算属性vs侦听器
Vue 提供了一种更通用的方式来观察和响应当前活动的实例上的数据变动:侦听属性。当你有一些数据需要随着其它数据变动而变动时,watch
很容易被滥用——特别是如果你之前使用过 AngularJS。然而,通常更好的做法是使用计算属性而不是命令式的 watch
回调。细想一下这个例子:
<div id="demo">{{ fullName }}</div>
const vm = Vue.createApp({
data() {
return {
firstName: 'Foo',
lastName: 'Bar',
fullName: 'Foo Bar'
}
},
watch: {
firstName(val) {
this.fullName = val + ' ' + this.lastName
},
lastName(val) {
this.fullName = this.firstName + ' ' + val
}
}
}).mount('#demo')
上面代码是命令式且重复的。将它与计算属性的版本进行比较:
const vm = Vue.createApp({
data() {
return {
firstName: 'Foo',
lastName: 'Bar'
}
},
computed: {
fullName() {
return this.firstName + ' ' + this.lastName
}
}
}).mount('#demo')
好很多了,不是吗?
4、过滤器
由于3.x版本已移除过滤器,虽然学习和工作中用的是2.x,但是为避免使用将要过时的写法,建议用计算属性或方法代替过滤器,而不是使用过滤器。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<table>
<tr v-for="user in userList">
<td>{{user.id}}</td>
<td>{{user.name}}</td>
<!-- 使用方法代替过滤器 -->
<td>{{genderFilter(user.gender)}}</td>
</tr>
</table>
</div>
</body>
<script src="../node_modules/vue/dist/vue.js"></script>
<script>
let app = new Vue({
el: "#app",
data: {
userList: [{
id: 1,
name: 'jacky',
gender: 1
},
{
id: 2,
name: 'peter',
gender: 0
}]
},
methods: {
genderFilter(gender) {
return gender === 1 ? '男~' : '女~'
}
},
});
</script>
</html>
5、组件化
在大型应用开发的时候,页面可以划分成很多部分。往往不同的页面,也会有相同的部分。
例如可能会有相同的头部导航。
但是如果每个页面都独自开发,这无疑增加了我们开发的成本。所以我们会把页面的不同部
分拆分成独立的组件,然后在不同页面就可以共享这些组件,避免重复开发。
在 vue 里,所有的 vue 实例都是组件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
<button v-on:click="count++">我被点击了 {{count}} 次</button>
<counter></counter>
<counter></counter>
<counter></counter>
<counter></counter>
<counter></counter>
<!-- 使用所定义的组件button-counter -->
<button-counter></button-counter>
</div>
<script src="../node_modules/vue/dist/vue.js"></script>
<script>
//1、全局声明注册一个组件
Vue.component("counter", {
template: `<button v-on:click="count++">我被点击了 {{count}} 次</button>`,
data() {
return {
count: 1
}
}
});
//2、局部声明一个组件
const buttonCounter = {
template: `<button v-on:click="count++">我被点击了 {{count}} 次~~~</button>`,
data() {
return {
count: 1
}
}
};
new Vue({
el: "#app",
data: {
count: 1
},
components: {
//声明所定义的局部组件
'button-counter': buttonCounter
}
})
</script>
</body>
</html>
- 组件其实也是一个 Vue 实例,因此它在定义时也会接收:data、methods、生命周期函数等
- 不同的是组件不会与页面的元素绑定,否则就无法复用了,因此没有 el 属性。
- 但是组件渲染需要 html 模板,所以增加了 template 属性,值就是 HTML 模板
- 全局组件定义完毕,任何 vue 实例都可以直接在 HTML 中通过组件名称来使用组件了
- data 必须是一个函数,不再是一个对象
6、生命周期钩子函数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
<span id="num">{{num}}</span>
<button @click="num++">赞!</button>
<h2>{{name}},有{{num}}个人点赞</h2>
</div>
<script src="../node_modules/vue/dist/vue.js"></script>
<script>
let app = new Vue({
el: "#app",
data: {
name: "张三",
num: 100
},
methods: {
show() {
return this.name;
},
add() {
this.num++;
}
},
beforeCreate() {
console.log("=========beforeCreate=============");
console.log("数据模型未加载:" + this.name, this.num);
console.log("方法未加载:" + this.show());
console.log("html模板未加载:" + document.getElementById("num"));
},
created: function () {
console.log("=========created=============");
console.log("数据模型已加载:" + this.name, this.num);
console.log("方法已加载:" + this.show());
console.log("html模板已加载:" + document.getElementById("num"));
console.log("html模板未渲染:" + document.getElementById("num").innerText);
},
beforeMount() {
console.log("=========beforeMount=============");
console.log("html模板未渲染:" + document.getElementById("num").innerText);
},
mounted() {
console.log("=========mounted=============");
console.log("html模板已渲染:" + document.getElementById("num").innerText);
},
beforeUpdate() {
console.log("=========beforeUpdate=============");
console.log("数据模型已更新:" + this.num);
console.log("html模板未更新:" + document.getElementById("num").innerText);
},
updated() {
console.log("=========updated=============");
console.log("数据模型已更新:" + this.num);
console.log("html模板已更新:" + document.getElementById("num").innerText);
}
});
</script>
</body>
</html>
7、模块化开发
7.1、环境配置
全局安装webpack
npm install webpack -g
全局安装vue
npm install -g @vue/cli-init
webpack是自动化项目构建工具。gulp 也是同类产品
7.2、初始化一个vue项目
安装后使用vue命令初始化项目提示
vue init webpack vue-demo
bash: vue: command not found
查看npm安装路径prefix
npm config list
在这个目录下没有vue的文件
prefix = "C:\\Users\\11244\\AppData\\Roaming\\npm"
解决方法:
npm install --global vue-cli
再次执行vue init webpack vue-demo成功。
创建过程中有一些项目配置
Project name //项目名称
Project description (A Vue.js project) //项目描述
? Author (齐天大圣 <1124421329@qq.com>) //作者
Vue build (Use arrow keys) //默认,回车即可
Install vue-router? //Y
Use ESLint to lint your code? //是否用ESLint来规范我们的代码 No
Set up unit tests //是否使用自动化的测试工具 No
Setup e2e tests with Nightwatch? //使用nightatch设置E2E测试 No
Should we run `npm install` for you after the project has been created? (recom
mended) (Use arrow keys) 选择npm安装
运行vue项目
npm run dev
7.3项目结构
7.3、运行流程
-
进入页面首先加载 index.html 和 main.js 文件。
-
main.js 导入了一些模块【vue、app、router】,并且创建 vue 实例,关联 index.html 页面的
元素。使用了 router,导入了 App 组件。并且使用标签引用了这个组件 -
第一次默认显示 App 组件。App 组件有个图片和,所以显示了图片。但是由于代表路由的视图,默认是访问/#/路径(router 路径默认使用 HASH 模式)。在 router 中配置的/是显示 HelloWorld 组件。
-
所以第一次访问,显示图片和 HelloWorld 组件。
-
我们尝试自己写一个组件,并且加入路由。点击跳转。需要使用Go to Foo标签
8、vue整合echarts
npm install echarts --save
创建components
<template>
<div id="main" :style="{width: '1400px', height: '400px'}"></div>
</template>
<<script>
import * as echarts from 'echarts';
export default {
name: 'EchartsDemo',
watch: {
data:{
handler(val, oldVal){
this.init();
},
deep:true //true 深度监听
},
},
data () {
return {
data: [],
}
},
mounted() {
this.init()
},
methods: {
init(){
}
},
}
</script>
例如:
<template>
<div id="main" :style="{width: '1400px', height: '400px'}"></div>
</template>
<<script>
import * as echarts from 'echarts';
export default {
name: 'BarDemo',
watch: {
data:{
handler(val, oldVal){
this.init();
},
deep:true //true 深度监听
},
},
data () {
return {
data: [120, 200, 150, 80, 70, 110, 130],
//x轴刻度
xAxisData: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
}
},
mounted() {
this.init()
},
methods: {
init(){
var chartDom = document.getElementById('main');
var myChart = echarts.init(chartDom);
var option;
option = {
//竖着的柱状图
// xAxis: {
// type: 'category',
// data: this.xAxisData
// },
// yAxis: {
// type: 'value'
// },
//横着的柱状图
yAxis: {
type: 'category',
data: this.xAxisData
},
xAxis: {
type: 'value'
},
series: [
{
data: this.data,
type: 'bar'
}
]
};
option && myChart.setOption(option);
}
},
}
</script>
注意这里要用mounted,使用created报错:Error: Initialize failed: invalid dom.
created这时候还只是创建了实例,但模板还没挂载完成
在index中添加
//导入组件
import EchartsDemo from '@/components/test/EchartsDemo'
//添加routes
{
path: '/EchartsDemo',
name: 'EchartsDemo',
component: EchartsDemo
}
在其他页面使用router-link跳转即可
<router-link to="/EchartsDemo">echarts柱状图</router-link>
9. vue整合element ui
官网: https://element.eleme.cn/#/zh-CN/component/installation
安装
npm i element-ui -S
在 main.js 中写入以下内容:
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI);
现在就可以在vue中使用elementui组件了