Vue(适合移动端的项目,特点小巧,不兼容ie)
https://cn.vuejs.org(官网)
基础代码(声明式渲染)
Vue.js 的核心是一个允许采用简洁的模板语法来声明式地将数据渲染进 DOM 的系统:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<script src="./lib/vue%20(1).js"></script>
<body>
<div id="app">
{{message}}
</div>
<script>
window.onload= function () {
var app=new Vue({
el:'#app',
data:{
message:'Hellobejing'
}
})
}
</script>
</body>
</html>
我们已经成功创建了第一个 Vue 应用!看起来这跟渲染一个字符串模板非常类似,但是 Vue 在背后做了大量工作。现在数据和 DOM 已经被建立了关联,所有东西都是响应式的。我们要怎么确认呢?打开你的浏览器的 JavaScript 控制台 (就在这个页面打开),并修改 app.message 的值,你将看到上例相应地更新。
除了文本插值,我们还可以像这样来绑定元素特性:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<script src="./lib/vue%20(1).js"></script>
<body>
<div id="app">
<span v-bind:title="message">//简写v-bind:title 可以写成:title
鼠标悬停此处查看动态绑定提示信息
</span>
</div>
<script>
var app=new Vue({
el:'#app',
data:{
message:'页面加载于'+new Date().toLocaleString()
}
})
</script>
</body>
</html>
//class宇style是特例 两者绑定的方式相同举例如下(注意复合样式,采用驼峰命名法)
//第一种方法
data:{
c:{color:'red'},
b:{backgroundColor:'blue'}
}
<p :style="[c,b]">文字</p>
//第二种方法
data:{
json:{
color:'red',
backgroundColor:'green'
}
}
<div class="box">
<p :style="json">这是个文字</p>
</div>
这里我们遇到了一点新东西。你看到的 v-bind 特性被称为指令。指令带有前缀 v-,以表示它们是 Vue 提供的特殊特性。可能你已经猜到了,它们会在渲染的 DOM 上应用特殊的响应式行为。在这里,该指令的意思是:“将这个元素节点的 title 特性和 Vue 实例的 message 属性保持一致”。
双向数据绑定
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<script src="./lib/vue%20(1).js"></script>
<body>
<div id="box">
<input type="text" v-model="msg">
<br/>
{{msg}}
</div>
</body>
<script>
window.onload= function () {
var vm=new Vue({
el:'#box',//可以挂在到Class 或者id选择器或者标签
data:{
msg:'宝剑锋从磨砺出,梅花香自苦寒兰'
}
})
}
</script>
</html>
结合案例:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<script src="./lib/vue%20(1).js"></script>
<script type="text/javascript"></script>
<body>
<div id="box"></div>
<script>
var vm=new Vue({
el:'#box',
template:`
<div>
<ul>
<li>{{text1}}</li>
<li>{{text2}}</li>
</ul>
<input type="text" v-model="text2">
</div>
`,
data:{
text1:'abc',
text2:'123'
}
})
</script>
</body>
</html>
v-for
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<script src="./lib/vue%20(1).js"></script>
<script type="text/javascript"></script>
<body>
<div id="app"></div>
<script>
var App={
template:`
<div>
数组
<ul>
<li v-for="(hero,index) in heros" :key="index">
{{hero.name}} {{index}}
</li>
</ul>
对象
<ul>
<li>值 | key | 索引</li>
<li v-for="(value,key,index) in person ":key="index">
{{value}}{{key}}{{index}}
</li>
</ul>
</div>
`,
data: function () {
return{
heros:[{id:1 , name:'小京京'},{id:2 , name:'小凯文'},{id:3 , name:'小宝宝'}],
person:{
a:1,
b:2
}
}
}
}
new Vue({
el:'#app',
render: function (c) {
return c(App);
}
})
</script>
</body>
</html>
//vue是根据当前指定值使用一定的算法,计算,算出一个元素的唯一标识,给定key,则节省了运算标识的消耗.
处理用户输入
为了让用户和你的应用进行交互,我们可以用 v-on 指令添加一个事件监听器,通过它调用在 Vue 实例中定义的方法:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<script src="./lib/vue%20(1).js"></script>
<script>
window.onload= function () {
var app=new Vue({
el:'.box',
data:{
msg:'helloword'
},
methods:{
reversemsg:function(ev){
this.msg=this.msg.split('').reverse().join(''),
console.log(ev.clientX)
}
}
})
}
</script>
<body>
<div class="box">
<p>{{msg}}</p>
<button v-on:click="reversemsg($event)">反转信息</button> //v-on:click可以简写成为@click
//@click.stop(阻止冒泡) 或者ev.cancelBubble=true;
//@click.prevent(阻止默认事件)或者ev.preventDefault();
</div>
</body>
</html>
键盘事件
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<script src="./lib/vue%20(1).js"></script>
<script>
window.onload= function () {
var app=new Vue({
el:'.box',
data:{
msg:''
},
methods:{
show:function(ev){
alert("回车键被敲击了")
}
}
})
}
</script>
<body>
<div class="box">
<input type="text" @keyup.13="show">
//@keydown.enter 后面可以是键码或者是具体的名称
</div>
</body>
</html>
模板
一次性绑定 v-once
<div id="app">
<p v-once>{{once}}</p>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
once: 'once content'
}
});
app.once = 'changed content';
</script>
不进行 html 转义
<div id="app">
<p v-html="html">不转义的绑定(直接输出 html)</p>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
html: '<div>div element</div>'
}
});
</script>
render属性
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<script src="./lib/vue%20(1).js"></script>
<script type="text/javascript"></script>
<body>
<div id="app"></div>
<script>
var App={
template:`
<div>
<ul>
<li>{{text1}}</li>
<li>{{text2}}</li>
</ul>
</div>
`,
data: function () {
return{
text1:'abc',
text2:'123'
}
}
}
new Vue({
el:'#app',
render:function(createElement){
return createElement(App);
}
})
//简洁版1
// new Vue({
// el:'#app',
// render:function(c){
// return c(App);
// }
// })
//简洁版2
// new Vue({
// el:'#app',
// render: c => c(App)
// })
</script>
</body>
</html>
//var App= {};等同于 var App=Vue.extend ({});(语法糖)
v-text
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<script src="./lib/vue%20(1).js"></script>
<script type="text/javascript"></script>
<body>
<div id="app"></div>
<script>
var App={
template:`
<span v-text="vtext"></span>
`,
data: function () {
return{
vtext:'<h1>快乐老家</h1>'
}
}
}
new Vue({
el:'#app',
render: function (c) {
return c(App);
}
})
</script>
</body>
</html>
//元素的innerText ,只能是双标签,不会解析标签
v-html
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<script src="./lib/vue%20(1).js"></script>
<script type="text/javascript"></script>
<body>
<div id="app"></div>
<script>
var App={
template:`
<span v-html="vhtml"></span>
`,
data: function () {
return{
vhtml:'<h1>快乐老家</h1>'
}
}
}
new Vue({
el:'#app',
render: function (c) {
return c(App);
}
})
</script>
</body>
</html>
//元素的innerHtml ,只能是双标签 , 会解析标签
v-if与v-else
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<script src="./lib/vue%20(1).js"></script>
<script type="text/javascript"></script>
<body>
<div id="app"></div>
<script>
var App={
template:`
<p v-if="isAble">这段话不会存在</p>
<p v-else>这段话会存在</p>
`,
data: function () {
return{
isAble:false
}
}
}
new Vue({
el:'#app',
render: function (c) {
return c(App);
}
})
</script>
</body>
</html>
漂亮的列表案例
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
.sss{
background-color: mediumvioletred;
}
.ss{
background-color: cadetblue;
}
.s{
background-color: black;
}
</style>
</head>
<script src="./lib/vue%20(1).js"></script>
<script type="text/javascript"></script>
<body>
<div id="app"></div>
<script>
var App={
template:`
<div>
排名颜色
<ul>
<li v-for="(hero,index) in heros" :key="heros.id" :class="{SSS:'sss',SS:'ss',S:'s'} [hero.level]">
{{hero.name}} {{hero.level}}
</li>
</ul>
奇偶变色
<ul>
<li v-for="(hero,index) in heros" :key="heros.id" :class="index%2==0?'sss':'s'">
{{hero.name}} {{hero.level}}
</li>
</ul>
`,
data: function () {
return{
heros:[{id:1 , name:'小京京',level:'SSS'},
{id:2 , name:'小凯文',level:'S'},
{id:3 , name:'小宝宝',level:'SS'}],
}
}
}
new Vue({
el:'#app',
render: function (c) {
return c(App);
}
})
</script>
</body>
</html>
// 在做:class 就等于v-bind:class
- 在内部就可以随意的获取data下面的属性,从而来做判断
* 设置了一个`{变量值:'样式1',变量值:'样式2'}[hero.level]`
* class:
- 取其一
+ 三元表达式,最终返回字符串
+ 从对象中通过key去取值,最终返回字符串
- 取多个样式 (样式1 样式2)
+ 对象的方式 `{样式1:true,样式2:true}`
components
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<script src="./lib/vue%20(1).js"></script>
<script type="text/javascript"></script>
<body>
<div id="app"></div>
<script>
var Header={
template:`
<div style="background-color:red; height: 200px">
</div>
`
}
var Body={
template:`
<div style="background-color:greenyellow; height: 400px">
</div>
`
}
var Footer={
template:`
<div style="background-color:blanchedalmond; height: 100px">
</div>
`
}
var App={
template:`
<div>
<header-vue></header-vue>
<body-vue></body-vue>
<footer-vue></footer-vue>
</div>
`,
components:{
'header-vue':Header,
'body-vue':Body,
'footer-vue':Footer
}
}
new Vue({
el:'#app',
render: function (c) {
return c(App);
}
})
</script>
</body>
</html>
webpack(打包工具)
webpack 入口文件 出口文件
`webpack ./main.js ·/build.js`
webpack.png
webpack模块化开发
项目目录
components.png
代码结构
index.html代码
<html>
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div id="app"></div>
<script src="../vue.js"></script>
<script src="./build.js"></script>
</body>
</html>
main.js代码
//启动vue
var Vue = require('../vue.js');
var App= require('./App.js');
new Vue({
el:'#app',
render:c=>c(App)
})
App.js代码
/ /入口组件
var HeaderVue=require('./HeaderVue.js');
var BodyVue=require('./BodyVue.js');
var FooterVue=require('./FooterVue.js');
module.exports = {
template:`
<div>
<header-vue></header-vue>
<!--我是App组件-->
<body-vue></body-vue>
<footer-vue></footer-vue>
</div>
`,
components:{
'header-vue':HeaderVue,
'body-vue':BodyVue,
'footer-vue':FooterVue
}
}
Header代码
//头组件
module.exports = {
template:`<div style="background-color:red;height:150px">
我是头
</div>`
}
Body代码
//中间组件
module.exports = {
template:`<div style="background-color:yellowgreen;height:400px">
我是主体内容,新闻联播,现在开始......
</div>`
}
Footer代码
//底部组件
module.exports= {
template:`<div style="background-color:skyblue;height:150px">
版权所有、违者必究
</div>`
}
//首先安装webpack 首先命令行cd到当前目录下,使用npm命令行安装 webpack $npm i -g webpack 安装成功之后进入到当前文件命令行,
webpack ./main.js ./build.js 之后我们把引入的main文件换成build文件
·
代码结构
index.html代码
<html>
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div id="app"></div>
<script src="./build.js"></script>
</body>
</html>
main.js代码
//启动vue
var Vue = require('../vue.js');
var App= require('./App.js');
var Header=require('./HeaderVue.js')
var Body=require('./BodyVue.js')
var Footer=require('./FooterVue.js')
Vue.component('header-vue',Header);
Vue.component('body-vue',Body);
Vue.component('footer-vue',Footer);
new Vue({
el:'#app',
render:c=>c(App)
})
App.js代码
/ /入口组件
module.exports = {
template:`
<div>
<header-vue></header-vue>
<!--我是App组件-->
<body-vue></body-vue>
<footer-vue></footer-vue>
</div>
`
}
Header代码
//头组件
module.exports = {
template:`<div style="background-color:red;height:150px">
我是头
</div>`
}
Body代码
//中间组件
module.exports = {
template:`<div style="background-color:yellowgreen;height:400px">
我是主体内容,新闻联播,现在开始......
</div>`
}
Footer代码
//底部组件
module.exports= {
template:`<div style="background-color:skyblue;height:150px">
版权所有、违者必究
</div>`
}
//每次修改东西之后需要重新build
父向子传递值
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<script src="./vue.js"></script>
<body>
<div id="app"></div>
<script>
//子组件
var SubVue={
template:`
<span>{{msg}}</span>
`,
props:['msg']
}
//全局组件
Vue.component('sub-vue',SubVue);
//父组件
var App={
template:`
<div>
<sub-vue msg="我是中国人(父组件传递)"></sub-vue>
<sub-vue :msg="letter"></sub-vue>
</div>
`,
data(){
return {
letter:'我爱你'
}
}
}
new Vue({
el:'#app',
render:c=>c(App)
})
</script>
</body>
</html>
子向父传递值
<html>
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div id="app"></div>
<script type="text/javascript" src="../vue.js"></script>
<script type="text/javascript">
//App父 Sub 子
var Sub = {
template:`
<div style="background-color:yellowgreen">
我是子组件
<button @click="help">呼叫爹地</button>
</div>
`,
methods:{
help(){
//呼叫爸爸
// console.log(this);
this.$parent.$emit('helpme','路上有巫婆');
}
}
};
var App = {
template:`
<div style="background-color:hotpink">
我是父组件
<button @click="listen">孩子走啦,开始看电话</button>
<sub-vue></sub-vue>
</div>
`,
components:{
'sub-vue':Sub
},
methods:{
listen(){
var self = this;
//$on
//this 是实例 app
this.$on('helpme',function(msg){
console.log('宝宝说:'+msg);
console.log('抄家伙,冲出去');
console.log('不再听电话了');
//关闭事件
self.$off('helpme');
});
//
//也可以只触发一次
// this.$once('helpme',function(msg){
// console.log('宝宝说:'+msg);
// console.log('抄家伙,冲出去');
// });
}
}
};
//启动
new Vue({
el:'#app',
render:c=>c(App)
})
</script>
</body>
</html>
增删改查
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div id="app"></div>
</body>
<script src="../vue.js"></script>
<script>
var data=[
{id:'1',name:'黄忠'},{id:'2',name:'扁鹊'},{id:'3',name:'李元芳'}]
var Add={
template:`
<div>
<input type="text" v-model="id"><br/>
<input type="text" v-model="name"><br/>
<button @click="addHero">添加</button>
</div>
<button>删除</button>
`,methods:{
addHero(){
data.push({
id:this.id,
name:this.name
})
}
},
data(){
return{
id:'',
name:''
}
}
}
var List={
template:`
<div>
<ul>
<li v-for="(hero,index) in heros" :key="index">
{{hero.name}}
<button @click="del(hero.id)">删除</button>
</li>
</ul>
</div>
`,
data(){
return {
heros:data
}
},methods:{
del(id){
var index=data.findIndex(function (ele,index,arr) {
return ele.id==id;
});
data.splice(index,1);
}
}
}
var App={
template:`
<div>
我是App父组件
<list></list>
<add></add>
<button @click="change">更新</button>
</div>
`,
components:{
list:List,
add:Add
},methods:{
change(){
data[0].name='随便啦'
}
}
}
new Vue({
el:'#app',
render:c=>c(App)
})
</script>
</html>
过滤器
Vue.js 允许你自定义过滤器,可被用于一些常见的文本格式化。过滤器可以用在两个地方:双花括号插值和 v-bind 表达式 (后者从 2.1.0+ 开始支持)。过滤器应该被添加在 JavaScript 表达式的尾部,由“管道”符号指示:
创建 Vue 实例之前全局定义过滤器:(举例首字母大写过滤器)
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<script src="./lib/vue%20(1).js"></script>
<body>
<div id="box">
{{msg|capitalize}}
</div>
<script>
Vue.filter('capitalize', function (value) {
if (!value) return ''
value = value.toString()
return value.charAt(0).toUpperCase() + value.slice(1)
})
new Vue({
el:'#box',
data:{
msg:'helloworld'
}
})
</script>
</body>
</html>
·
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div id="app"></div>
<script src="../vue.js"></script>
<script>
var App={
template:`
<div>
<input type="text" v-model="msg">
{{msg | myfilter}}
</div>
`,
data(){
return{
msg:'123456'
}
},
filters:{
'myfilter': function (value) {
var newStr=value.split('').reverse().join('');
return newStr;
}
}
}
new Vue({
el:'#app',
render:c=>c(App)
})
</script>
</body>
</html>
全局过滤器
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div id="app"></div>
<script src="../vue.js"></script>
<script>
var App={
template:`
<div>
<input type="text" v-model="msg">
{{msg | myfilter}}
</div>
`,
data(){
return{
msg:'123456'
}
}
}
Vue.filter('myfilter', function (value) {
var newStr=value.split('').reverse().join('');
return newStr;
})
new Vue({
el:'#app',
render:c=>c(App)
})
</script>
</body>
</html>
watch
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div id="app"></div>
<script src="../vue.js"></script>
<script>
var App={
template:`
<div>
<input type="text" v-model="msg">
{{msg}}
<button @click="change">通过调用函数更改person.name</button>
{{person.name}}
</div>
`,
data(){
return{
msg:'123456',
person:{name:'jack'}
}
},
watch:{
'msg': function (newV,oldV) {
console.log("更改被监视到了",newV)
},
'person':{
handler: function (newV,oldV) {
console.log("更改监视",newV)
},
deep:true
}
},
methods:{
change(){
this.person.name="rose"
}
}
}
new Vue({
el:'#app',
render:c=>c(App)
})
</script>
</body>
</html>
//监视watch
//* 需求:
//- 监视一个值的改变,页面中的change事件
//* 监视单个data中的属性值的改变
//- 原始数据类型 watch:{ 属性名:fn }
//- 引用数据类型 watch:{ 属性名:{deep:true,handler:fn}
计算属性
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div id="app"></div>
<script src="./../vue.js"></script>
<script>
var App={
template:`
<div>
<input type="text" v-model="n1">+
<input type="text" v-model="n2">*
<input type="text" v-model="rate">=
{{numResult.money}}
</div>
`,
data(){
return{
n1:0,
n2:0,
rate:0
}
},
computed:{
'numResult': function () {
return{
money:((this.n1-0)+(this.n2-0))*this.rate//-0把字符串拼接变成number值
}
}
}
}
new Vue({
el:'#app',
render:c=>c(App)
})
</script>
</body>
</html>
生命周期
//生命周期
//* 实例:
// - 1: `new Vue()` vue的实例 (一个)
//- 2: 组件内的this对象,组件对象的实例 (多个)
//
//* 总结
//- beforeCreate 相比created数据还未初始化
//- created 相比mounted,还未生成DOM
//+ 可以发起ajax请求,获取数据,变更数据,来做装载
//- beforeMount
//- 装载中。。。。。生成DOM(包含数据)
//- mounted
//+ 可以操作DOM
//- created用来操作数据,mounted用来操作DOM
<html>
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div id="app"></div>
<script type="text/javascript" src="../vue.js"></script>
<script type="text/javascript">
// beforeCreate 创建之前(组件)
// created 创建之后
// beforeMount 装载之前(数据) = template + data 结合 + 放置到目的地
// mounted 装载之后
// 在正常顺序下不会触发的
// beforeUpdate 更新之前(组件数据)
// updated 更新之后
// activated 激活(组件)
// deactivated 停用(组件)
// beforeDestroy 销毁之前(组件)
// destroyed 销毁之后(组件)
var App = {
data(){
return {
text:'hello'
}
},
// beforeCreate(){ //10岁
// console.log(this.text); //undefined ,此时没有完成对数据的初始化
// // console.log('beforeCreate');
// },
created(){ //20岁
//console.log(this.text); //有数据,可以操作数据
//this.text = '大家好'; //模拟ajax请求获取数据
// console.log('created');
console.log(this.$refs.mydiv); //DOM还未生成,不能操作DOM
},
// beforeMount(){ //30岁
// console.log('beforeMount');
// },
mounted(){
//console.log('mounted');
console.log(this.$refs.mydiv); //可以操作DOM
},
template:`<div ref="mydiv">
我是App,{{text}}
</div>`
}
new Vue({
el:'#app',
render:c=>c(App)
})
</script>
</body>
</html>
获取元素
* 1: 在template模板中元素上加上 ref="xxx"
* 2: 在函数、或者mounted钩子函数中 获取: this.$refs.xxx 元素
- 如果ref="xxx" 是写在原生DOM元素上,获取的就是原生DOM元素
- 如果ref="xxx" 是放在组件标签上,获取的就是组件对象
内置组件
* keep-alive
- 可以将频繁插入和移除的元素,进行缓存,而无需重复的创建和销毁
- 其包裹的元素,就有这个效果,同时也会根据v-if不同的结果
- 触发 激活和停用事件,此2事件与 destroyed和created互斥
·
总结
* 事件的回调函数 = 钩子函数
* beforeCreate 创建之前(组件) 没有完成数据的初始化
* created 创建之后,可以操作数据(最佳) v-if="true"
* beforeMount 装载之前(数据) = template + data 结合 + 放置到 目的地
* mounted 装载之后,可以操作DOM,给dom元素添加一些事件, 修改某个DOM元素的显示
* 在正常顺序下不会触发的
* beforeUpdate 更新之前(组件数据),尽量少用
* updated 更新之后,尽量少用
* activated 激活(组件)配合keep-alive内置组件来使用,将组 件数据缓存到js内存中
* deactivated 停用(组件)配合keep-alive内置组件来使用
* beforeDestroy 销毁之前(组件) v-if="false"
* destroyed 销毁之后(组件)
* 创建、激活 根据v-if="true"来决定
* 销毁、停用 根据v-if="false"来决定
<html>
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div id="app"></div>
<script type="text/javascript" src="../vue.js"></script>
<script type="text/javascript">
// beforeCreate 创建之前(组件)
// created 创建之后
// beforeMount 装载之前(数据) = template + data 结合 + 放置到目的地
// mounted 装载之后
// 在正常顺序下不会触发的
// beforeUpdate 更新之前(组件数据)
// updated 更新之后
// activated 激活(组件)
// deactivated 停用(组件)
// beforeDestroy 销毁之前(组件)
// destroyed 销毁之后(组件)
var SubVue = {
template:`<div>
我是子组件
</div>`,
beforeDestroy(){
console.log('beforeDestroy');
},
destroyed(){ //杀猪 ,放猪
console.log('destroyed');
},
created(){ //买猪 ,关猪
console.log('created');
},
beforeCreate(){
console.log('beforeCreate');
},
activated(){
console.log('激活了activated');
},
deactivated(){
console.log('停用了deactivated');
}
}
//注册全局组件
Vue.component('sub-vue',SubVue);
var App = {
data(){
return {
text:'hello',
isAble:true
}
}
// ,
//更新后,不建议,做二次更新
// beforeUpdate(){
// console.log('beforeUpdate')
// },
// updated(){
// console.log('updated')
// }
,template:`<div ref="mydiv">
我是App,{{text}}
<button @click="change">更改Text的值</button>
<keep-alive>
<sub-vue v-if="isAble"></sub-vue>
</keep-alive>
<button @click="isAble = !isAble">销毁或常见子组件</button>
</div>`
,methods:{
change(){
this.text = 'abc';
}
}
}
new Vue({
el:'#app',
render:c=>c(App)
})
</script>
</body>
</html>
vue-router
//index.html
<html>
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div id="app"></div>
<!-- 引1个包 -->
<script type="text/javascript" src="./build.js"></script>
</body>
</html>
//main.js
//引入Vue
var Vue = require('../vue.js');
//引入VueRouter
var VueRouter = require('../vue-router.js');
var App = require('./App.js');
//安装插件
Vue.use(VueRouter); //挂载一些属性,供组件使用其功
//创建路由对象
var router = new VueRouter({
//配置路由规则
routes: [{
path: '/music',
component: { //组件内容,也可以引入
template: `
<div>
我是音乐,在人民广场吃炸鸡!
</div>
`
}
},{
path: '/movie',
component: { //组件内容,也可以引入
template: `
<div>
我是电影, 摔跤吧爸爸!
</div>
`
}
}]
});
//把路由对象交给vue
new Vue({
el:'#app',
router:router,
render:c=>c(App)
})
//App.js
module.exports = {
template:`
<div>
我是App主体
以下是变化的内容,留坑
<router-view></router-view>
</div>
`
}
router步骤
- 1: 引入对象
- `var VueRouter = require('vue-router/dist/vue-router.common.js');`
- 2: 安装插件 `Vue.use(VueRouter);`
+ 会给this(组件对象挂载一些对象,具备一些功能)
- 3:创建路由对象 `var router3 = new VueRouter(路由规则);`
- 4:配置路由规则 `routes:[ {path:'/home',component:Home } ] `
- 5:将配置好规则的路由对象交给Vue的实例构造函数参数中
+ `new Vue({ router:router3 })`
- 6: 留坑 `<router-view></router-view>`
*
router-link
//index.html
<html>
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div id="app"></div>
<script type="text/javascript" src="build.js"></script>
</body>
</html>
//main.js
var Vue = require('vue/dist/vue.common.js');
var VueRouter = require('vue-router/dist/vue-router.common.js');
var App = require('./App.js');
var Home = require('./Home.js');
var Music = require('./Music.js');
var Movie = require('./Movie.js');
//安装插件
Vue.use(VueRouter);
//创建路由对象
var router = new VueRouter({
routes:[
{ path:'/',component:Home }, //Home有头中底
{ path:'/music',component:Music },
{ path:'/movie',component:Movie },
]
});
new Vue({
el:'#app',
router,
render:c=>c(App)
})
//App.js
module.exports = {
template:`
<div>
我是App
<router-view></router-view>
</div>
`
}
//home.js
module.exports = {
template:`
<div>
<div style="background-color:hotpink;">
<!-- <a href="#/music">音乐</a>
<a href="#/movie">电影</a>
-->
<router-link to="/music">音乐</router-link>
<router-link to="/movie">电影</router-link>
</div>
<div style="background-color:yellowgreen;">正在热播....</div>
<div style="background-color:skyblue;">版权所有违者必究</div>
</div>
`
}
//music.js
module.exports = {
template:`
<div>
我是音乐
</div>
`
}
//movie.js
module.exports = {
template:`
<div>
我是电影
</div>
`
}
#### router-link
* vue-router内置组件,可以根据to的属性生成a标签及其href,让我们不用担心是#还 是#!等等等。。
* `<a href="#!/xxxx">xxx</a>`
* `<router-link to="/xxxx">xxx</router-link>`
router-named
//index.html
<html>
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<!-- <router-link to="/music">音乐</router-link>
<router-link :to="{ name:'music' }" >音乐</router-link> -->
<div id="app"></div>
<script type="text/javascript" src="build.js"></script>
</body>
</html>
//App.js
module.exports = {
template:`
<div>
我是App
<router-view></router-view>
</div>
`
}
//home.js
module.exports = {
template:`
<div>
<div style="background-color:hotpink;">
<router-link :to=" {name:'music'} ">音乐</router-link>
<router-link :to=" {name:'music'} ">音乐</router-link>
<router-link :to=" {name:'music'} ">音乐</router-link>
<router-link :to=" {name:'movie'} ">电影</router-link>
<router-link :to=" {name:'movie'} ">电影</router-link>
<router-link :to=" {name:'movie'} ">电影</router-link>
</div>
<div style="background-color:yellowgreen;">正在热播....</div>
<div style="background-color:skyblue;">版权所有违者必究</div>
</div>
`
}
//main.js
module.exports = {
template:`
<div>
<div style="background-color:hotpink;">
<router-link :to=" {name:'music'} ">音乐</router-link>
<router-link :to=" {name:'music'} ">音乐</router-link>
<router-link :to=" {name:'music'} ">音乐</router-link>
<router-link :to=" {name:'movie'} ">电影</router-link>
<router-link :to=" {name:'movie'} ">电影</router-link>
<router-link :to=" {name:'movie'} ">电影</router-link>
</div>
<div style="background-color:yellowgreen;">正在热播....</div>
<div style="background-color:skyblue;">版权所有违者必究</div>
</div>
`
}
//mocie.js
module.exports = {
template:`
<div>
我是电影
</div>
`
}
//music.js
module.exports = {
template:`
<div>
我是音乐
</div>
`
}
#### 命名路由
* 通过name属性去寻找路由规则,获取其path属性,作为a标签的href属性
* 生成:
- 操作 `<router-link :to=" {name:'bj'} "` (去哪里玩呢?)
- 规则 ` { name:'bj',path:'/beijing',component:BeiJing} ` (导航)
- 生成 `根据name属性找到对象,获取path生成a的href`
+ `#/beijing`
* 减少维护URL的成本
#### 关于属性赋值的总结
* 常量赋值: 不绑定属性,直接给值 xxx='abc'
* 变量赋值: 绑定属性 :xxx="变量名"
查询字符串的显示
//index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app"></div>
<script src="build.js"></script>
</body>
</html>
//App.js
module.exports={
template:`
<div>
<router-view></router-view>
</div>
`
}
//main.js
var Vue = require('vue/dist/vue.common.js');
var VueRouter = require('vue-router/dist/vue-router.common.js');
//通过加载的相对路径获取绝对路径
// console.log( require.resolve('vue-router') );
var App = require('./App.js');
var List = require('./List.js');
var Detail = require('./Detail.js');
//安装插件
Vue.use(VueRouter);
//创建路由对象
var router = new VueRouter({
routes:[
{ path:'/',component:List },
{ name:'detail',path:'/detail',component:Detail},
{ name:'detail2',path:'/detail2/test/:myid',component:Detail}
]
});
//启动vue
new Vue({
el:'#app',
router,
render:c=>c(App)
})
//Detail.js
module.exports = {
template:`
<div>
我是详情
</div>
`,
data(){
return {
text:''
}
},
// beforeCreate(){
// this.text = 'abc'; //undefined
// //获取路由参数,并显示在页面
// }
//完成数据观察
created(){
console.log(this.$route.query);
// 1:去哪里 {name:'detail2',params:{myid:hero.id} }
//2:导航{ name:'detail2',path:'/detail2/test/:myid',component:Detail}
console.log(this.$route.params );
}
}
//List.js
module.exports = {
template:`
<div>
查询字符串
<ul>
<li v-for="(hero,index) in heros" :key="hero.id" >
{{hero.name}} <router-link :to=" {name:'detail',query:{id:hero.id} } " >查看详情</router-link>
</li>
</ul>
<hr/>
路径方式
<ul>
<li v-for="(hero,index) in heros" :key="hero.id" >
{{hero.name}} <router-link :to=" {name:'detail2',params:{myid:hero.id} } " >查看详情</router-link>
</li>
</ul>
</div>
`,
data(){
//干掉:function,this指向一致
return {
heros:[ {id:1,name:'小粑粑'} ,{id:2,name:'大雄'},{id:3,name:'胖虎'}]
}
}
}
String.png
path.png
多视图
//index.html
<html>
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div id="app"></div>
<script type="text/javascript" src="build.js"></script>
</body>
</html>
//main.js
var Vue = require('../vue.js');
var VueRouter = require('../vue-router.js');
var App = require('./App.js');
var HeaderVue = require('./HeaderVue.js');
var BodyVue = require('./BodyVue.js');
var FooterVue = require('./FooterVue.js');
//全局组件
// Vue.component('header-vue',HeaderVue);
// Vue.component('body-vue',BodyVue);
// Vue.component('footer-vue',FooterVue);
//安装插件
Vue.use(VueRouter);
//创建路由对象
var router = new VueRouter({
routes:[
{
path:'/',components: {
'a':FooterVue,
'b':HeaderVue,
'default':BodyVue
}
}
]
});
new Vue({
el:'#app',
router,
render:c=>c(App)
})
//App/jsmodule.exports = {
template:`
<div>
<router-view name="a"></router-view>
<router-view name="b"></router-view>
<router-view></router-view>
</div>
`,
}
//Header Body Footer
module.exports = {
template:`
<div>
头部/中部/底部
</div>
`
}
#### 多视图(命名视图)
* 更为灵活的维护,灵活的配置修改显示的效果
* 区分component和components
- component填一个坑 组件对象
- components填多个坑 是一个对象`{坑名:组件}`
嵌套路由 与页面的重定向和404
//index.html
<html>
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div id="app"></div>
<script type="text/javascript" src="build.js"></script>
</body>
</html>
//main.js
var Vue=require('../vue.js');
var VueRouter=require('../vue-router.js');
var App=require('./App.js');
var Home=require('./Home.js');
var Music=require('./Music.js');
var Movie=require('./Movie.js');
var NotFount=require('./NotFount.js')
Vue.use(VueRouter);
var router=new VueRouter({
routes:[
{path:'/',redirect:'/home'},//页面的重定向 一开始默认进入页面时显示的页面 redirect:'/home'
{path:'*',component:NotFount},//当页面404的时候显示的友好页面
{name:'home',path:'/home',component:Home,
children:[
{name:'home.music',path:'music',component:Music},
{name:'home.movie',path:'movie',component:Movie}
]
}]
});
new Vue({
el:'#app',
router:router,
render:c=>c(App)
})
//App.js
module.exports = {
template:`
<div>
<router-view></router-view>
</div>
`
}
//Home.js
module.exports = {
template:`
<div>
欢迎来到首页
<router-link :to="{ name:'home.music'}">音乐</router-link>
<router-link :to="{ name:'home.movie'}">电影</router-link>
<hr/>
<router-view></router-view>
</div>
`
}
//Movie/Music.js
module.exports = {
template:`
<div>
music / movie
</div>
`
}
//NOtFount.js
/**
* Created by Administrator on 2018/2/28.
*/
module.exports = {
template:`
<div>
您要找的页面去旅行了
</div>
`,
}
#### 嵌套路由
* 案例
- 进入我的主页显示:电影、歌曲
* 1: 视图包含视图(保证坑)
* 2: 路由包含子路由 (锚点值)
- 父子路由都要映射组件 (显示内容)
### 重定向及404
* 404:所有规则都匹配不上,最后一条生效
* 路由规则对象中,有属性redirect
* `{ redirect:{ name:'xxx'} } ` 一般写在规则的前面,跳转的写在其后面
编程导航
//index.html
<html>
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div id="app"></div>
<script type="text/javascript" src="build.js"></script>
</body>
</html>
//main.js
var Vue = require('vue/dist/vue.common.js');
var VueRouter = require('vue-router/dist/vue-router.common.js');
var App = require('./App.js');
var Home = require('./Home.js');
//安装插件
Vue.use(VueRouter);
//创建路由对象
var router = new VueRouter({
routes:[
{ name:'home', path:'/home',component:Home},
]
});
new Vue({
el:'#app',
router,
render:c=>c(App)
})
//App.js
module.exports = {
template:`
<div>
<button @click="$router.go(1)">下一页</button>
输入: <input type="text" @change="change" v-model="hash" />
<router-view></router-view>
</div>
`,
methods:{
change(){
if(this.hash != '123456'){
//密码错误,不给予跳转
alert('操作失败!');
}else{
//$route 获取信息 $router 行为操作
this.$router.push({
name:'home'
}); //改变锚点值,跳转到/home
}
}
},
data(){
return {
hash:''
}
}
}
//home.js
module.exports = {
template:`
<div>
<button @click="goBack">返回默认页</button>
我是首页
</div>
`,
methods:{
goBack(){
//借助history历史记录
this.$router.go(-1);
}
}
}
#### 编程式导航
* 改变锚点 `this.$router.push({ name:'xx' })`
* 根据历史记录跳转 `this.$router.go(-1||1);` 前进或后退
webpack:
使用配置文件设置出入口
//index.html
<html>
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<script type="text/javascript" src="build.js"></script>
</body>
</html>
//main.js
var cal = require('./cal.js');
console.log(cal.add(8,7));
//cal.js
module.exports = {
add(n1,n2){
return n1 + n2;
}
}
//weboack.config.js
// 运行的环境是node
'use strict';
module.exports = {
//配置对象
entry:{//入口
//入口之一
'test1233':'./main.js'
},
//出口(产出)
output:{
//生成的js文件名
filename:'./build.js'
}
}
css-loader
首先我们在文件打开命令行 npm i css-loader style-loader -D
//index.html
<html>
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<script type="text/javascript" src="build.js"></script>
</body>
</html>
//index.css
body{
background-color: yellowgreen;
}
//main.js
require('./index.css');
//webpack.config.js
module.exports = {
entry:{
'main':'./main.js'
},
output:{
filename:'./build.js'
},
//模块,对象
module:{
//一堆加载器 loaders
loaders:[
//解析css
{
//匹配条件 './index.css'
test:/\.css$/, //以.css结尾的文件
loader:'style-loader!css-loader',
//代码顺序是1,2 执行顺序 2,1,顺序不要搞凡
}
]
}
}
less-loader
首先我们在文件打开命令行 npm i less-loader less -D
//index.html
<html>
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<script type="text/javascript" src="build.js"></script>
</body>
</html>
//index.less
@color:skyblue;
body{
background-color: @color;
}
//main.js
require('./index.less');
//webpack.config.js
module.exports = {
entry:{
'main':'./main.js'
},
output:{
filename:'./build.js'
},
//模块,对象
module:{
//一堆加载器 loaders
loaders:[
//解析css
{
//匹配条件 './index.css'
test:/\.css$/, //以.css结尾的文件
loader:'style-loader!css-loader',
//代码顺序是1,2 执行顺序 2,1,顺序不要搞凡
},
{
test:/\.less$/,
loader:'style-loader!css-loader!less-loader',
}
]
}
}
解析文件
//首先我们 npm i url-loader file-loader -D
//webpack.cpnfig.js
module.exports = {
entry:{ //入口
'main':'./src/main.js'
},
output:{ //产出
path:'./dist', //输出目录 使用好像会报错 现在不能用了好像
filename:'build.js' //js文件名
},
//模块,对象
module:{
//一堆加载器 loaders
loaders:[
//解析css
{
//匹配条件 './index.css'
test:/\.css$/, //以.css结尾的文件
loader:'style-loader!css-loader',
//代码顺序是1,2 执行顺序 2,1,顺序不要搞凡
},
{
test:/\.less$/,
loader:'style-loader!css-loader!less-loader',
},
{
//通过url-loader来依赖file-loader
//如果url-loader满足条件,则将文件生成base64编码
//如果url-loader不满足条件,则新生成原文件
test:/\.(jpg|png|svg|ttf|gif)$/,
loader:'url-loader?limit=4096&name=[name].[ext]', //依赖file-loader内部由url来判断调用
//limit=4096 资源再4096btye以下生成base64,以上则生成文件
//[name].[ext] 原名.原后缀名
}
]
}
}
//src/index.html
<html>
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<script type="text/javascript" src="build.js"></script>
</body>
//src/index.css
body{
background-image: url('./1.jpg');
}
//src/main.js
require('./index.css');
#### 处理文件 + base64
* 将文件以base64加密,好处:减少请求次数
* 图片在经过加密后,会在原大小基础上,增加三分之一左右
* 应用场景:
- 针对不大的图片,而频繁需要使用的场景
- 4096b 4kb
特殊符号
* 字符串内存在! 代表分隔多个
* 字符串内存在? 代表参数 ?key=value&key=value
* 字符串内& 还是并且的意思
字符串内使用的内置变量
* 在字符串内使用`[name]` 文件的原名
* `[ext]` 文件原后缀名
* output:{}
- path 资源输出路径
- filename js文件名
html插件
//首先我们 npm i html -webpack-plugin -D
//然后再次npm i webpack -D
//webpack.config.js
'use strict';
const htmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry:{ //入口
'main':'./src/main.js'
},
output:{ //产出
filename:'build.js' //js文件名
},
//模块,对象
module:{
//一堆加载器 loaders
loaders:[
//解析css
{
//匹配条件 './index.css'
test:/\.css$/, //以.css结尾的文件
loader:'style-loader!css-loader',
//代码顺序是1,2 执行顺序 2,1,顺序不要搞凡
},
{
test:/\.less$/,
loader:'style-loader!css-loader!less-loader',
},
{
//通过url-loader来依赖file-loader
//如果url-loader满足条件,则将文件生成base64编码
//如果url-loader不满足条件,则新生成原文件
test:/\.(jpg|png|svg|ttf|gif)$/,
loader:'url-loader?limit=4096&name=[name].[ext]', //依赖file-loader内部由url来判断调用
//limit=4096 资源再4096btye以下生成base64,以上则生成文件
//[name].[ext] 原名.原后缀名
}
]
},
plugins:[
//一堆插件中的一个,第一个执行
new htmlWebpackPlugin({
//参照模板
template:'./src/index.html'
})
]
}
#### 处理html
* npm i html-webpack-plugin -D
* 在配置文件中,引入这个对象
* 在webpack配置对象的根属性中,设置plugins:[ new 以上对象(options)]
* 插件数组元素的顺序,与代码的执行顺序一致
* `options:{ template:'./src/index.html' //参照物 }`
处理es6
//首先我们npm i babel-loader babel-core babel-preset-env babel-plugin-transform-runtime -D
//'use strict';
const htmlWebpackPlugin = require('html-webpack-plugin');
const path = require("path")
module.exports = {
entry:{ //入口
'main':'./src/main.js'
},
output:{ //产出
path:path.resolve("./dist"), //输出目录
filename:'build.js' //js文件名
},
//模块,对象
module:{
//一堆加载器 loaders
loaders:[
//解析css
{
//匹配条件 './index.css'
test:/\.css$/, //以.css结尾的文件
loader:'style-loader!css-loader',
//代码顺序是1,2 执行顺序 2,1,顺序不要搞凡
},
{
test:/\.less$/,
loader:'style-loader!css-loader!less-loader',
},
{
//通过url-loader来依赖file-loader
//如果url-loader满足条件,则将文件生成base64编码
//如果url-loader不满足条件,则新生成原文件
test:/\.(jpg|png|svg|ttf|gif)$/,
loader:'url-loader?limit=4096&name=[name].[ext]', //依赖file-loader内部由url来判断调用
//limit=4096 资源再4096btye以下生成base64,以上则生成文件
//[name].[ext] 原名.原后缀名
},
//处理js
{
test:/\.js$/,
loader:'babel-loader',
//排除node_modules目录
exclude:/node_modules/,
//设置语法预设、函数插件
options:{
//处理语法部分
presets:['env'],//处理es2015/2016/2017语法部分
plugins:['transform-runtime'],//处理函数部分
}
}
]
},
plugins:[
//一堆插件中的一个,第一个执行
new htmlWebpackPlugin({
//参照模板
template:'./src/index.html'
})
]
}
//main.js
let num = 1;
const num2 = 2;
let fn = ()=>{
return 1;
}
let num3 = Math.trunc(3.165);
console.log(num3);
new Promise(function(resolve,reject){
});
#### ES6
* const let Math.trunc
#### babel语法转换器
* es6/es7/react
* 设置语法 es6
* 通过插件设置 转换函数
* 通过webpack 将所有的js代码,进行转换,babel-loader,其依赖于babel-core
* 语法babel-preset-es2015(babel-preset-env:包含了所有(es6/es7/es8) )
- es2015/es2016/es2017
* 函数babel-plugin-transform-runtime
* babel-loader babel-core babel-preset-env babel-plugin-transform-runtime
引入vue
//首先倒入依赖包 npm i vue-template-compiler vue-loader -D
//index.html
<html>
<head>
<meta charset="UTF-8">
<title>单文件</title>
</head>
<body>
<div id="app"></div>
</body>
</html>
//main.js
const Vue = require('vue/dist/vue.runtime.common.js');
//App组件
const App = require('./App.vue').default; //以vue结尾的加上default
// module.exports = { default:{xxxx} } = export default App;
// console.log(App); //{ default:组件的options }
new Vue({
el:'#app',
render:c=>c(App)
});
//app.css
#d1{
background-color: yellowgreen;
}
//正常app.js用来对比app.vue
// css
require('./app.css');
module.exports = {
//HTML
template:`
<div id="d1">
我是App.js组件
</div>
`,
//jS
created(){
console.log('我是App.js组件 ');
}
}
//app.vue
<style>
#d2{
background-color: skyblue;
}
</style>
<template>
<div id="d2">
我是app.vue组件
</div>
</template>
<script>
module.exports = {
created(){
console.log('我是app.vue组件')
}
}
</script>
//webpack.cpnfig.js
'use strict';
const htmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry:{ //入口
'main':'./src/main.js'
},
output:{ //产出
path:'./dist', //输出目录
filename:'build.js' //js文件名
},
//模块,对象
module:{
//一堆加载器 loaders
loaders:[
//解析css
{
//匹配条件 './index.css'
test:/\.css$/, //以.css结尾的文件
loader:'style-loader!css-loader',
//代码顺序是1,2 执行顺序 2,1,顺序不要搞凡
},
{
test:/\.less$/,
loader:'style-loader!css-loader!less-loader',
},
{
//通过url-loader来依赖file-loader
//如果url-loader满足条件,则将文件生成base64编码
//如果url-loader不满足条件,则新生成原文件
test:/\.(jpg|png|svg|ttf|gif)$/,
loader:'url-loader?limit=4096&name=[name].[ext]', //依赖file-loader内部由url来判断调用
//limit=4096 资源再4096btye以下生成base64,以上则生成文件
//[name].[ext] 原名.原后缀名
},
//处理js
{
test:/\.js$/,
loader:'babel-loader',
//排除node_modules目录
exclude:/node_modules/,
//设置语法预设、函数插件
options:{
//处理语法部分
presets:['env'],//处理es2015/2016/2017语法部分
plugins:['transform-runtime'],//处理函数部分
}
},
{
//处理vue
test:/\.vue$/,
loader:'vue-loader', //依赖vue-template-compiler
}
]
},
plugins:[
//一堆插件中的一个,第一个执行
new htmlWebpackPlugin({
//参照模板
template:'./src/index.html'
})
]
}
#### 单文件方式
* 引包的方式(方式一)
- var 组件 = {}
* 浅尝webpack
- 解析commonjs (组件 + 模块的使用)
* 单文件方式(方式二)
- 以App.vue方式来编写代码 (结合webpack来编写)
- 主流方式
* 注意 在引入.vue的文件的时候,加上.default来获取options对象
* 原因在于 在vue-loader中,默认是以ES6导出的,而我们以commonjs引入的,
* 由于webpack最终会把es6转换成commonjs中的module.exports.default = App组件
总结
//index.html
<html>
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div id="app"></div>
</body>
</html>
//main.js
const Vue = require('../vue.js');
const VueRouter = require('../vue-routerjs');
// const VueRouter = require('vue-router').default;
//因为组件,是.vue文件,而其是被vue-loader加载,又因为,vue-loader向外导出的方式是es6的模块
//所以,我们require最终拿到的是 module.exports -> { default:对象 }
//ES6模块导出代码 export default 对象 ,es6模块导出,就是一个对象,default是其中的属性
const App = require('./App.vue').default;
const Home = require('./Home.vue').default;
//安装插件
Vue.use(VueRouter);
//创建路由对象
let router = new VueRouter({
routes:[
{ path:'/',redirect:{ name:'home'} },
{ name:'home',path:'/home',component:Home }
]
});
new Vue({
el:'#app',
router,
render:c=>c(App)
})
//Home.vue
<template>
<div>
我是home首页
</div>
</template>
<script>
module.exports = {
}
</script>
<style scoped>
/*让样式只在当前的Template中生效,可以在style上加上一个scoped*/
div{
background-color: hotpink;
}
</style>
//App.vue
<template>
<!-- 必须1个[根]节点 -->
<div>
我是app.vue啊啊啊
<router-view></router-view>
</div>
</template>
<script>
// 首先写上导出
module.exports = {
}
</script>
<style scoped>
/*让样式只在当前的Template中生效,可以在style上加上一个scoped*/
div{
background-color: yellowgreen;
}
</style>
//webpack.config.js
'use strict';
const path = require('path');
const htmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry:{
'main':'./src/main.js'
},
output:{
path:path.resolve('./dist'),
filename:'build.js'
},
module:{
loaders:[
//css
{
test:/\.css$/,
loader:'style-loader!css-loader'
},
//less
{
test:/\.less/,
loader:'style-loader!css-loader!less-loader'
},
//file
{
test:/\.(jpg|png|svg|gif)$/,
// loader:'url-loader?limit=4096&name=[name].[ext]'
loader:'url-loader',
options:{
limit:4096,
name:'[name].[ext]'
}
},
//js
{
test:/\.js$/,
loader:'babel-loader',
//排除掉node_modules
exclude:/node_modules/,
options:{
presets:['env'], //转换语法关键字
plugins:['transform-runtime'] //转换函数
}
},
//vue
{
test:/\.vue/,
loader:'vue-loader'
}
]
},
//html
plugins:[
new htmlWebpackPlugin({
template:'./src/index.html'
})
]
}