什么是Vue.js
Vue.js 是目前最火的一个前端框架,React是最流行的一个前端框架(React除了开发网站,还可以开发手机App, Vue语法也是可以用于进行手机App开发的,需要借助于Weex)
Vue.js 是前端的主流框架之一,和Angular.js、React.js 一起,并成为前端三大主流框架!
Vue.js 是一套构建用户界面的框架,只关注视图层,它不仅易于上手,还便于与第三方库或既有项目整合。(Vue有配套的第三方类库,可以整合起来做大型项目的开发)
前端的主要工作?主要负责MVC中的V这一层;主要工作就是和界面打交道,来制作前端页面效果;
为什么要学习流行框架
企业为了提高开发效率:在企业中,时间就是效率,效率就是金钱;企业中,使用框架,能够提高开发的效率;
提高开发效率的发展历程:原生JS -> Jquery之类的类库 -> 前端模板引擎 -> Angular.js / Vue.js(能够帮助我们减少不必要的DOM操作;提高渲染效率;双向数据绑定的概念【通过框架提供的指令,我们前端程序员只需要关心数据的业务逻辑,不再关心DOM是如何渲染的了】)
在Vue中,一个核心的概念,就是让用户不再操作DOM元素,解放了用户的双手,让程序员可以更多的时间去关注业务逻辑;
增强自己就业时候的竞争力
人无我有,人有我优
框架和库的区别
框架:是一套完整的解决方案;对项目的侵入性较大,项目如果需要更换框架,则需要重新架构整个项目。 - node 中的 express;
库(插件):提供某一个小功能,对项目的侵入性较小,如果某个库无法完成某些需求,可以很容易切换到其它库实现需求。
- 1. 从Jquery 切换到 Zepto
- 2. 从 EJS 切换到 art-template
Node(后端)中的 MVC 与 前端中的 MVVM 之间的区别
MVC 是后端的分层开发概念;
MVVM是前端视图层的概念,主要关注于 视图层分离,也就是说:MVVM把前端的视图层,分为了 三部分 Model, View , VM ViewModel
Vue之 - `基本的代码结构`和`插值表达式`、`v-cloak`
{{msg}} //使用v-aloak能够解决 插值表达式闪烁问题
//默认v-text没有闪烁问题
//创建vue实例
var vm = new Vue({
el:"#app",
data:{
msg:"欢迎学习vue",
msg2:"
",
}
})
这是第 {{i}} 个P标签 在2.x版本中[手动实现筛选的方式](https://cn.vuejs.org/v2/guide/list.html#显示过滤-排序结果) Vue调试工具`vue-devtools`的安装步骤和使用 过滤器 {{ msg | msgFormat('love', 'you') | test }} 私有过滤器 全局过滤器 键盘修饰符以及自定义键盘修饰符 [自定义指令](https://cn.vuejs.org/v2/guide/custom-directive.html) 使用 Vue.directive() 定义全局的指令 v-focus // 自定义一个 设置字体颜色的 指令 // 自定义局部指令 v-color 和 v-font-weight,为绑定的元素设置指定的字体颜色 和 字体粗细: Vue 1.x 中 自定义元素指令【已废弃,了解即可】 [vue实例的生命周期](https://cn.vuejs.org/v2/guide/instance.html#实例生命周期) [vue-resource 实现 get, post, jsonp请求](https://github.com/pagekit/vue-resource) 5. vue-resource 的配置步骤: 配置本地数据库和数据接口API // 如果我们通过全局配置了,请求的数据接口 根域名,则 ,在每次单独发起 http 请求的时候,请求的 url 路径,应该以相对路径开头,前面不能带 / ,否则 不会启用根路径做拼接; [Vue中的动画](https://cn.vuejs.org/v2/guide/transitions.html) [使用第三方 CSS 动画库](https://cn.vuejs.org/v2/guide/transitions.html#自定义过渡类名) 使用动画钩子函数 [v-for 的列表过渡](https://cn.vuejs.org/v2/guide/transitions.html#列表的进入和离开过渡) 定义Vue组件 组件中展示数据和响应事件 2. 在子组件中,如果将模板字符串,定义到了script标签中,那么,要访问子组件身上的`data`属性中的值,需要使用`this`来访问; 使用`components`属性定义局部子组件 使用`flag`标识符结合`v-if`和`v-else`切换组件 使用`:is`属性来切换不同的子组件,并添加切换动画 父组件向子组件传值 子组件向父组件传值 评论列表案例 使用 `this.$refs` 来获取元素和组件 什么是路由? 在 vue 中使用 vue-router 在路由规则中定义参数 使用 `children` 属性实现路由嵌套 命名视图实现经典布局 `watch`属性的使用 `computed`计算属性的使用 `watch`、`computed`和`methods`之间的对比 `nrm`的安装使用 Webpack: 网页中引入的静态资源多了以后有什么问题??? 如何解决上述两个问题 什么是webpack? 如何完美实现上述的2种解决方案 webpack安装的两种方式 初步使用webpack打包构建列表隔行变色案例 使用webpack的配置文件简化打包时候的命令 实现webpack的实时打包构建 使用`html-webpack-plugin`插件配置启动页面 实现自动打开浏览器、热更新和配置浏览器的默认端口号 使用webpack打包css文件 使用webpack打包less文件 使用webpack打包sass文件 使用webpack处理css中的路径 使用babel处理高级JS语法 相关文章 webpack.config.js: 在webpack中配置.vue组件页面的解析 在使用webpack构建的Vue项目中使用模板对象? ES6中语法使用总结 在vue组件页面中,集成vue-router路由模块 组件中的css作用域问题Vue指令之`v-bind`的三种用法
1. 直接使用指令`v-bind`
2. 使用简化指令`:`
3. 在绑定的时候,拼接绑定内容:`:title="btnTitle + ', 这是追加的内容'"`
data:{
mytitle:"这是一个自定义title"
}
Vue指令之`v-on`和`跑马灯效果`
methods:{
show:function (e) {
console.log(e)
}
}
{{ msg }}
// 注意:在 VM实例中,如果想要获取 data 上的数据,或者 想要调用 methods 中的 方法,必须通过 this.数据属性名 或 this.方法名 来进行访问,这里的this,就表示 我们 new 出来的 VM 实例对象
var vm = new Vue({
el: '#app',
data: {
msg: '猥琐发育,别浪~~!',
intervalId: null // 在data上定义 定时器Id
},
methods: {
go() {
if (this.intervalId != null) return;
this.intervalId = setInterval(() => {
var start = this.msg.substring(0, 1)
var end = this.msg.substring(1) // 获取到 后面的所有字符
this.msg = end + start // 重新拼接得到新的字符串,并赋值给 this.msg
}, 400)
// 注意: VM实例,会监听自己身上 data 中所有数据的改变,只要数据一发生变化,就会自动把 最新的数据,从data 上同步到页面中去;【好处:程序员只需要关心数据,不需要考虑如何重新渲染DOM页面】
},
stop() { // 停止定时器
clearInterval(this.intervalId)
this.intervalId = null; // 每当清除了定时器之后,需要重新把 intervalId 置为 null
}
}
})
Vue指令之`v-on的缩写`和`事件修饰符`
事件修饰符:
.stop 阻止冒泡
.prevent 阻止默认事件
.capture 添加事件侦听器时使用事件捕获模式
.self 只当事件在该元素本身(比如不是子元素)触发时触发回调
.once 事件只触发一次
Vue指令之`v-model`和`双向数据绑定`
{{msg}}
简易计算器案例
var vm = new Vue({
el: '#app',
data: {
n1: 0,
n2: 0,
result: 0,
opt: '+'
},
methods: {
calc() { // 计算器算数的方法
// 逻辑:
/* switch (this.opt) {
case '+':
this.result = parseInt(this.n1) + parseInt(this.n2)
break;
case '-':
this.result = parseInt(this.n1) - parseInt(this.n2)
break;
case '*':
this.result = parseInt(this.n1) * parseInt(this.n2)
break;
case '/':
this.result = parseInt(this.n1) / parseInt(this.n2)
break;
} */
// 注意:这是投机取巧的方式,正式开发中,尽量少用
var codeStr = 'parseInt(this.n1) ' + this.opt + ' parseInt(this.n2)'
this.result = eval(codeStr)
}
}
});
在Vue中使用样式
使用class样式
样式!!!
样式!!!
样式!!!
样式!!!
data: {
flag: true,
classObj: { red: true, thin: true, italic: false, active: false }
},
使用内联样式
1. 直接在元素上通过 `:style` 的形式,书写样式对象
这是一个H1
2. 将样式对象,定义到 `data` 中,并直接引用到 `:style` 中 在data上定义样式:
这是一个善良的H1
data: {
h1StyleObj: { color: 'red', 'font-size': '40px', 'font-weight': '200' }
}
+ 在元素中,通过属性绑定的形式,将样式对象应用到元素中:
3. 在 `:style` 中通过数组,引用多个 `data` 上的样式对象
这是一个善良的H1
data: {
h1StyleObj: { color: 'red', 'font-size': '40px', 'font-weight': '200' },
h1StyleObj2: { fontStyle: 'italic' }
}
Vue指令之`v-for`和`key`属性
1. 迭代数组
2. 迭代对象中的属性
3. 迭代数字 i 值从 1 开始
> 2.2.0+ 的版本里,当在组件中使用 v-for 时,key 现在是必须的。
当 Vue.js 用 v-for 正在更新已渲染过的元素列表时,它默认用 “就地复用” 策略。如果数据项的顺序被改变,Vue将不是移动 DOM 元素来匹配数据项的顺序, 而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素。
为了给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一 key 属性。
注意: v-for 循环的时候,key 属性只能使用 number获取string
注意: key 在使用的时候,必须使用 v-bind 属性绑定的形式,指定 key 的值
在组件中,使用v-for循环的时候,或者在一些特殊情况中,如果 v-for 有问题,必须 在使用 v-for 的同时,指定 唯一的 字符串/数字 类型 :key 值
Vue指令之`v-if`和`v-show`
v-if 的特点:每次都会重新删除或创建元素
v-show 的特点: 每次不会重新进行DOM的删除和创建操作,只是切换了元素的 display:none 样式
v-if 有较高的切换性能消耗 ,如果元素可能永远也不会被显示出来被用户看到,则推荐使用 v-if
v-show 有较高的初始渲染消耗 ,如果元素涉及到频繁的切换,最好不要使用 v-if, 而是推荐使用 v-show
列表案例:
搜素
// 在使用 `v-for` 指令循环每一行数据的时候,不再直接 `item in list`,而是 `in` 一个 过滤的methods 方法,同时,把过滤条件`keywords`传递进去
{{item.id}} -------- {{item.name}} ----- {{item.time}} -------
删除
search(keywords) { // 根据关键字,进行数据的搜索
/* var newList = []
this.list.forEach(item => {
if (item.name.indexOf(keywords) != -1) {
newList.push(item)
}
})
return newList */
// 注意: forEach some filter findIndex 这些都属于数组的新方法, 都会对数组中的每一项,进行遍历,执行相关的操作;
return this.list.filter(item => {
// if(item.name.indexOf(keywords) != -1)
// 注意 : ES6中,为字符串提供了一个新方法,叫做 String.prototype.includes('要包含的字符串')
// 如果包含,则返回 true ,否则返回 false
// contain
if (item.name.includes(keywords)) {
return item
}
})
}
[Vue.js devtools - 安装方式 - 推荐](https://chrome.google.com/webstore/detail/vuejs-devtools/nhdogjmejiglipccpnnnanhbledajbpd?hl=zh-CN)
概念:Vue.js 允许你自定义过滤器,**可被用作一些常见的文本格式化**。过滤器可以用在两个地方:**mustache 插值和 v-bind 表达式**。过滤器应该被添加在 JavaScript 表达式的尾部,由“管道”符指示;
// 过滤器的定义语法
// Vue.filter('过滤器的名称', function(){})
// 过滤器中的 function ,第一个参数,已经被规定死了,永远都是 过滤器 管道符前面 传递过来的数据
Vue.filter('过滤器的名称', function (data) {
return data + '123'
})
// 定义一个 Vue 全局的过滤器,名字叫做 msgFormat
Vue.filter('msgFormat', function (msg, arg, arg2) {
// 字符串的 replace 方法,第一个参数,除了可写一个 字符串之外,还可以定义一个正则
return msg.replace(/单纯/g, arg + arg2)
})
Vue.filter('test', function (msg) {
return msg + '========'
})
{{ item.ctime | dateFormat() }} 删除
// 全局的过滤器, 进行时间的格式化
// 所谓的全局过滤器,就是所有的VM实例都共享的
Vue.filter('dateFormat', function (dateStr, pattern = "") {
// 根据给定的时间字符串,得到特定的时间
var dt = new Date(dateStr)
// yyyy-mm-dd
var y = dt.getFullYear()
var m = dt.getMonth() + 1
var d = dt.getDate()
if (pattern.toLowerCase() === 'yyyy-mm-dd') {
return `${y}-${m}-${d}`
} else {
var hh = dt.getHours()
var mm = dt.getMinutes()
var ss = dt.getSeconds()
return `${y}-${m}-${d} ${hh}:${mm}:${ss}`
}
})
1. HTML元素:
{{item.ctime | dataFormat('yyyy-mm-dd')}}
2. 私有 `filters` 定义方式:
filters: { // 私有局部过滤器,只能在 当前 VM 对象所控制的 View 区域进行使用 过滤器有两个 条件 【过滤器名称 和 处理函数】
// 过滤器调用的时候,采用的是就近原则,如果私有过滤器和全局过滤器名称一致了,这时候 优先调用私有过滤器
dataFormat(input, pattern = "") { // 在参数列表中 通过 pattern="" 来指定形参默认值,防止报错
var dt = new Date(input);
var y = dt.getFullYear();// 获取年月日
var m = (dt.getMonth() + 1).toString().padStart(2, '0');
var d = dt.getDate().toString().padStart(2, '0');
// 如果 传递进来的字符串类型,转为小写之后,等于 yyyy-mm-dd,那么就返回 年-月-日 否则,就返回 年-月-日 时:分:秒
if (pattern.toLowerCase() === 'yyyy-mm-dd') {
return `${y}-${m}-${d}`;
} else {// 获取时分秒
var hh = dt.getHours().toString().padStart(2, '0');
var mm = dt.getMinutes().toString().padStart(2, '0');
var ss = dt.getSeconds().toString().padStart(2, '0');
return `${y}-${m}-${d} ${hh}:${mm}:${ss}`;
}
}
}
> 使用ES6中的字符串新方法 String.prototype.padStart(maxLength, fillString='') 或 String.prototype.padEnd(maxLength, fillString='')来填充字符串;
// 定义一个全局过滤器
Vue.filter('dataFormat', function (input, pattern = '') {
var dt = new Date(input);
var y = dt.getFullYear();// 获取年月日
var m = (dt.getMonth() + 1).toString().padStart(2, '0');
var d = dt.getDate().toString().padStart(2, '0');
// 如果 传递进来的字符串类型,转为小写之后,等于 yyyy-mm-dd,那么就返回 年-月-日 否则,就返回 年-月-日 时:分:秒
if (pattern.toLowerCase() === 'yyyy-mm-dd') {
return `${y}-${m}-${d}`;
} else {// 获取时分秒
var hh = dt.getHours().toString().padStart(2, '0');
var mm = dt.getMinutes().toString().padStart(2, '0');
var ss = dt.getSeconds().toString().padStart(2, '0');
return `${y}-${m}-${d} ${hh}:${mm}:${ss}`;
}
});
> 注意:当有局部和全局两个名称相同的过滤器时候,会以就近原则进行调用,即:局部过滤器优先于全局过滤器被调用!
1.x中自定义键盘修饰符【了解即可】
Vue.directive('on').keyCodes.f2 = 113;
2.x中自定义键盘修饰符](https://cn.vuejs.org/v2/guide/events.html#键值修饰符)
1. 通过`Vue.config.keyCodes.名称 = 按键值`来自定义案件修饰符的别名:
Vue.config.keyCodes.f2 = 113;
2. 使用自定义的按键修饰符:
1. 自定义全局和局部的 自定义指令:
// 自定义全局指令 v-focus,为绑定的元素自动获取焦点:
Vue.directive('focus', {
inserted: function (el) { // inserted 表示被绑定元素插入父节点时调用
el.focus();
}
});
// 其中:参数1 : 指令的名称,注意,在定义的时候,指令的名称前面,不需要加 v- 前缀, 但是: 在调用的时候,必须 在指令名称前 加上 v- 前缀来进行调用
// 参数2: 是一个对象,这个对象身上,有一些指令相关的函数,这些函数可以在特定的阶段,执行相关的操作
Vue.directive('focus', {
bind: function (el) { // 每当指令绑定到元素上的时候,会立即执行这个 bind 函数,只执行一次
// 注意: 在每个 函数中,第一个参数,永远是 el ,表示 被绑定了指令的那个元素,这个 el 参数,是一个原生的JS对象
// 在元素 刚绑定了指令的时候,还没有 插入到 DOM中去,这时候,调用 focus 方法没有作用, 因为,一个元素,只有插入DOM之后,才能获取焦点
// el.focus()
},
inserted: function (el) { // inserted 表示元素 插入到DOM中的时候,会执行 inserted 函数【触发1次】
el.focus() // 和JS行为有关的操作,最好在 inserted 中去执行,放置 JS行为不生效
},
updated: function (el) { // 当VNode更新的时候,会执行 updated, 可能会触发多次
}
})
Vue.directive('color', {
// 样式,只要通过指令绑定给了元素,不管这个元素有没有被插入到页面中去,这个元素肯定有了一个内联的样式, 将来元素肯定会显示到页面中,这时候,浏览器的渲染引擎必然会解析样式,应用给这个元素
bind: function (el, binding) { // 和样式相关的操作,一般都可以在 bind 执行
// el.style.color = 'red'
// console.log(binding.name) //color
// console.log(binding.value) // blue
// console.log(binding.expression) // 'blue'
el.style.color = binding.value
}
})
directives: {
color: { // 为元素设置指定的字体颜色
bind(el, binding) {
el.style.color = binding.value;
}
},
'font-weight': function (el, binding2) { // 自定义指令的简写形式,等同于定义了 bind 和 update 两个钩子函数
el.style.fontWeight = binding2.value;
}
}
2. 自定义指令的使用方式:
Vue.elementDirective('red-color', {
bind: function () {
this.el.style.color = 'red';
}
});
使用方式:
什么是生命周期:从Vue实例创建、运行、到销毁期间,总是伴随着各种各样的事件,这些事件,统称为生命周期!
[生命周期钩子](https://cn.vuejs.org/v2/api/#选项-生命周期钩子):就是生命周期事件的别名而已;
生命周期钩子 = 生命周期函数 = 生命周期事件
主要的生命周期函数分类:
创建期间的生命周期函数:
beforeCreate:实例刚在内存中被创建出来,此时,还没有初始化好 data 和 methods 属性
created:实例已经在内存中创建OK,此时 data 和 methods 已经创建OK,此时还没有开始 编译模板
beforeMount:此时已经完成了模板的编译,但是还没有挂载到页面中
mounted:此时,已经将编译好的模板,挂载到了页面指定的容器中显示
运行期间的生命周期函数:
beforeUpdate:状态更新之前执行此函数, 此时 data 中的状态值是最新的,但是界面上显示的 数据还是旧的,因为此时还没有开始重新渲染DOM节点
updated:实例更新完毕之后调用此函数,此时 data 中的状态值 和 界面上显示的数据,都已经完成了更新,界面已经被重新渲染好了!
销毁期间的生命周期函数:
beforeDestroy:实例销毁之前调用。在这一步,实例仍然完全可用。
destroyed:Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。
除了 vue-resource 之外,还可以使用 `axios` 的第三方包实现实现数据的请求
1. 之前的学习中,如何发起数据请求?
2. 常见的数据请求类型? get post jsonp
3. 测试的URL请求资源地址:
get请求地址: http://vue.studyit.io/api/getlunbo
post请求地址:http://vue.studyit.io/api/post
jsonp请求地址:http://vue.studyit.io/api/jsonp
4. JSONP的实现原理
由于浏览器的安全性限制,不允许AJAX访问 协议不同、域名不同、端口号不同的 数据接口,浏览器认为这种访问不安全;
可以通过动态创建script标签的形式,把script标签的src属性,指向数据接口的地址,因为script标签不存在跨域限制,这种数据获取方式,称作JSONP(注意:根据JSONP的实现原理,知晓,JSONP只支持Get请求);
具体实现过程:
先在客户端定义一个回调方法,预定义对数据的操作;
再把这个回调方法的名称,通过URL传参的形式,提交到服务器的数据接口;
服务器数据接口组织好要发送给客户端的数据,再拿着客户端传递过来的回调方法名称,拼接出一个调用这个方法的字符串,发送给客户端去解析执行;
客户端拿到服务器返回的字符串之后,当作Script脚本去解析执行,这样就能够拿到JSONP的数据了;
带大家通过 Node.js ,来手动实现一个JSONP的请求例子;
const http = require('http');
// 导入解析 URL 地址的核心模块
const urlModule = require('url');
const server = http.createServer();
// 监听 服务器的 request 请求事件,处理每个请求
server.on('request', (req, res) => {
const url = req.url;
// 解析客户端请求的URL地址
var info = urlModule.parse(url, true);
// 如果请求的 URL 地址是 /getjsonp ,则表示要获取JSONP类型的数据
if (info.pathname === '/getjsonp') {
// 获取客户端指定的回调函数的名称
var cbName = info.query.callback;
// 手动拼接要返回给客户端的数据对象
var data = {
name: 'zs',
age: 22,
gender: '男',
hobby: ['吃饭', '睡觉', '运动']
}
// 拼接出一个方法的调用,在调用这个方法的时候,把要发送给客户端的数据,序列化为字符串,作为参数传递给这个调用的方法:
var result = `${cbName}(${JSON.stringify(data)})`;
// 将拼接好的方法的调用,返回给客户端去解析执行
res.end(result);
} else {
res.end('404');
}
});
server.listen(3000, () => {
console.log('server running at http://127.0.0.1:3000');
});
案例:
const http = require('http') // 导入 http 内置模块
const urlModule = require('url') // 这个核心模块,能够帮我们解析 URL地址,从而拿到 pathname query
// 创建一个 http 服务器
const server = http.createServer()
// 监听 http 服务器的 request 请求
server.on('request', function (req, res) {
const { pathname: url, query } = urlModule.parse(req.url, true)
if (url === '/getscript') {
var data = {
name: 'xjj',
age: 18,
gender: '女孩子'
}
var scriptStr = `${query.callback}(${JSON.stringify(data)})`
// res.end 发送给 客户端, 客户端去把 这个 字符串,当作JS代码去解析执行
res.end(scriptStr)
} else {
res.end('404')
}
})
// 指定端口号并启动服务器监听
server.listen(3000, function () {
console.log('server listen at http://127.0.0.1:3000')
})
直接在页面中,通过`script`标签,引入 `vue-resource` 的脚本文件;
注意:引用的先后顺序是:先引用 `Vue` 的脚本文件,再引用 `vue-resource` 的脚本文件;
6. 发送get请求:
getInfo() { // get 方式获取数据
this.$http.get('http://127.0.0.1:8899/api/getlunbo').then(res => {
console.log(res.body);
})
}
7. 发送post请求:
postInfo() {
var url = 'http://127.0.0.1:8899/api/post';
// post 方法接收三个参数:
// 参数1: 要请求的URL地址
// 参数2: 要发送的数据对象
// 参数3: 指定post提交的编码类型为 application/x-www-form-urlencoded
this.$http.post(url, { name: 'zs' }, { emulateJSON: true }).then(res => {
console.log(res.body);
});
}
8. 发送JSONP请求获取数据:
jsonpInfo() { // JSONP形式从服务器获取数据
var url = 'http://127.0.0.1:8899/api/jsonp';
this.$http.jsonp(url).then(res => {
console.log(res.body);
});
}
1. 先解压安装 `PHPStudy`;
2. 解压安装 `Navicat` 这个数据库可视化工具,并激活;
3. 打开 `Navicat` 工具,新建空白数据库,名为 `dtcmsdb4`;
4. 双击新建的数据库,连接上这个空白数据库,在新建的数据库上`右键` -> `运行SQL文件`,选择并执行 `dtcmsdb4.sql` 这个数据库脚本文件;如果执行不报错,则数据库导入完成;
5. 进入文件夹 `vuecms3_nodejsapi` 内部,执行 `npm i` 安装所有的依赖项;
6. 先确保本机安装了 `nodemon`, 没有安装,则运行 `npm i nodemon -g` 进行全局安装,安装完毕后,进入到 `vuecms3_nodejsapi`目录 -> `src`目录 -> 双击运行 `start.bat`
7. 如果API启动失败,请检查 PHPStudy 是否正常开启,同时,检查 `app.js` 中第 `14行` 中数据库连接配置字符串是否正确;PHPStudy 中默认的 用户名是root,默认的密码也是root
Vue.http.options.root = 'http://vue.studyit.io/';
// 全局启用 emulateJSON 选项
Vue.http.options.emulateJSON = true;
// 创建 Vue 实例,得到 ViewModel
var vm = new Vue({
el: '#app',
data: {
name: '',
list: [ // 存放所有品牌列表的数组 ]
},
created() { // 当 vm 实例 的 data 和 methods 初始化完毕后,vm实例会自动执行created 这个生命周期函数
this.getAllList()
},
methods: {
getAllList() { // 获取列表
this.$http.get('api/getprodlist').then(result => {
var result = result.body
if (result.status === 0) { this.list = result.message } else { alert('获取数据失败!') }
})
},
add() { // 添加列表到后台服务器
2. this.$http.post() 中接收三个参数:
2.1 第一个参数: 要请求的URL地址
2.2 第二个参数: 要提交给服务器的数据 ,要以对象形式提交给服务器 { name: this.name }
3.3 第三个参数: 是一个配置对象,要以哪种表单数据类型提交过去, { emulateJSON: true }, 以普通表单格式,将数据提交给服务器 application/x-www-form-urlencoded
3. 在 post 方法中,使用 .then 来设置成功的回调函数,如果想要拿到成功的结果,需要 result.body
this.$http.post('api/addproduct', { name: this.name }).then(result => {
if (result.body.status === 0) {
this.getAllList() // 添加完成后,需要手动,再调用一下 getAllList 刷新品牌列表
this.name = '' // 清空 name
} else { alert('添加失败!') }
})
},
del(id) { // 删除品牌
this.$http.get('api/delproduct/' + id).then(result => {
if (result.body.status === 0) { // 删除成功
this.getAllList()
} else { alert('删除失败!') }
})
}
}
});
为什么要有动画:动画能够提高用户的体验,帮助用户更好的理解页面中的功能;
使用过渡类名
1. HTML结构:
2. VM 实例:
// 创建 Vue 实例,得到 ViewModel
var vm = new Vue({
el: '#app',
data: {
isshow: false
},
methods: {
myAnimate() {
this.isshow = !this.isshow;
}
}
});
3. 定义两组类样式:
/* 定义进入和离开时候的过渡状态 */
.fade-enter-active,
.fade-leave-active {
transition: all 0.2s ease;
position: absolute;
}
/* v-enter 【这是一个时间点】 是进入之前,元素的起始状态,此时还没有开始进入 */
/* v-leave-to 【这是一个时间点】 是动画离开之后,离开的终止状态,此时,元素 动画已经结束了 */
/* 定义进入过渡的开始状态 和 离开过渡的结束状态 */
.fade-enter,
.fade-leave-to {
opacity: 0;
transform: translateX(100px);
}
1. 导入动画类库:
2. 定义 transition 及属性:
leave-active-class="fadeOutRight"
:duration="{ enter: 500, leave: 800 }">
1. 定义 transition 组件以及三个钩子函数:
@enter="enter"
@after-enter="afterEnter">
2. 定义三个 methods 钩子方法:
methods: {// 动画钩子函数的第一个参数:el,表示 要执行动画的那个DOM元素,是个原生的 JS DOM对象
beforeEnter(el) { // 动画进入之前的回调
el.style.transform = 'translateX(500px)';
},
enter(el, done) { // 动画进入完成时候的回调
el.offsetWidth;// 这句话,没有实际的作用,但是,如果不写,出不来动画效果; 可以认为 el.offsetWidth 会强制动画刷新
el.style.transform = 'translateX(0px)';
el.style.transition = 'all 1s ease'
//回调函数done是必须的
done(); // 这里的 done, 起始就是 afterEnter 这个函数,也就是说:done 是 afterEnter 函数的引用
},
afterEnter(el) { // 动画进入完成之后的回调
this.isshow = !this.isshow;
}
}
3. 定义动画过渡时长和样式:
.show{
transition: all 0.4s ease;
}
1. 定义过渡样式:
2. 定义DOM结构,其中,需要使用 transition-group 组件把v-for循环的列表包裹起来:
3. 定义 VM中的结构:
// 创建 Vue 实例,得到 ViewModel
var vm = new Vue({
el: '#app',
data: {
txt: '',
list: [1, 2, 3, 4]
},
methods: {
add() {
this.list.push(this.txt);
this.txt = '';
}
},
del(i) {
this.list.splice(i, 1)
}
});
列表的排序过渡
`
`v-move` 和 `v-leave-active` 结合使用,能够让列表的过渡更加平缓柔和:
.v-move{
transition: all 0.8s ease;
}
.v-leave-active{
position: absolute;
}
相关文章
1. [vue.js 1.x 文档](https://v1-cn.vuejs.org/)
2. [vue.js 2.x 文档](https://cn.vuejs.org/)
3. [String.prototype.padStart(maxLength, fillString)](http://www.css88.com/archives/7715)
4. [js 里面的键盘事件对应的键码](http://www.cnblogs.com/wuhua1/p/6686237.html)
5. [pagekit/vue-resource](https://github.com/pagekit/vue-resource)
6. [navicat如何导入sql文件和导出sql文件](https://jingyan.baidu.com/article/a65957f4976aad24e67f9b9b.html)
7. [贝塞尔在线生成器](http://cubic-bezier.com/#.4,-0.3,1,.33)
什么是组件: 组件的出现,就是为了拆分Vue实例的代码量的,能够让我们以不同的组件,来划分不同的功能模块,将来我们需要什么样的功能,就可以去调用对应的组件即可;
组件化和模块化的不同:
模块化: 是从代码逻辑的角度进行划分的;方便代码分层开发,保证每个功能模块的职能单一;
组件化: 是从UI界面的角度进行划分的;前端的组件化,方便UI组件的重用;
全局组件定义的三种方式
// 如果使用 Vue.component 定义全局组件的时候,组件名称使用了 驼峰命名,则在引用组件的时候,需要把 大写的驼峰改为小写的字母,同时,两个单词之前,使用 - 链接; 如果不使用驼峰,则直接拿名称来使用即可;
// 注意:不论是哪种方式创建出来的组件,组件的 template 属性指向的模板内容,必须有且只能有唯一的一个根元素
1. 使用 Vue.extend 配合 Vue.component 方法:
var login = Vue.extend({
template: '登录
' // 通过 template 属性,指定了组件要展示的HTML结构
});
Vue.component('login', login);
2. 直接使用 Vue.component 方法:
Vue.component('register', {
template: '注册
'
});
③
Vue.component('mycom3', {
template: '#tmpl'
})
3. 将模板字符串,定义到script标签种:
同时,需要使用 Vue.component 来定义组件:
Vue.component('account', {
template: '#tmpl'
});
> 注意: 组件中的DOM结构,有且只能有唯一的根元素(Root Element)来进行包裹!
1. 在组件中,`data`需要被定义为一个方法,例如:
// 1. 组件可以有自己的 data 数据
// 2. 组件的 data 和 实例的 data 有点不一样,实例中的 data 可以为一个对象,但是 组件中的 data 必须是一个方法
// 3. 组件中的 data 除了必须为一个方法之外,这个方法内部,还必须返回一个对象才行;
Vue.component('account', {
template: '#tmpl',
data() {
return {
msg: '大家好!'
}
},
methods:{
login(){
alert('点击了登录按钮');
}
}
});
【重点】为什么组件中的data属性必须定义为一个方法并返回一个对象
1. 通过计数器案例演示
{{count}}
var dataObj = { count: 0 }
// 这是一个计数器的组件, 身上有个按钮,每当点击按钮,让 data 中的 count 值 +1
Vue.component('counter', {
template: '#tmpl',
data: function () {
// return dataObj
return { count: 0 }
},
methods: {
increment() {
this.count++
}
}
})
1. 组件实例定义方式:
2. 引用组件:
1. 页面结构:
2. Vue实例定义:
1. 组件实例定义方式:
// 登录组件
const login = Vue.extend({
template: `
登录组件
});
Vue.component('login', login);
// 注册组件
const register = Vue.extend({
template: `
注册组件
});
Vue.component('register', register);
// 创建 Vue 实例,得到 ViewModel
var vm = new Vue({
el: '#app',
data: { comName: 'login' },
methods: {}
});
2. 使用`component`标签,来引用组件,并通过`:is`属性来指定要加载的组件:
3. 添加切换样式:
1. 组件实例定义方式,注意:一定要使用`props`属性来定义父组件传递过来的数据
// 创建 Vue 实例,得到 ViewModel
var vm = new Vue({
el: '#app',
data: {// 注意: 子组件中的 data 数据是子组件自身私有的,比如: 子组件通过 Ajax ,请求回来的数据,都可以放到 data 身上;data 上的数据,都是可读可写的;
msg: '这是父组件中的消息'
},
components: {
son: {
template: '这是子组件 --- {{finfo}}
',
// 注意: 组件中的 所有 props 中的数据,都是通过 父组件传递给子组件的, props 中的数据,都是只读的,无法重新赋值
props: ['finfo']
}
}
});
2. 使用`v-bind`或简化指令,将数据传递到子组件中:
1. 原理:父组件将方法的引用,传递到子组件内部,子组件在内部调用父组件传递过来的方法,同时把要发送给父组件的数据,在调用方法的时候当作参数传递进去;
2. 父组件将方法的引用传递给子组件,其中,`getMsg`是父组件中`methods`中定义的方法名称,`func`是子组件调用传递过来方法时候的方法名称
3. 子组件内部通过`this.$emit('方法名', 要传递的数据)`方式,来调用父组件中的方法,同时把数据传递给父组件使用
这是一个大大的H1
1. 后端路由:对于普通的网站,所有的超链接都是URL地址,所有的URL地址都对应服务器上对应的资源;
2. 前端路由:对于单页面应用程序来说,主要通过URL中的hash(#号)来实现不同页面之间的切换,同时,hash有一个特点:HTTP请求中不会包含hash相关的内容;所以,单页面程序中的页面跳转主要用hash实现;
3. 在单页面应用程序中,这种通过hash改变来切换页面的方式,称作前端路由(区别于后端路由);
1. 导入 vue-router 组件类库:
2. 使用 router-link 组件来导航
3. 使用 router-view 组件来显示匹配到的组件
4. 创建使用`Vue.extend`创建组件
// 4.1 使用 Vue.extend 来创建登录组件
var login = Vue.extend({
template: '登录组件
'
});
// 4.2 使用 Vue.extend 来创建注册组件
var register = Vue.extend({
template: '注册组件
'
});
5. 创建一个路由 router 实例,通过 routers 属性来定义路由匹配规则
// 5. 创建一个路由 router 实例,通过 routers 属性来定义路由匹配规则
// 2. 创建一个路由对象, 当 导入 vue-router 包之后,在 window 全局对象中,就有了一个 路由的构造函数,叫做 VueRouter
var router = new VueRouter({
routes: [
{ path: '/', redirect: '/login' },
{ path: '/login', component: login },// 注意: component 的属性值,必须是一个 组件的模板对象, 不能是 组件的引用名称;
{ path: '/register', component: register }
],
linkActiveClass: 'myactive' //设置路由高亮
});
6. 使用 router 属性来使用路由规则
// 6. 创建 Vue 实例,得到 ViewModel
var vm = new Vue({
el: '#app',
router: router // 使用 router 属性来使用路由规则
});
var login = {
template: '登录 --- {{ $route.query.id }} --- {{ $route.query.name }}
',
created(){ // 组件的生命周期钩子函数
// console.log(this.$route)
// console.log(this.$route.query.id)
}
}
var router = new VueRouter({
routes: [
{ path: '/login', component: login },
]
})
1. 在规则中定义参数:
{ path: '/register/:id', component: register }
2. 通过 `this.$route.params`来获取路由中的参数:
var register = Vue.extend({
template: '注册组件 --- {{this.$route.params.id}}
'
});
var login = {
template: '登录 --- {{ $route.params.id }} --- {{ $route.params.name }}
',
created(){ // 组件的生命周期钩子函数
console.log(this.$route.params.id)
}
}
var router = new VueRouter({
routes: [
{ path: '/login/:id/:name', component: login },
]
})
1. 标签代码结构:
2. JS代码:
3. CSS 样式:
考虑一个问题:想要实现 `名` 和 `姓` 两个文本框的内容改变,则全名的文本框中的值也跟着改变;(用以前的知识如何实现???)
1. 监听`data`中属性的改变:
+
=
{{fullName}}
2. 监听路由对象的改变:
1. 默认只有`getter`的计算属性:
+
=
{{fullName}}
2. 定义有`getter`和`setter`的计算属性:
{{fullName}}
1. `computed`属性的结果会被缓存,除非依赖的响应式属性变化才会重新计算。主要当作属性来使用;
2. `methods`方法表示一个具体的操作,主要书写业务逻辑;
3. `watch`一个对象,键是需要观察的表达式,值是对应回调函数。主要用来监听某些特定数据的变化,从而进行某些具体的业务逻辑操作;可以看作是`computed`和`methods`的结合体;
作用:提供了一些最常用的NPM包镜像地址,能够让我们快速的切换安装包时候的服务器地址;
什么是镜像:原来包刚一开始是只存在于国外的NPM服务器,但是由于网络原因,经常访问不到,这时候,我们可以在国内,创建一个和官网完全一样的NPM服务器,只不过,数据都是从人家那里拿过来的,除此之外,使用方式完全一样;
1. 运行`npm i nrm -g`全局安装`nrm`包;
2. 使用`nrm ls`查看当前所有可用的镜像源地址以及当前所使用的镜像源地址;
3. 使用`nrm use npm`或`nrm use taobao`切换不同的镜像源地址;
在网页中会引用哪些常见的静态资源?
+ JS
- .js .jsx .coffee .ts(TypeScript 类 C# 语言)
+ CSS
- .css .less .sass .scss
+ Images
- .jpg .png .gif .bmp .svg
+ 字体文件(Fonts)
- .svg .ttf .eot .woff .woff2
+ 模板文件
- .ejs .jade .vue【这是在webpack中定义组件的方式,推荐这么用】
1. 网页加载速度慢, 因为 我们要发起很多的二次请求;
2. 要处理错综复杂的依赖关系
1. 合并、压缩、精灵图、图片的Base64编码
2. 可以使用之前学过的requireJS、也可以使用webpack可以解决各个包之间的复杂依赖关系;
webpack 是前端的一个项目构建工具,它是基于 Node.js 开发出来的一个前端工具;
1. 使用Gulp, 是基于 task 任务的;
2. 使用Webpack, 是基于整个项目进行构建的;
+ 借助于webpack这个前端自动化构建工具,可以完美实现资源的合并、打包、压缩、混淆等诸多功能。
+ 根据官网的图片介绍webpack打包的过程
+ [webpack官网](http://webpack.github.io/)
1. 运行`npm i webpack -g`全局安装webpack,这样就能在全局使用webpack的命令
2. 在项目根目录中运行`npm i webpack --save-dev`安装到项目依赖中
1. 运行`npm init`初始化项目,使用npm管理项目中的依赖包
2. 创建项目基本的目录结构
3. 使用`cnpm i jquery --save`安装jquery类库
4. 创建`main.js`并书写各行变色的代码逻辑:
// 导入jquery类库
import $ from 'jquery'
$('#list li:even').css('backgroundColor','lightblue'); // 设置偶数行背景色,索引从0开始,0是偶数
$('#list li:odd').css('backgroundColor','pink'); // 设置奇数行背景色
5. 直接在页面上引用`main.js`会报错,因为浏览器不认识`import`这种高级的JS语法,需要使用webpack进行处理,webpack默认会把这种高级的语法转换为低级的浏览器能识别的语法;
6. 运行`webpack 入口文件路径 输出文件路径`对`main.js`进行处理:
webpack src/js/main.js dist/bundle.js
1. 在项目根目录中创建`webpack.config.js`
2. 由于运行webpack命令的时候,webpack需要指定入口文件和输出文件的路径,所以,我们需要在`webpack.config.js`中配置这两个路径:
// 导入处理路径的模块
var path = require('path');
// 导出一个配置对象,将来webpack在启动的时候,会默认来查找webpack.config.js,并读取这个文件中导出的配置对象,来进行打包处理
module.exports = {
entry: path.resolve(__dirname, 'src/js/main.js'), // 项目入口文件
output: { // 配置输出选项
path: path.resolve(__dirname, 'dist'), // 配置输出的路径
filename: 'bundle.js' // 配置输出的文件名
}
}
1. 由于每次重新修改代码之后,都需要手动运行webpack打包的命令,比较麻烦,所以使用`webpack-dev-server`来实现代码实时打包编译,当修改代码之后,会自动进行打包构建。
2. 运行`cnpm i webpack-dev-server --save-dev`安装到开发依赖
3. 安装完成之后,在命令行直接运行`webpack-dev-server`来进行打包,发现报错,此时需要借助于`package.json`文件中的指令,来进行运行`webpack-dev-server`命令,在`scripts`节点下新增`"dev": "webpack-dev-server"`指令,发现可以进行实时打包,但是dist目录下并没有生成`bundle.js`文件,这是因为`webpack-dev-server`将打包好的文件放在了内存中
+ 把`bundle.js`放在内存中的好处是:由于需要实时打包编译,所以放在内存中速度会非常快
+ 这个时候访问webpack-dev-server启动的`http://localhost:8080/`网站,发现是一个文件夹的面板,需要点击到src目录下,才能打开我们的index首页,此时引用不到bundle.js文件,需要修改index.html中script的src属性为:``
+ 为了能在访问`http://localhost:8080/`的时候直接访问到index首页,可以使用`--contentBase src`指令来修改dev指令,指定启动的根目录:
"dev": "webpack-dev-server --contentBase src"
同时修改index页面中script的src属性为``
由于使用`--contentBase`指令的过程比较繁琐,需要指定启动的目录,同时还需要修改index.html中script标签的src属性,所以推荐大家使用`html-webpack-plugin`插件配置启动页面.
1. 运行`cnpm i html-webpack-plugin --save-dev`安装到开发依赖
2. 修改`webpack.config.js`配置文件如下:
// 导入处理路径的模块
var path = require('path');
// 导入自动生成HTMl文件的插件
var htmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: path.resolve(__dirname, 'src/js/main.js'), // 项目入口文件
output: { // 配置输出选项
path: path.resolve(__dirname, 'dist'), // 配置输出的路径
filename: 'bundle.js' // 配置输出的文件名
},
plugins:[ // 添加plugins节点配置插件
new htmlWebpackPlugin({
template:path.resolve(__dirname, 'src/index.html'),//模板路径
filename:'index.html'//自动生成的HTML文件的名称
})
]
}
3. 修改`package.json`中`script`节点中的dev指令如下:
"dev": "webpack-dev-server"
4. 将index.html中script标签注释掉,因为`html-webpack-plugin`插件会自动把bundle.js注入到index.html页面中!
**注意:热更新在JS中表现的不明显,可以从一会儿要讲到的CSS身上进行介绍说明!**
方式1:
修改`package.json`的script节点如下,其中`--open`表示自动打开浏览器,`--port 4321`表示打开的端口号为4321,`--hot`表示启用浏览器热更新:
"dev": "webpack-dev-server --hot --port 4321 --open"
方式2:
1. 修改`webpack.config.js`文件,新增`devServer`节点如下:
devServer:{
hot:true,
open:true,
port:4321
}
2. 在头部引入`webpack`模块:
var webpack = require('webpack');
3. 在`plugins`节点下新增:
new webpack.HotModuleReplacementPlugin()
1. 运行`cnpm i style-loader css-loader --save-dev`
2. 修改`webpack.config.js`这个配置文件:
module: { // 用来配置第三方loader模块的
rules: [ // 文件的匹配规则
{ test: /\.css$/, use: ['style-loader', 'css-loader'] }//处理css文件的规则
]
}
3. 注意:`use`表示使用哪些模块来处理`test`所匹配到的文件;`use`中相关loader模块的调用顺序是从后向前调用的;
1. 运行`cnpm i less-loader less -D`
2. 修改`webpack.config.js`这个配置文件:
{ test: /\.less$/, use: ['style-loader', 'css-loader', 'less-loader'] },
1. 运行`cnpm i sass-loader node-sass --save-dev`
2. 在`webpack.config.js`中添加处理sass文件的loader模块:
{ test: /\.scss$/, use: ['style-loader', 'css-loader', 'sass-loader'] }
1. 运行`cnpm i url-loader file-loader --save-dev`
2. 在`webpack.config.js`中添加处理url路径的loader模块:
{ test: /\.(png|jpg|gif)$/, use: 'url-loader' }
3. 可以通过`limit`指定进行base64编码的图片大小;只有小于指定字节(byte)的图片才会进行base64编码:
{ test: /\.(png|jpg|gif)$/, use: 'url-loader?limit=43960' },
1. 运行`cnpm i babel-core babel-loader babel-plugin-transform-runtime --save-dev`安装babel的相关loader包
2. 运行`cnpm i babel-preset-es2015 babel-preset-stage-0 --save-dev`安装babel转换的语法
3. 在`webpack.config.js`中添加相关loader模块,其中需要注意的是,一定要把`node_modules`文件夹添加到排除项:
{ test: /\.js$/, use: 'babel-loader', exclude: /node_modules/ }
4. 在项目根目录中添加`.babelrc`文件,并修改这个配置文件如下:
{
"presets":["es2015", "stage-0"],
"plugins":["transform-runtime"]
}
5. 注意:语法插件`babel-preset-es2015`可以更新为`babel-preset-env`,它包含了所有的ES相关的语法;**
[babel-preset-env:你需要的唯一Babel插件](https://segmentfault.com/p/1210000008466178)
[Runtime transform 运行时编译es6](https://segmentfault.com/a/1190000009065987)
// 由于 webpack 是基于Node进行构建的,所有,webpack的配置文件中,任何合法的Node代码都是支持的
var path = require('path')
// 在内存中,根据指定的模板页面,生成一份内存中的首页,同时自动把打包好的bundle注入到页面底部
// 如果要配置插件,需要在导出的对象中,挂载一个 plugins 节点
var htmlWebpackPlugin = require('html-webpack-plugin')
// 当以命令行形式运行 webpack 或 webpack-dev-server 的时候,工具会发现,我们并没有提供 要打包 的文件的 入口 和 出口文件,此时,他会检查项目根目录中的配置文件,并读取这个文件,就拿到了导出的这个 配置对象,然后根据这个对象,进行打包构建
module.exports = {
entry: path.join(__dirname, './src/main.js'), // 入口文件
output: { // 指定输出选项
path: path.join(__dirname, './dist'), // 输出路径
filename: 'bundle.js' // 指定输出文件的名称
},
plugins: [ // 所有webpack 插件的配置节点
new htmlWebpackPlugin({
template: path.join(__dirname, './src/index.html'), // 指定模板文件路径
filename: 'index.html' // 设置生成的内存页面的名称
})
],
module: { // 配置所有第三方loader 模块的
rules: [ // 第三方模块的匹配规则
{ test: /\.css$/, use: ['style-loader', 'css-loader'] }, // 处理 CSS 文件的 loader
{ test: /\.less$/, use: ['style-loader', 'css-loader', 'less-loader'] }, // 处理 less 文件的 loader
{ test: /\.scss$/, use: ['style-loader', 'css-loader', 'sass-loader'] }, // 处理 scss 文件的 loader
{ test: /\.(jpg|png|gif|bmp|jpeg)$/, use: 'url-loader?limit=7631&name=[hash:8]-[name].[ext]' }, // 处理 图片路径的 loader
// limit 给定的值,是图片的大小,单位是 byte, 如果我们引用的 图片,大于或等于给定的 limit值,则不会被转为base64格式的字符串, 如果 图片小于给定的 limit 值,则会被转为 base64的字符串
{ test: /\.(ttf|eot|svg|woff|woff2)$/, use: 'url-loader' }, // 处理 字体文件的 loader
{ test: /\.js$/, use: 'babel-loader', exclude: /node_modules/ }, // 配置 Babel 来转换高级的ES语法
]
}
}
1. 运行`cnpm i vue -S`将vue安装为运行依赖;
2. 运行`cnpm i vue-loader vue-template-compiler -D`将解析转换vue的包安装为开发依赖;
3. 运行`cnpm i style-loader css-loader -D`将解析转换CSS的包安装为开发依赖,因为.vue文件中会写CSS样式;
4. 在`webpack.config.js`中,添加如下`module`规则:
module: {
rules: [
{ test: /\.css$/, use: ['style-loader', 'css-loader'] },
{ test: /\.vue$/, use: 'vue-loader' }
]
}
5. 创建`App.js`组件页面:
这是APP组件 - {{msg}}
我是h3
6. 创建`main.js`入口文件:
// 导入 Vue 组件
import Vue from 'vue'
// 导入 App组件
import App from './components/App.vue'
// 创建一个 Vue 实例,使用 render 函数,渲染指定的组件
var vm = new Vue({
el: '#app',
render: c => c(App)
});
1. 在`webpack.config.js`中添加`resolve`属性:
resolve: {
alias: {
'vue$': 'vue/dist/vue.esm.js'
}
}
1. 使用 `export default` 和 `export` 导出模块中的成员; 对应ES5中的 `module.exports` 和 `export`
2. 使用 `import ** from **` 和 `import '路径'` 还有 `import {a, b} from '模块标识'` 导入其他模块
3. 使用箭头函数:`(a, b)=> { return a-b; }`
// 注意: export default 向外暴露的成员,可以使用任意的变量来接收
// 注意: 在一个模块中,export default 只允许向外暴露1次
// 注意: 在一个模块中,可以同时使用 export default 和 export 向外暴露成员
export var content = '哈哈哈'
// 注意: 使用 export 向外暴露的成员,只能使用 { } 的形式来接收,这种形式,叫做 【按需导出】
// 注意: export 可以向外暴露多个成员, 同时,如果某些成员,我们在 import 的时候,不需要,则可以 不在 {} 中定义
// 注意: 使用 export 导出的成员,必须严格按照 导出时候的名称,来使用 {} 按需接收;
// 注意: 使用 export 导出的成员,如果 就想 换个 名称来接收,可以使用 as 来起别名;
[vue-router官网](https://router.vuejs.org/)
1. 导入路由模块:
import VueRouter from 'vue-router'
2. 安装路由模块:
Vue.use(VueRouter);
3. 导入需要展示的组件:
import login from './components/account/login.vue'
import register from './components/account/register.vue'
4. 创建路由对象:
var router = new VueRouter({
routes: [
{ path: '/', redirect: '/login' },
{ path: '/login', component: login },
{ path: '/register', component: register }
]
});
5. 将路由对象,挂载到 Vue 实例上:
var vm = new Vue({
el: '#app',
// render: c => { return c(App) }
render(c) {
return c(App);
},
router // 将路由对象,挂载到 Vue 实例上
});
6. 改造App.vue组件,在 template 中,添加`router-link`和`router-view`:
你可能感兴趣的:(vue)