vue(筑基篇一)
1基础知识
1.1、概念区别
vue是把它们的特点整合起来。
1、单页面框架
2、给予模块化、组件化的安装模式
Vue.js是当下很火的一个JavaScript MVVM库(Model-View-ViewModel),它是以数据驱动和组件化的思想构建的。相比于Angular.js,Vue.js提供了更加简洁、更易于理解的API,使得我们能够快速地上手并使用Vue.js。
如果你之前已经习惯了用jQuery操作DOM,学习Vue.js时请先抛开手动操作DOM的思维,因为Vue.js是数据驱动的,你无需手动操作DOM。它通过一些特殊的HTML语法,将DOM和数据绑定起来。一旦你创建了绑定,DOM将和数据保持同步,每当变更了数据,DOM也会相应地更新。
当然了,在使用Vue.js时,你也可以结合其他库一起使用,比如jQuery
这2个链接是60分钟快速入门,讲解了原理
http://www.cnblogs.com/keepfool/p/5619070.html
https://www.cnblogs.com/rik28/p/6024425.html
这个是菜鸟入门,可运行看效果
http://www.runoob.com/vue2/vue-install.html
1.2 前端构建工具
前端构建工具(如 Webpack
功能定位
- 构建工具(如Webpack、Gulp)主要负责代码转换、打包和优化,将开发中的源代码(如ES6、Sass)转换为浏览器可识别的静态文件,并优化资源(如压缩CSS/JS、合并图片等)。
- 脚手架工具(如Vue CLI、Create React App)则提供项目快速搭建和初始化配置,生成项目结构、配置文件及基础代码,减少手动配置工作量。
使用场景
- 构建工具贯穿项目整个生命周期,从开发到维护均需使用(如Webpack需手动配置入口文件和loader)。
- 脚手架工具仅在项目初期使用,后续开发可直接使用其生成的配置文件。 15
典型差异
- Webpack需手动配置
webpack.config.js
文件,支持模块化打包、代码拆分等功能; - Vue CLI通过命令行生成项目模板,内置Vue Router、Vuex等插件,无需手动配置基础架构。
1.3 webpack
Webpack 本身只能处理 JavaScript 模块,如果要处理其他类型的文件,就需要使用 loader 进行转换。
所以如果我们需要在应用中添加 css 文件,就需要使用到 css-loader 和 style-loader,他们做两件不同的事情,css-loader 会遍历 CSS 文件,然后找到 url() 表达式然后处理他们,style-loader 会把原来的 CSS 代码插入页面中的一个 style 标签中。
接下来我们使用以下命令来安装 css-loader 和 style-loader(全局安装需要参数 -g)。
执行以上命令后,会再当前目录生成 node_modules 目录,它就是 css-loader 和 style-loader 的安装目录。
http://www.runoob.com/w3cnote/webpack-tutorial.html使用Vue的过程就是定义MVVM各个组成部分的过程。
1.4、环境搭建
必须先安装nodejs(自带Node.js 的包管理器npm),安装vue脚手架工具(命令行工具)# 最新稳定版
$ npm install vue
安装淘宝npm(cnpm)
(1)输入以下命令
npm install -g cnpm --registry=https://registry.npm.taobao.org
(2)输入cnpm -v输入是否正常,这里肯定会出错。
cnpm -v
(3)添加系统变量path的内容
因为cnpm会被安装到D:\Program Files\nodejs\node_global下,而系统变量path并未包含该路径。在系统变量path下添加该路径即可正常使用cnpm。
npm从国外下载包,cnpm从国内下载包
安装脚手架工具,即vue的命令行cli工具
cnpm install --global vue-cli
或
cnpm install -g @vue/cli
(它创建的目录结构很简单)
chcp 65001切换到utf8编码,应为在dos下项目有中文输出
安装webpack
cnpm install -g webpack
webpack是javascript打包器(module bundler)
1.node和npm卸载干净 1.1 apt-get卸载 sudo apt-get remove --purge npm sudo apt-get remove --purge nodejs sudo apt-get remove --purge nodejs-legacy sudo apt-get autoremove 1.2 手动删除npm及相关目录 rm -r /usr/local/bin/npm rm -r /usr/local/lib/node-moudels find / -name npm rm -r /tmp/npm* 2.离线安装node和npm
# apt-get install nodejs #安装nodejs安装好后node、noejs-legacy、npm都安装了,安装n把node更新到最新版,然后升级npm # 先在系统上安装好nodejs和npm #apt-get install nodejs-legacy #apt-get install npm # 升级npm为最新版本 #sudo npm install npm@latest -g # 安装用于安装nodejs的模块n sudo npm install -g n # 通过n模块安装指定的nodejs(3选一) sudo n stable(安装node稳定版) sudo n latest(不建议) sudo n lts(不建议) #which n #查看n安装目录 升级npm #npm i -g npm 设置淘宝镜像,此时npm就是cnpm(不是产生cnpm命令) sudo npm config set registry https://registry.npm.taobao.org //设置淘宝镜像 source ~/.bashrc //使修改立即生效 或安装淘宝镜像,因为npm的源是国外的,有时候会比较慢 (这么设置cnpm才是走淘宝镜像) npm install -g cnpm --registry=https://registry.npm.taobao.org
2、创建项目
2.1、创建项目:
vue init webpack projectName如:使用vue初始化一个项目, vue init webpack demo1
或
vue init webpack-simple demo2
注意:不能在vue当前目录执行这个命令,否则一直在下载中
或vue ui直接进入视图操作界面生成
2.2、进入项目,下载依赖:
npm install 或者 cnpm install
依赖放在node_modules目录,如果使用vue init webpack projectName安装,这个依赖会被同时安装,这一步可以省略
3、运行项目:
npm run dev运行完它,访问地址会自动生成
三、vue指令
安装脚手架工具,即vue的命令行cli工具
指令的作用:
将指令绑定在元素上时,指令会为绑定的目标元素添加一些特殊的行为。
vue内置的指令有:
v-html将key值当做html代码解析输出
v-if:
v-if
是条件渲染指令,它根据表达式的真假来删除和插入元素、v-show:是条件渲染指令,元素始终会被渲染到HTML,它只是简单地为元素设置CSS的style属性、
v-else:为
v-if
或v-show的
“else块”。v-else
元素必须立即跟在v-if
或v-show
元素的后面,否则它不能被识别,如:<h1 v-if="age >= 25">Age: {{ age }}</h1>
<h1 v-else>Name: {{ name }}</h1>
v-else
元素是否渲染在HTML中,取决于前面使用的是v-if
还是v-show
指令、v-for:基于一个数组渲染一个列表,它和JavaScript的遍历语法相似、
v-bind:
语法:v-bind:属性="属性key",可简写为:属性="属性key"
如<div v-bind:class="student"></div>,简写为<div :class="student"></div>
可以在其名称后面带一个参数,中间放一个冒号隔开,这个参数通常是HTML元素的特性(attribute),
例如:
<li v-for="n in pageCount">
<a href="javascripit:void(0)" v-bind:class="activeNumber === n + 1 ? 'active' : ''">{{ n + 1 }}</a>表达式的含义是:高亮当前页
</li>
new Vue({
el: '#app',
data: {
activeNumber: 1,
pageCount: 10 }
})
v-on:用于监听DOM事件,它的用语法和v-bind是类似的,例如监听<a>元素的点击事件,例如:
可简写为@click
如
<button v-on:click='func'>点击</button>
可简写为
<button @click='func'>点击</button>
<div id="app">
<p><input type="text" v-model="message"></p>
<button v-on:click="greet">Greet</button>
<button v-on:click="say('Hi')">Hi</button>
</div>
var vm = new Vue({
el: '#app',
data: { message: 'Hello, Vue.js!' }, // 在 `methods` 对象中定义方法
methods: {
greet: function() {
// 方法内 `this` 指向 vm
alert(this.message)
},
say: function(msg) {
alert(msg) }
}
})
也可以自定义指令。
指令里的变量定义在vue实例选项对象的data属性中。
<div id="app">
<h1 v-if="yes">Yes!</h1>
<h1 v-if="age >= 25">Age: {{ age }}</h1>
<h1 v-if="name.indexOf('jack') >= 0">Name: {{ name }}</h1>
</div>
var vm = new Vue({
el: '#app',
data: {
yes: true,
age: 28,
name: 'keepfool'
}
})
双向数据绑定v-model
只能在表单里面实现,model改变影响视图,view改变影响model
ref:用户获取dom节点,类似于id
在方法中通过this.$refs.对应的ref名获取相应的dom节点
设置ref用于获取dom节点
<div class="user" ref='userBox'>
,使用原生js对其属性进行设置
事件传值
<button data-sex='man' @click="getEvent($event)">事件传值</button>
四、route路由
Vue.js 路由允许我们通过不同的 URL 访问不同的内容。
通过 Vue.js 可以实现多视图的单页Web应用(single page web application,SPA)。
Vue.js 路由需要载入 vue-router 库
安装中文文档地址:https://router.vuejs.org/zh/
1、安装vue-router,并引入插件
推荐使用淘宝镜像:
cnpm install vue-router(或直接下载 / CDN:https://unpkg.com/vue-router/dist/vue-router.js)
在main.js配置文件中进行配置,引入vue-router
6、在app.vue根组件中将动态匹配到组件将渲染到<router-view></router-view>
路由链接或跳转
<router-link to="/home">home</router-link>
五、动态路由获取参数和get传值获取
.....
在news.vue里
}
<script>
六、model模块化方法封装和使用
在model里封装storage.js
//把封装的 方法storage暴露出去
在xxx.vue中引入
import storage from '../model/localstorage.js';
就可使用封装的方法了
如:storage.set('todoDataList', this.todoDataList);
七、组件封装注册和使用
组件用于扩展html在构建应运的不足,封装可重用的代码。由包含html的模板(所有内容要被根节点,如<div>包含)、js、css组成
App.vue是根组件,在里面可以引用其它组件,其它组件再引用别的组件,形成树状组件结构
1、写组件
2、使用import引用组件
3、使用components注册组件,起个别名
4、在模板中使用注册的别名组件
在components/ButtonCount.Vue写组件
<template>
<div>
<h1>点击计算器演示</h1>
<button @click="clickfnc">
{{ title }} you click me {{ cnt }} times
<slot></slot> //使用槽,这样在别的组件引用它时,可以在<button></button>元素里添加内容,否则不显示
</button>
</div>
</template>
<script>
export default {
// name : 'button_count',
props: { //定时组件元素属性,类型为String,默认值为title1
title: {
type : String,
default: 'title1:'
}
},
data(){
return {
cnt : 0,
};
},
methods: {
clickfnc : function() {
this.cnt++;
this.$emit('clicknow', this.cnt); //绑定clicknow方法,传递参数 this.cnt
}
}
}
</script>
//使用scoped,可以使该css样式只对当前组件起作用,但scoped对部分浏览器不支持,最好使用类限制
<style scoped="scoped">
h1 {
color:red;
}
</style>
在根组件app.Vue里引用ButtonCount组件
//组件属性,title为组件定义的属性,不写使用其默认值
<button-count title="描述" >
<h2>这是点击按钮</h2> //因为ButtonCount组件里使用了 <slot></slot>,这里的h2内容才能显示
</button-count>
<script>
//2、引用组件
import ButtonCount from '../components/ButtonCount.vue';
export default {
....,
components:{ //组件注册
'button-count': ButtonCount
}
}
</script>
八、生命周期钩子函数
生命周期钩子函数是组件挂载、更新、销毁时触发的一系列方法
beforeCreate | 组件实例刚被创建,组件属性计算之前,如data属性等 |
created | 组件实例创建完成,属性已绑定,但DOM还未生成,$el属性还不存在 |
beforeMount | 模板编译 / 挂载之前 |
mounted | 模板编译 / 挂载之后 |
beforeUpdate | 组件更新之前 |
update | 组件更新之后 |
activated | 组件被激活时调用 |
deactivated | 组件被移除时调用 |
beforeDestory | 组件销毁前调用 |
destoryed | 组件销毁后调用 |
在components/Life.Vue写组件
<template>
<div>
<h1>{{ message }}</h1>
<button @click='change'>更新message的值</button>
</div>
</template>
<script>
export default {
data(){
return {
message : '生命周期钩子组件'
};
},
methods: {
change: function() {
this.message='声明周期组件更新值测试'
}
},
beforeCreate(){
console.group('beforeCreate 创建前状态 ------------>');
console.log("%c%s", "color:red" , "el : " + this.$el); //undefined
console.log("%c%s", "color:red","data : " + this.$data); //undefined
console.log("%c%s", "color:red","message: " + this.message)
},
created() {
console.group('created 创建完毕状态 ------------>');
console.log("%c%s", "color:red","el : " + this.$el); //undefined
console.log("%c data值为:%O", "color:red", this.$data); //已被初始化
console.log("%c%s", "color:red","message: " + this.message); //已被初始化
},
beforeMount() {
console.group('beforeMount 挂载前状态 ------------>');
console.log("%c%s", "color:red","el : " + (this.$el)); //已被初始化
console.log("%c%s", "color:red","data : " + this.$data); //已被初始化
console.log("%c%s", "color:red","message: " + this.message); //已被初始化
},
mounted() {
console.group('mounted 挂载结束状态 ------------>');
console.log("%c%s", "color:red","el : " + this.$el); //已被初始化
console.log(this.$el);
console.log("%c%s", "color:red","data : " + this.$data); //已被初始化
console.log("%c%s", "color:red","message: " + this.message); //已被初始化
},
beforeUpdate() {
console.group('beforeUpdate 更新前状态 ------------>');
console.log("%c%s", "color:red","el : " + this.$el);
console.log(this.$el);
console.log('真实dom结构:' + document.getElementById('app').innerHTML);
console.log("%c%s", "color:red","data : " + this.$data);
console.log("%c%s", "color:red","message: " + this.message);
},
updated() {
console.group('updated 更新完成状态 ------------>');
console.log("%c%s", "color:red","el : " + this.$el);
console.log(this.$el);
console.log('真实dom结构:' + document.getElementById('app').innerHTML);
console.log("%c%s", "color:red","data : " + this.$data);
console.log("%c%s", "color:red","message: " + this.message);
},
beforeDestroy() {
console.group('beforeDestroy 销毁前状态 ------------>');
console.log("%c%s", "color:red","el : " + this.$el);
console.log(this.$el);
console.log("%c%s", "color:red","data : " + this.$data);
console.log("%c%s", "color:red","message: " + this.message);
},
destroyed() {
console.group('destroyed 销毁完成状态 ------------>');
console.log("%c%s", "color:red","el : " + this.$el);
console.log(this.$el);
console.log("%c%s", "color:red","data : " + this.$data);
console.log("%c%s", "color:red","message: " + this.message)
}
}
</script>
<div id="app">
<button @click="delVM">destory vm</button>
倒计时:{{ time }}秒
</div>
const vm = new Vue({
el: '#app',
data:{
time: 100,
},
methods: {
delVM() {
this.$destroy();
}
},
mounted(){
this.intervalId = setInterval(()=>{
console.log(this.time);
this.time--;
}, 1000);
},
beforeDestroy() {
clearInterval(this.intervalId);
}
});
<div id="app">
<button @click="flag=!flag">创建或销毁组件</button>
</template>
import Life from "../components/Life.vue";
'v-life' : Life
}