vue: 渐进式JavaScript 框架

Vue项目构建

npm install -g vue
vue init webpack-simple my-project
cd my-project
npm install
npm run dev

vue项目开发步骤

  • 根据原型稿拆分组件——》路由组件(pages)、复用组件(components)
  • 根据路由组件定好路由router/index.js
  • 看后端接口文档写好api/ajax、index请求好数据,有些时候后端没写好接口则需要自己mock数据
  • 确定好共享的状态数据,写好store
  • 分别用复用组件开发路由组件

Vue知识总结

Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层

模块化与组件化的区别:

  • 1.模块化是针对代码来说的,即抽离js代码进行复用
  • 2.组件化是针对Ui来说的,由组件就能很快组成一个页面

vue与react的比较

  • 1.Vue里使用.vue格式模板实现组件化,而react采用把html写进js即jsx
  • 2.vue是双向数据绑定,react是单向数据绑定,在通过state来管理

声明式渲染

<div id="app">
{{ message }}
</div>
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
}
})

条件与循环

<div id="app-3">
<p v-if="seen">现在你看到我了</p>
</div>
var app3 = new Vue({
el: '#app-3',
data: {
seen: true
}
})

处理用户输入

v-on 指令添加一个事件监听器,通过它调用在 Vue 实例中定义的方法

v-on:click = @click 事件

组件化应用构建

全局定义组件

// 定义名为 todo-item 的新组件
Vue.component('todo-item', {
template: '<li>这是个待办项</li>'
})
<ol>
<!-- 创建一个 todo-item 组件的实例 -->
<todo-item></todo-item>
</ol>

vue生命周期

)

vue指令

v-html绑定html

v-text绑定文本

v-bind:属性 = :属性 绑定属性

v-on:click = @click 事件

v-class

<ul  v-for="item in list1">
<li :class='{red: flag, blue: !flag}'>{{item}}</li>
</ul>

v-style

<div class="box" :style="{'width': boxWidth+'px'}">

</div>

获取ref定义的dom节点

<input type="text" ref="userInfo">
<div ref="box"></div>
<button @click="getValue()">点击</button>
export default {
data(){
return {
message: '这是一个根组件',
}
},
methods: {
getValue(){
console.log(this.$refs.userInfo);
this.$refs.box.style.background='red';
alert(this.$refs.userInfo.value);
}
}
}

修饰符

  • sync:在2.3.0+版本之后,vue又重新引进了.sync这个修饰符了,这个修饰符可以让子组件的数据带动父组件的数据改动。但是除了这个修饰符,我们还要在子组件里面添加一个watch 监测事件来,触发修改父组件的数据。

自定义属性

1.html里设置data-xx

2.把$event传给事件

3.事件利用e.srcElement.dataset.aid获取 或

e.srcElement.style.background='red';修改样式

<button data-aid='123' @click="eventFn($event)">事件对象</button>
export default {
data () {
return {
msg: '你好vue',
list:[]
}
},
methods:{
eventFn(e){
console.log(e);
// e.srcElement dom节点
e.srcElement.style.background='red';
console.log(e.srcElement.dataset.aid);//123 /*获取自定义属性的值*/
} }
}

vue父子组件通信

1、父组件可以使用 props 把数据传给子组件。

2、子组件可以使用 $emit 触发父组件的自定义事件。

vm.$emit( event, arg ) //触发当前实例上的事件

vm.$on( event, fn );//监听event事件后运行 fn;

例如:

子组件:

<template>
<div class="train-city">
<h3>父组件传给子组件的toCity:{{sendData}}</h3>
<br/><button @click='select(`大连`)'>点击此处将‘大连’发射给父组件</button>
</div>
</template>
<script>
export default {
name:'trainCity',
props:['sendData'], // 用来接收父组件传给子组件的数据
methods:{
select(val) {
let data = {
cityname: val
};
this.$emit('showCityName',data);//select事件触发后,自动触发showCityName事件
}
}
}
</script>

父组件:

<template>
<div>父组件的toCity{{toCity}}</div>
<train-city @showCityName="updateCity" :sendData="toCity"></train-city>
<template>
<script>
import TrainCity from "./train-city";
export default {
name:'index',
components: {TrainCity},
data () {
return {
toCity:"北京"
}
},
methods:{
updateCity(data){//触发子组件城市选择-选择城市的事件
this.toCity = data.cityname;//改变了父组件的值
console.log('toCity:'+this.toCity)
}
}
}
</script>

同级通信

