vscode 快捷键
- ctrl + shift + p 打开搜索命令
- control + ` 吊起终端,关闭终端
vue指令
// v-once 绑定的内容只赋值一次,之后的赋值不会再改变
<h2 v-once>{{message}}</h2>
// v-html 他可以解析标签
<div v-html="url"></div>
js --> url:'<a href="http://www.baidu.com">百度一下</a>'
// v-text 展示文本内容,跟 {{}} 功能一样, v-text 会把标签内的内容全部覆盖,不会拼接。
<h2 v-text="message"></h2>
js --> message: '你好,世界!!!',
// v-pre 会把标签内的内容原封不动的展示出来,
<div v-pre>{{message}}</div>
js --> message:"hello world "
展示的内容依旧是 {{message}}
// v-cloak 防止插值闪烁, cloak 斗篷的意思
// 在vue 解析之前,标签中有一个 v-cloak 属性,
// 在vue 解析之后,标签中的v-cloak 属性会被删除掉
// 所以用css 把所有有v-cloak 属性的标签隐藏就可以达到防止标签闪烁的问题了
<style>
[v-cloak] {
display: none;
}
</style>
<h2 v-once v-cloak>{{message}}</h2>
<script>
setTimeout(() => {
let app = new Vue({
el: '#app',
data: {
message: '你好,世界!!!',
url: '<a href="http://www.baidu.com">百度一下</a>'
},
})
}, 1000);
</script>
- v-bind 绑定属性
// {{}} 绑定在小程序中可以绑定到属性,但是在浏览器中是不可以绑定到属性中的,只可以绑定到标签内容上。
<body>
<style>
.active{
color: red;
}
.line{
border-bottom: 1px solid #aaa;
}
.title{
text-align: center;
}
</style>
<div id='app'>
<img v-bind:src="imgUrl" alt="" />
<!-- v-bind 语法糖,加一个 “:” 就是 v-bind 的缩写 -->
<a :href="aHref">百度一下</a>
<!-- 写死的class 不会被动态绑定的 :class 覆盖,而是会两者兼顾就存在 -->
<h2 class="title" :class="active">hello world</h2>
<!-- 动态绑定class对象语法 -->
<!-- class 里可以绑定对象,类名:bool值 bool值为true 时就绑定上这个类,为false 时就不绑定这个类 -->
<h2 :class="{active:isActive,line:isLine}">hello world</h2>
<!-- 按钮点击变红变黑 -->
<button v-on:click="btnClick">按钮</button>
<!-- 动态绑定 class 方法 -->
<h2 :class="getClass()">你好世界</h2>
<!-- 动态绑定 class 数组 也可以用数组返回,就不写例子了-->
<h2 :class="[active,line]">哈哈哈</h2>
<!-- 动态绑定 style 对象绑定 {属性名:属性值} 注意:属性值是需要用单引号括起来的,否则vue 会把他当做变量使用,key值使用驼峰命名法,有短杠连接有的时候不太好使-->
<div :style="{color:'#df2ab1',fontSize:'30px',borderBottom:borderBot}">烽火戏诸侯</div>
</div>
<script src='../js/vue.js'></script>
<script>
let app = new Vue({
el: '#app',
data: {
imgUrl:'https://img20.360buyimg.com/mobilecms/s144x144_jfs/t1/128237/27/1317/162369/5ebb98feEd1fe9033/6c0c1d20b7c4256b.jpg!q70.jpg',
aHref:'http://www.baidu.com',
active:'active',
isActive:true,
isLine:true,
borderBot:'2px solid #aaa'
},
methods:{
btnClick(){
this.isActive = !this.isActive
},
getClass(){
return {active:this.isActive,line:this.isLine}
}
}
})
</script>
</body>
- computed 计算属性
<body>
<div id='app'>
<h2>{{fullName}}</h2>
<h2>{{allName}}</h2>
</div>
<script src='../js/vue.js'></script>
<script>
let app = new Vue({
el: '#app',
data: {
firstName:"Lebron",
lastName:"James"
},
computed:{
// 计算属性是缓存到内存中的,在内容不变的情况下只会执行一次,比方法更高效
fullName:function(){
return this.firstName + ' ' + this.lastName
},
allName:{
// 计算属性的 set方法
set:function(newValue){
return "你改你妹"
},
// 计算属性的get 方法
get:function(){
return this.firstName + ' ' +'say hello to'+ ' ' + this.lastName
}
}
}
})
</script>
</body>
- 小知识:ES5 中,if ,for 是没有块级作用域的,只有 function 有块级作用域。
ES6中,let 变量是有if,for 块级作用域的, - 小知识:const 定义常量必须赋值,const 定义的对象不能修改,但是,对象的属性可以修改。
- v-on 事件监听
<div id='app'>
<div>{{number}}</div>
<!-- 1,在事件监听的时候,2,方法没有传参数。满足这两个条件调用方法中的 “()” 才可以不添加。-->
<button v-on:click="add">按钮+</button>
<!-- v-on 语法糖,@ -->
<button @click="number--">按钮-</button>
<!-- 方法中有参数,调用的时候没传小括号,vue 会把浏览器默认的event 事件传入进去 -->
<button @click="btnClick2">按钮三</button>
<!-- 传 $event 就是把浏览器的 event事件传进去 -->
<button @click="btnClick3('abc',$event)">按钮4</button>
<div class="btn_div" @click="divClick">
<!-- 修饰符 .stop 阻止冒泡事件 -->
<button class="div_btn" @click.stop="btnClick"></button>
</div>
<div>
<form action="baidu">
<!-- 修饰符 .prevent 阻止表单自动提交,而是在自己的方法里处理事件 -->
<input type="submit" value="提交" @click.prevent="submitClick">
</form>
</div>
<div>
<!-- keyup 键盘点击弹起事件 -->
<!-- .enter 监听回车敲击 -->
<input type="text" @keyup.enter="keyup">
<!-- 监听第一次点击,只监听一次事件 -->
<button @click.once="clickOnce">一次点击</button>
</div>
</div>
- v-if ,v-else-if ,v-else , v-show 条件判断
<body>
<div id='app'>
<span v-if="isUser">
<!-- label 里的for 绑定到input 之后,点击label input 就会聚焦 -->
<label for="username" >用户账号</label>
<input type="text" id="username" placeholder="请输入用户账号" key="username">
</span>
<!-- 有一个问题当input 中输入了123 当点击切换的时候,换到下面的input 内还存在123 这个内容 -->
<!-- 这是因为vue 虚拟dom 在对比了页面变化之后,复用了上面的 input -->
<!-- 如果不想让他复用,就给input 加一个 key来保证input 不可被复用 -->
<span v-else>
<label for="userEmail">用户邮箱</label>
<input type="text" id="userEmail" placeholder="请输入用户邮箱" key="userEmail">
</span>
<button @click="isUser = !isUser">切换账户</button>
<!-- v-show 显示还是隐藏只是改变display:none; 节点还在 -->
<!-- v-if 是把整个节点都删除了,当显示隐藏的切换频率不高的话,用 v-if ,当频率很高的话用 v-show -->
<div v-show="isShow">你好啊</div>
</div>
<script src='../js/vue.js'></script>
<script>
let app = new Vue({
el: '#app',
data: {
isUser:true,
isShow:false
},
})
</script>
</body>
- vue 数组中那些改变是响应式的,哪些不是响应式的
<body>
<div id='app'>
<ul>
<li v-for="item in letters">{{item}}</li>
</ul>
<button @click="btnClick">按钮</button>
</div>
<script src='../js/vue.js'></script>
<script>
let app = new Vue({
el: '#app',
data: {
letters:['a','b','c','d']
},
methods:{
btnClick(){
// push 方法是响应式的,往数组里添加完元素页面就会改变 (push 可以一次加多个元素)
// this.letters.push('ddd','eee')
// pop 响应式,把数组最后的元素删除掉
//this.letters.pop()
// shift 响应式,把数组的第一个元素删除掉
// this.letters.shift()
// unshift 响应式,在数组最前面添加元素 (unshift 也可以一次加多个元素)
// this.letters.unshift('ddd')
// splice 响应式 删除,插入,替换元素
// this.letters.splice(2,0,'v','x','l')
// sort 排序 响应式
// this.letters.sort()
// reverse 反转 响应式
// this.letters.reverse()
// 通过索引值修改数组的元素 就不是响应式的,页面并不会发生变化
//this.letters[0] = 'ddd'
// vue 内部实现的修改对象某个属性,数组某个值的方法
Vue.set(this.letters,1,'bbbb')
}
}
})
</script>
</body>
- v-model 双向绑定
<body>
<div id='app'>
<!-- v-model 双向绑定input 标签,变量改变,输入框内的内容也变,输入内容变,变量跟着变 -->
<input type="text" v-model="message">
<!-- v-model 绑定 radio -->
<label for="male">
<!-- name相同 radio 会互斥,v-model绑定同一个变量,name就可以不传 -->
<input type="radio" id="male" name="sex" value="男" v-model="sexx">男
</label>
<label for="female">
<input type="radio" id="female" name="sex" value="女" v-model="sexx">女
</label>
<h2>您选择的性别是:{{sexx}}</h2>
<!-- v-model 绑定 checkbox 单选框 -->
<label for="xieyi">
<input type="checkbox" id="xieyi" v-model="agree">同意协议
</label>
<h2>您选择的是:{{agree}}</h2>
<!-- v-model 绑定 checkbox 多选框 -->
<label for="hobby">
<input type="checkbox" value="篮球" v-model="hobbies">篮球
<input type="checkbox" value="足球" v-model="hobbies">足球
<input type="checkbox" value="乒乓球" v-model="hobbies">乒乓球
<input type="checkbox" value="羽毛球" v-model="hobbies">羽毛球
</label>
<h2>您选择的爱好是:{{hobbies}}</h2>
<!-- v-model绑定 select 下拉选框 -->
<select name="f" id="fru" v-model="fruit">
<option value="苹果">苹果</option>
<option value="香蕉">香蕉</option>
<option value="梨">梨</option>
</select>
<!-- v-model绑定 select 下拉选框选多个 -->
<select name="f" v-model="fruits" multiple>
<option value="苹果">苹果</option>
<option value="香蕉">香蕉</option>
<option value="梨">梨</option>
</select>
<!-- 值绑定概念,value 不是写死的了,可以动态的绑定 value的值 -->
<label v-for="item in originFurniture">
<input type="checkbox" :value="item" v-model="furnitures">{{item}}
</label>
<h2>您选择的家具是:{{furnitures}}</h2>
<!-- .lazy 修饰符,输入框不再时时绑定,而是等你敲回车或者,输入框失去焦点才会绑定 -->
<input type="text" v-model.lazy="content">
<h2>{{content}}</h2>
<!-- .number 把输入框中的string 类型自动转换成number 类型 -->
<input type="number" v-model.number="numInput">
<h2>{{typeof numInput}}-{{numInput}}</h2>
<!-- .trim 去掉输入框左右的空格,就不写例子了,vue 太**强了吧。 -->
</div>
<script src='../js/vue.js'></script>
<script>
let app = new Vue({
el: '#app',
data: {
message: '你好,世界!!!',
sexx:'男', // 默认绑定
agree:false, // 单选框
hobbies:[], // 多选框
fruit:"香蕉",// 下拉单选
fruits:[], // 下拉多选
originFurniture:["桌子","椅子","床","柜子"],
furnitures:[],
content:"你好啊",
numInput:0,
},
})
</script>
</body>
- 组件化开发1
<body>
<!--
组件开发三步骤,
1,Vue.extend()创建组件构造器
2,Vue.component()注册全局组件
3,在Vue实例的作用范围内使用组件
-->
<div id='app'>
<!-- 正常一个步骤不落的全局组件注册 -->
<my-cpn></my-cpn>
<!-- 正常一个步骤不落的局部组件注册 -->
<cpn></cpn>
<!-- 父子组件 -->
<fruist></fruist>
<!-- 全局组件语法糖 -->
<hello-world></hello-world>
<!-- 局部组件语法糖 -->
<part-components></part-components>
<!-- 使用javascript标签进行 模板抽离组件 -->
<tem-com></tem-com>
<!-- 使用template 标签进行模板抽离 -->
<template-cop></template-cop>
</div>
<template id="template-c">
<div>
<h2>我是template标签抽离的模板</h2>
<h6>你看是不是我最帅</h6>
</div>
</template>
<!-- 模板抽离,把 script 标签的type 设置成 text/x-template ,就可以引用id 当模板使用了 -->
<script type="text/x-template" id="tem-component">
<div>
<h2>我是被抽离的模板</h2>
<p>你看我好看吗</p>
</div>
</script>
<script src='../js/vue.js'></script>
<script>
const cpnC = Vue.extend({
template:`
<div>
<h2>我是标题</h2>
<p>我是标题啊</p>
<p>我是个p</p>
<p>你是个锤子</p>
</div>
`
})
// 全局组件,可以在多个vue 实例中引用
Vue.component('my-cpn',cpnC)
const ban = Vue.extend({
template:`
<p>香蕉</p>
`
})
const fruists = Vue.extend({
template:`
<div>
<h2>水果家族</h2>
<div>苹果</div>
<banada></banada>
</div>
`,
// 父组件里注册子组件
components:{
banada:ban,
}
})
// vue 语法糖注册全局组件
Vue.component('hello-world',{
template:`
<div>
<h2>hello your mother</h2>
</div>
`
})
Vue.component("tem-com",{
template:"#tem-component"
})
Vue.component("template-cop",{
template:"#template-c"
})
// vue 又被称为 root 组件
const app = new Vue({
el:'#app',
data:{
},
// 局部组件,只能在这一个vue 组件中使用
components:{
cpn:cpnC,
fruist:fruists,
// 局部组件语法糖
'part-components':{
template:`<div><h2>我是局部组件语法糖</h2></div>`
},
// "tem-com":"#tem-component"
},
methods:{
}
})
</script>
</body>
- 定义模板的时候必须有跟节点,就是必须写在<div></div>内
- 模板传值的时候,js 里变量是驼峰命名法的,在html文件上就用 “-” 连接每一个驼峰单词。
- 组件通信父传子
<body>
<div id='app'>
<!-- 组件绑定自己的数据,data 必须是个函数,切记 -->
<com-data></com-data>
<!-- 父组件往子组件传值A -->
<cpn :cmessage="message"></cpn>
<!-- 父组件往子组件传值B ctip 如果不传值就会显示默认的内容 -->
<cpn2 :cmovies="movies" :ctip="tip"></cpn2>
</div>
<!-- 演示组件自己绑定数据模板 -->
<template id="com">
<div>
<h2>{{title}}</h2>
<p>{{content}}</p>
</div>
</template>
<!-- 演示父组件往子组件传值模板A -->
<template id="porps">
<div>
<h2>{{cmessage}}</h2>
</div>
</template>
<!-- 演示父组件往子组件传值模板B -->
<template id="props2">
<div>
<h2>{{ctip}}</h2>
<ul>
<li v-for="item in cmovies">{{item}}</li>
</ul>
</div>
</template>
<script src='../js/vue.js'></script>
<script>
Vue.component("com-data",{
template:"#com",
// 组件里的data 必须是个返回函数,因为如果是对象的话,就会引起连锁反应,你改一个组件内的数据,再其他组件
// 也跟着改变,这点儿你应该懂得,深复制浅复制的道理。对象引用的逻辑,are you understand?
data(){
return{
title:"组件数据绑定",
content:"组件数据绑定的内容"
}
}
})
// 子组件A
let cpn = {
template:"#porps",
// props 可以是字符串数组里定义一些变量,在html模板上绑定父组件内的信息传递进来,之后就可以在自己的模板
// 上使用数据了
props:["cmessage"]
}
// 子组件B
let cpn2 = {
template:"#props2",
// props 可以是对象,规定传递的变量的类型,设置传递内容的默认值之类的。
props:{
// 数组或对象如果想设默认值的话,最好用函数return 返回,否则新版的vue 会报错
cmovies:{
type:Array,
default(){return [] } // 直接写 default:[],新版是不允许这个写的了。
},
ctip:{
type:String,
default:"我是个提示默认值",
required:true // 如果他为true则别人在用我这个组件的时候必须传这个变量,不传就会报错。
},
//以下说一下传参的类型,
// null 匹配任何类型
props1:Number,
// 多个可能的类型
props2:[Number,String],
// 自定义函数验证
props3:{
validator:function(value){
return ["success","hahh","hehe"].indexOf(value) !== -1
}
},
// 自定义Person类型验证
props4:Person,
}
}
function Person(name,age){
this.name = name
this.age = age
}
// 父组件
let app = new Vue({
el: '#app',
data: {
message: '你好,世界!!!',
movies:["海贼王","皮卡丘","哆啦A梦","东邪西毒"],
tip:"我给你传值了你敢显示默认内容?",
},
components:{
cpn,
cpn2
}
})
</script>
</body>
- 用 this.$children 可以拿到所有的子组件
- 给组件加上 ref = "aaa" 他就相当于给组件加了一个id 之后可以通过 this.$refs.aaa 精准获取到想要拿的组件了。
- 组件通信子传父
<body>
<div id='app'>
<!-- 这里这个cpnClick 如果不传参数,会默认组件抛出的item入参 -->
<cnp @itemclick="cpnClick"></cnp>
<button @click="clickforprint">打印子组件按钮</button>
</div>
<template id="temp">
<div>
<button v-for="item in categories" @click="btnClick(item)" >{{item.name}}</button>
</div>
</template>
<script src='../js/vue.js'></script>
<script>
const cnp = {
template:"#temp",
data(){
return{
categories:[
{id:"1",name:"热门推荐"},
{id:"2",name:"好物推荐"},
{id:3,name:"新品推荐"},
{id:4,name:"上衣推荐"}
]
}
},
methods:{
btnClick(item){
// emit 把组件的事件抛出去,在父级用 v-on 绑定事件就可以了。
this.$emit("itemclick",item)
// 子组件获得父组件,但是一般不建议这么用,因为会影响组件的复用性
console.log(this.$parent)
// 直接访问根组件,根vue里一般会放一些路由之类的东西,开发的时候还是需要用 $root 访问根vue 的
console.log(this.$root)
}
}
}
let app = new Vue({
el: '#app',
data: {
},
components:{
cnp,
},
methods:{
cpnClick(item){
console.log(item.name)
},
clickforprint(){
// 用 this.$children 可以拿到所有的子组件
console.log(this.$children)
// 给组件加上 ref = "aaa" 他就相当于给组件加了一个id 之后可以通过 this.$refs.aaa 精准
// 获取到想要拿的组件了。
console.log(this.$refs.aaa)
}
}
})
</script>
</body>
- 组件化的 slot 插槽
<body>
<div id='app'>
<temp>
<div>我预留的插槽</div>
</temp>
<!-- 具名插槽,指出要替换那个插槽 v-slot 只能使用在template 上,弃用的 slot 可以用到div 等其他标签上
弃用的用法可自行去vue官网上查看文档-->
<ntemp ><template v-slot:center>我替代了你的中间</template></ntemp>
<!-- 作用域插槽演练 :父组件里拿到子组件内的值-->
<!-- alangs.langs 一定要记住,是 . 的 模板上定义的 langs 属性 -->
<areatemp ref="aaa">
<template v-slot:areaslot="alangs">
<span v-for="item in alangs.langs">{{item}} -- </span>
</template>
</areatemp>
</div>
<template id="temp">
<div>
<h2>我是组件</h2>
<div>啊哈哈</div>
<!-- slot 里放个默认的按钮,之后如果使用的时候插槽内放东西了,就会替代这个默认的按钮 -->
<slot><button>按钮</button></slot>
</div>
</template>
<template id="ntemp">
<div>
<slot name="left"><span>左边</span></slot>
<slot name="center"><span>中间</span></slot>
<slot name="right"><span>右边</span></slot>
</div>
</template>
<template id="areatemp" >
<div>
<slot name="areaslot" :langs="languages">
<ul>
<li v-for="item in languages">{{item}}</li>
</ul>
</slot>
</div>
</template>
<script src='../js/vue.js'></script>
<script>
let app = new Vue({
el: '#app',
data: {
message: '你好,世界!!!'
},
components:{
temp:{
template:"#temp",
},
ntemp:{
template:"#ntemp"
},
areatemp:{
template:"#areatemp",
data(){
return{
languages:["javascript","Go","PHP","python","swift","flutter"]
}
}
}
}
})
</script>
</body>
- commenJS 制定规则模块规则 module.exports = {} 导出,let aa = require("../aa.js")导入
- es6 的模块的导入导出
// aa.js 文件
var name = "小明"
var flag = true
// 导出方式1
export let age = "18"
// 导出方式2
export{
flag
}
var obj = {
name:"李留",
age:10
}
// 默认导出的,再导入的时候名字可以随便起, 一个模块里只能有一个 default 导出
export default obj
// index.html 文件
<!-- 引用模块化的文件的时候需要把script 的 type 设置为 module -->
<script src="./aa.js" type="module"></script>
<script src="./bb.js" type="module"></script>
// bb.js 文件
// 导入 export 导出的
// import {flag,age} from "./aa.js"
// 导入 export default 导出的
// import person from "./aa.js"
// 把整个aa.js 模块导出的变量,函数,对象,全部导入
import * as aaa from "./aa.js"
// if(flag){
// console.log("我是你粑粑")
// console.log(age)
// }
// console.log(person.name)
console.log(aaa.age)
console.log(aaa.default.name)
- webpack
// 命令
// 打包,webpack 入口文件 出口文件
webpack ./src/main.js ./dist/bundle.js
// 初始化npm
npm init
// 导入npm 指定的包文件
npm install
// 配置一个webpack.config.js 文件,指定入口文件和出口文件,之后的打包命令就可以简写
// 为 webpack 而不需要带入口文件和出口文件了
// webpack.config.js 文件内的配置内容如下
const path = require("path")
module.exports = {
entry:"./src/main.js",
output:{
path:path.resolve(__dirname,"dist"),
filename:"bundle.js"
}
}
// 在package.json 配置文件内指定脚本 build 为webpack ,
// 之后就可以使用 npm run build 指代 webpack 打包进行打包了
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build":"webpack"
},
// 安装一个项目内的webpack ,webpack 是开发时依赖(上线的项目不需要webpack 了)
// 在终端敲webpack 都是用的全局的webpack ,影射到 build 命令上执行 npm run build 就会优先执行本地的webpack
npm install webpack@3.6.0 --save-dev
// webpack 打包css ,less 等其他除了js 文件之外的文件,需要合适的loader来
// 帮忙
npm install --save-dev css-loader
// css-loader 只负责将css文件加载,不负责渲染到界面,所以还需要加载一个style-loader
npm install style-loader --save-dev
// webpack.config.js 文件内加loader引用
// webpack 读取多个loader时,是从右往左读的,所以use数组才会这么写。
module:{
rules:[
{
test: /\.css$/,
use: [ 'style-loader','css-loader' ]
}
]
}
- webpack 中文翻译文档 https://www.webpackjs.com/loaders/style-loader/