<body>
<div id="app">
<huahua></huahua>
<shuandan></shuandan>
</div>
<script src="./vue.js"></script>
<script>
let Event = new Vue();
Vue.component('huahua', {
template: `<div>我说:<input v-model='i_said' @keyup='onChange'></div>`,
data: function(){
return {
i_said: ''
}
},
methods: {
onChange: function(){
Event.$emit('huahua-said-something', this.i_said);
}
}
});
Vue.component('shuandan', {
template: '<div>花花说:{{huahua_said}}</div>',
data: function(){
return {
huahua_said: ''
}
},
mounted: function(){
let _this = this;
console.log(_this);
Event.$on('huahua-said-something', function(data){
console.log('data', data);
//console.log('this', this);
_this.huahua_said = data;
})
}
})
let app = new Vue({
el: '#app'
})
</script>

vue中的注意点:

1.component中的data必须是函数

Vue.component('', {
template: '<div></div>',
data: function(){
return {
huahua_said: ''
}
}
})

2.为了给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一 key 属性。理想的 key 值是每项都有的且唯一的 id。

<div v-for="item in items" :key="item.id">
<!-- 内容 -->
</div>

vue组件库的使用。

element-ui使用局部引入使用

1.在组件里import { Table, TableColumn } from "element-ui";

2.components: {Table, TableColumn}

3.<Table></Table>、<table-column type="selection" width="55"></table-column>全局引入使用

1.在main中import { Input} from 'element-ui';

2.在组件中<el-input placeholder="请输入内容" prefix-icon="el-icon-search" v-model="input" @change="search" id="el-input"></el-input>

二者在使用时注意是否要加el-

增加eslint做代码规范

安装依赖

npm install eslint eslint-config-standard eslint-loader eslint-plugin-html eslint-plugin-import eslint-plugin-node eslint-plugin-promise eslint-plugin-standard -D

配置.eslintrc

{
"extends": "standard",
"plugins": [
"html"
],
"parser": "babel-eslint"
}

配置package.json的脚本:

"lint": "eslint --ext .js --ext .jsx --ext .vue client/",
"lint-fix": "eslint --fix --ext .js --ext .jsx --ext .vue client/",
"precommit": "npm run lint-fix"

执行命令

npm run lint
or
npm run lint-fix

webapck4升级

1.webpack相关的插件就是带有webpack的,以及loader插件(边升级报错,边修改);

2.有些API的修改或者废弃,需要修改配置

新增:

1、mode属性,在config中一定要写mode: process.env.NODE_ENV || 'production'

2、optimization属性

optimization: {
splitChunks: {
chunks: 'all'
},
runtimeChunk: true
}

废弃:

  • 1、webpack.NoEmitOnErrorsPlugin()
  • 2、webpack.optimize.CommonsChunkPlugin()

升级成webpack4过程遇到的坑

1.npm run dev后出现Path variable [contentHash] not implemented in this context: styles.[contentHash].css

解决方案:把[contentHash]换成 [chunkhash:8]

2.extract-text-webpack-plugin升级中警告它需要依赖webpack3,故决定试试@next,结果可以,

npm install extract-text-webpack-plugin@next,以后试试@next

单元测试(Unit Test)

用来对一个模块、一个函数或者一个类进行正确性检验的测试工作。

测试驱动开发: TDD-> Test-Driven Dovelopment

Karma(在node跑的测试框架)+Mocha

Mocha(测试框架) 不带断言库+Chai断言库

Vue遇到的坑

  • scpoed只对当前文件起作用。
  • for循环必须加key值,key值一般用item值而不用index,是为了虚拟dom的优化机制。

Vue犯错

  • router/index.js中的routes写错成routers,导致错误。

Vue组件库使用经验

element-ui使用

局部引入使用

1.在组件里import { Table, TableColumn } from "element-ui";

2. components: {Table, TableColumn}

3.<Table></Table><table-column type="selection" width="55"></table-column>

全局引入使用

1.在main中import { Input} from 'element-ui';

2.在组件中<el-input placeholder="请输入内容" prefix-icon="el-icon-search" v-model="input" @change="search" id="el-input"></el-input>

二者在使用时注意是否要加el-

方法methods、计算属性和侦听器computed、watch的区别

你可能已经注意到我们可以通过在表达式中调用方法来达到同样的效果:

<p>Reversed message: "{{ reversedMessage() }}"</p>
// 在组件中
methods: {
reversedMessage: function () {
return this.message.split('').reverse().join('')
}
}

我们可以将同一函数定义为一个方法而不是一个计算属性。两种方式的最终结果确实是完全相同的。然而,不同的是计算属性是基于它们的依赖进行缓存的。只在相关依赖发生改变时它们才会重新求值。这就意味着只要 message 还没有发生改变,多次访问 reversedMessage 计算属性会立即返回之前的计算结果,而不必再次执行函数。

这也同样意味着下面的计算属性将不再更新,因为 Date.now() 不是响应式依赖:

computed: {
now: function () {
return Date.now()
}
}

相比之下,每当触发重新渲染时,调用方法将总会再次执行函数。

我们为什么需要缓存?假设我们有一个性能开销比较大的计算属性 A,它需要遍历一个巨大的数组并做大量的计算。然后我们可能有其他的计算属性依赖于 A 。如果没有缓存,我们将不可避免的多次执行 A 的 getter!如果你不希望有缓存,请用方法来替代。

Vue 提供了一种更通用的方式来观察和响应 Vue 实例上的数据变动:侦听属性。当你有一些数据需要随着其它数据变动而变动时,你很容易滥用 watch——特别是如果你之前使用过 AngularJS。然而,通常更好的做法是使用计算属性而不是命令式的 watch 回调。细想一下这个例子:

<div id="demo">{{ fullName }}</div>
var vm = new Vue({
el: '#demo',
data: {
firstName: 'Foo',
lastName: 'Bar',
fullName: 'Foo Bar'
},
watch: {
firstName: function (val) {
this.fullName = val + ' ' + this.lastName
},
lastName: function (val) {
this.fullName = this.firstName + ' ' + val
}
}
})

上面代码是命令式且重复的。将它与计算属性的版本进行比较:

var vm = new Vue({
el: '#demo',
data: {
firstName: 'Foo',
lastName: 'Bar'
},
computed: {
fullName: function () {
return this.firstName + ' ' + this.lastName
}
}
})

引入外部库或者插件

  • 引入外部库

在main.js

import moment from 'moment';
Object.defineProperty(Vue.prototype, '$moment', { value: moment });

MyNewComponent.vue

export default {
created() {
console.log('The time is ' . this.$moment().format("HH:mm"));
}
}
  • 如何创建自己的Vue插件

    在main.js

import MyLibraryPlugin from 'my-library-plugin';
Vue.use(MyLibraryPlugin);
  • 如何写插件

首先,创建一个文件。本例中,我将引入一个Axios库的插件。我们就把这个文件命名为axios.js吧。

最关键的地方在于,我们需要暴露一个将Vue构造器作为第一个参数的install方法。

axios.js

export default {
install: function(Vue) {
// Do stuff
}
}

然后我们可以用之前的方式将库添加到Vue的原型对象上:

axios.js

import axios from 'axios';

export default {
install: function(Vue) {
Object.defineProperty(Vue.prototype, '$http', { value: axios });
}
}

接着我们只需要Vue实例的use方法就能将这个库引入整个项目了。我们像下面代码一样简单引入:

main.js

import AxiosPlugin from './axios.js';
Vue.use(AxiosPlugin); new Vue({
created() {
console.log(this.$http ? 'Axios works!' : 'Uh oh..');
}
})
  • 插件参数设置

插件的install方法还可以接受其他的可选参数。有些开发者可能不喜欢Axios实例对象的方法名$http,因为Vue resource插件的方法名也是这个。然后,让我们利用第二个参数来修改它。

axios.js

import axios from 'axios';

export default {
install: function(Vue, name = '$http') {
Object.defineProperty(Vue.prototype, name, { value: axios });
}
}

main.js

import AxiosPlugin from './axios.js';
Vue.use(AxiosPlugin, '$axios'); new Vue({
created() {
console.log(this.$axios ? 'Axios works!' : 'Uh oh..');
}
})

开发基于vue的组件库

参考: 如何开发一套基于Vue的组件库

vue知识总结的更多相关文章

  1. 2018 我要告诉你的 Vue 知识大全

    Vue ,React ,Angular 三大主流框架,最后我选择学习 Vue ,接触过 React ,自己感觉学习曲线有些陡峭,进而我选择了学习 Vue ,他的学习曲线平稳很多:不管选择什么框架,除了 ...

  2. 总结vue知识体系之实用技巧

    vue 作为目前前端三大框架之一,对于前端开发者可以说是必备技能.那么怎么系统地学习和掌握 vue 呢?为此,我做了简单的知识体系体系总结,不足之处请各位大佬多多包涵和指正,如果喜欢的可以点个小赞!本 ...

  3. vue知识总汇

    学前预备知识 ECMAScript简介和ES6的新增语法 Nodejs基础 webpack的介绍 babel简介 vue基础 vue基础

  4. Vue知识分享一

    最近想着把之前学的Vue的知识整理一下,方便在公司和同事一起分享.我想要按照下面几个方面去说一下,我对vue的学习理解. 一.什么是VUE vue.js是一个用来开发Web界面的前端库,是很轻量级的工 ...

  5. 前端Vue知识小白

    感觉是已好久没写博文了.今日难得有时间,便写一篇文章.此文章是关于前端知识的,我本身是后端,因工作或其他需要,便学习了前端Vue.此文章是在菜鸟教程上学习的.那么下面进入正文! 首先,Vue.js是一 ...

  6. 前端知识扫盲-VUE知识篇一(VUE核心知识)

    最近对整个前端的知识做了一次复盘,总结了一些知识点,分享给大家有助于加深印象. 想要更加理解透彻的同学,还需要大家自己去查阅资料或者翻看源码.后面会陆续的更新一些相关注知识点的文章. 文章只提出问题, ...

  7. Vue 知识复习(上)

    Vue Vue实例 创建实例: var vm = new Vue({ //code }) 数据与方法: 只有当实例被创建时 data 中存在的属性才是响应式的; Vm.b = 'h1' 是不会触发视图 ...

  8. Vue 知识整理—02-起步

    一:Vue 语法格式: vue vm = new Vue({ //选项 }) 二:Vue 实例: <div id="app"> <p>{{message}} ...

  9. Vue 知识整理—01-基础

    一:Vue是什么? Vue是一个JS框架. Vue.js是一套构建用户界面的渐进式框架. 库和框架的区别: ☞库:提供一些 API 工具函数,体现了封装的思想,需要我们主动调用: ☞框架:提供一套完整 ...

随机推荐

  1. UVA 548 Tree 建树

    题意: 输入中序和后序的权值,输出哪个叶子使它到根的路径上权和最小. 思路: 输入后建树,然后dfs求最小的叶子. #include<iostream> #include<cstdi ...

  2. In the beginning, Coders create the repos and blogs

    ---恢复内容开始--- 这是一个新的博客 print(‘hello new world’) 这个博客叫做 brain in a jar, 不知道以后会不会改名. 只是因为偶然想到了普特南的缸中之脑理 ...

  3. BZOJ 5118

    矩阵乘也是可以欧拉定理的HHH 所以幂次就是$(2^n-1) ~ mod ~ \varphi(p)$就好了 const ll p=1125899839733759ll; inline ll mu(ll ...

  4. Java面试宝典2018

    转 Java面试宝典2018 一. Java基础部分…………………………………………………………………………………….. 7 1.一个“.java”源文件中是否可以包括多个类(不是内部类)?有什么限制 ...

  5. js 执行顺序

    同步任务 异步任务 同步任务:立即执行 异步任务:进入到异步队列当中(Event Queue)eg:Ajax,SetTimeout,then,SetInterval Event loop 事件循环 T ...

  6. 自定义 绑定响应函数 解除响应函数 .addEventListener 兼容 .attachEvent

    嗯哼.不多说,直接上代码. // 自定义 绑定响应函数 兼容性封装 Test Already. function bindEventFunc(obj, eventStr, func){ // cons ...

  7. MyISAM和Innodb区别,为什么?

    事务支持 MyISAM不支持事务,而InnoDB支持. InnoDB的AUTOCOMMIT默认是打开的,即每条SQL语句会默认被封装成一个事务,自动提交,这样会影响速度, 所以最好是把多条SQL语句显 ...

  8. VS开发入门三:c#的类的修饰符和成员的修饰符

    初学者经常会犯下的错误就是,修饰符一大堆,而且类和其成员很多修饰符是一样的容易混用 这里总结下 C#修饰符之类修饰符(个 助记 PIPA SS ):public.internal. partial(多 ...

  9. yield关键字

    1.yield语句有两种形式 (1)yield return <expression>;一次返回一个元素 运行yield return 语句时,会返回一个 值,并记录当前位置及保留该值.下 ...

  10. [strongswan] strongswan是如何实现与xfrm之间的trap机制的

    目录 strongswan与xfrm之间的trap机制 0. 1. 前言 2. 描述 2.1 none 2.2 trap 3. 实验与过程 3.1 trap实验 3.2 none实验 4 背景知识 5 ...