代码拉取完成,页面将自动刷新
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" container="IE=edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no" />
<title>bilibili从入门到精通Vue</title>
<link rel="shortcut icon " type="images/x-icon" href="../favicon.ico" />
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<!--<script src="js/index.js"></script>-->
<style type="text/css">
[v-cloak]{ display:none; }
.active{ color:red; }
.blue{ color:blue; }
.linebg{ background:lightcyan; }
table{ border: 1px solid #d9d9d9; border-collapse: collapse; border-spacing: 0; empty-cells: show; }
th, td{ padding: 8px 16px; border: 1px solid #e9e9e9; text-align: left; }
th{ background: #f7f7f7; color: #5c6b77; font-weight: 600; white-space: nowrap; }
</style>
</head>
<body>
<div id="app" v-cloak>
<h3>当前计数:{{ counter }}</h3>
<button @click="add()"> + </button>
<button @click="sub()"> - </button>
<button @click="handleAddTen(10, $event)"> +10 </button>
<!--如果需要同时传入某个参数,还有event时,可以通过 $event 传入事件-->
<input-demo :content="content"></input-demo>
<input-demo :content="content"></input-demo>
<div>{{message}}</div>
<div v-once>{{message}}</div> <!-- v-once 只执行一次,后面没有表达式 -->
<div>{{url}}</div>
<div v-html="url"></div> <!-- v-html 可以解析HTML标签-->
<div>{{message}}</div>
<div v-text="message"></div> <!-- v-text 不想用{{大括号}}的时候,可以v-text一般不用,不够灵活。 -->
<div>{{message}}</div>
<div v-pre>{{message}}</div> <!-- v-pre类似于pre标签,当只想显示{{msg}},而不想显示其内容的时候用-->
<div>{{message}}</div>
<!--<div v-cloak=""></div>--> <!-- v-cloak 用得少。闪动,网络慢的时候,开始会显示{{msg}},解析以后才显示其内容,在div上加v-cloak,并设置[v-cloak]{display:none;}可以避免闪动-->
<img src="https://gw.alicdn.com/tfs/TB176rg4VP7gK0jSZFjXXc5aXXa-286-118.png" />
<img v-bind:src="imgUrl" /> <!-- v-bind 动态绑定属性 -->
<a :href="aHref">淘宝网,淘我喜欢</a>
<div :class="{active:isActive,linebg:isLine}">绑定class0</div>
<div :class="getClass()">绑定class</div>
<button v-on:click="btnClick()">按钮</button>
<!--v-on 修饰符 :
.stop 阻止冒泡
.prevent 阻止默认行为,例如a标签的跳转默认行为
.native 监听组件根元素的原生事件
.{keyCode键修饰符 | keyAlias键别名}例如.keyup.enter
.once-->
<ul> <!--点击那个,那个的文字变成红色-->
<li :class="{active:currentIndex == index}" @click="btnClick2(index)" v-for="(item,index) in movies">{{index}} -- {{item}}</li>
</ul>
<!--:style如果是对象,里边的 键值对 中的“键”可以用小驼峰,也可以用中划线; 键值对 中的“值”需要用引号,如果不用,会当成变量去加载,如果“值”还有单位的话,也需要字符串连起来,即 “ +‘单位’ ”-->
<div :style="{fontSize:'50px',color:blue}">{{message}}</div>
<div>{{firstName}} {{lastName}}</div>
<div>{{getFullName()}}</div>
<div>{{fullName}}</div>
<div v-if="books.length">
<table border="1" cellspacing="0">
<thead>
<tr>
<th></th>
<th>书籍名称</th>
<th>出版日期</th>
<th>价格</th>
<th>购买数量</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr v-for="(item,index) in books">
<td>{{item.id}}</td>
<td>{{item.name}}</td>
<td>{{item.date}}</td>
<td>{{item.price | showPrice}}</td> <!--<td>{{'¥' + item.price.toFixed(2)}}</td>--> <!--<td>{{result(item.price)}}</td>-->
<td>
<!--<button @click="reduceNum(index)" :disabled="item.num == 1">-</button>-->
<button @click="reduceNum(index)">-</button>
{{item.num}}
<button @click="addNum(index)">+</button>
</td>
<td><button @click="deleteTr(index)">移除</button></td>
</tr>
</tbody>
</table>
<h3>总价格:{{allPrice | showPrice}}</h3>
</div>
<div v-else><h3>购物车为空</h3></div>
<input v-if="change" type="text" key="name" placeholder="账号" />
<input v-else type="password" key="psw" placeholder="密码" /><button @click="change=!change">切换类型</button>
<!--v-model 相当于v-bind和v-on的结合-->
<input type="text" v-model="message" />
<input type="text" :value="message" @input="valueChange" />
<label><input type="radio" v-model="sex" id="male" value="男" />男性</label>
<label><input type="radio" v-model="sex" id="female" value="女" />女性</label>
<h3>选择的性别是:{{sex}}</h3>
<label><input type="checkbox" id="agree" v-model="agree" />同意协议</label>
<p><button :disabled="!agree">下一步</button></p>
<label><input type="checkbox" value="足球" v-model="hobbies" />足球</label>
<label><input type="checkbox" value="篮球" v-model="hobbies" />篮球</label>
<label><input type="checkbox" value="乒乓球" v-model="hobbies" />乒乓球</label>
<label v-for="item in originHobbies"><input type="checkbox" :value="item" v-model="hobbies"/>{{item}}</label>
<p>爱好:{{hobbies}}</p>
<select name="abc" id="" v-model="selected" multiple>
<option value="第一个">第一个</option>
<option value="第二个">第二个</option>
<option value="第三个">第三个</option>
</select>
<p>选择的是{{selected}}</p>
<select name="aabc" id="" v-model="fruit">
<option :value="item" v-for="item in fruit">{{item}}</option>
</select>
<p>选择的水果是{{selected}}</p>
<!--v-model 修饰符 lazy 等修改完以后再同步,而不是实时同步-->
<!--<input type="text" v-model.lazy="{{message}}" />-->
<!--v-model 修饰符 number 让输入的数字是Number类型,因为默认的是String类型的-->
<!--<input type="text" v-model.numver="{{counter}}" />-->
<!--v-model 修饰符 trim 剥除 输入内容前后有很多空格的时候,通常我们希望去除空格,trim就可以做到-->
<!--<input type="text" v-model.trim="{{message}}" />-->
<!--3 使用组件-->
<!--<cpn1></cpn1>
<cpn2></cpn2>
<hcpn></hcpn>
<hcpn2></hcpn2>
<ccppnn></ccppnn>
<h2>现在的数字是:{{total}}</h2>
<child-cpn @increment2="changeTotal" @decrement2="changeTotal"></child-cpn>-->
</div>
<!--<script type="text/x-template" id="cpn1">
<div>
<h4>h4标题哦哦哦</h4>
<p>h4内容噢噢噢噢噢噢噢噢</p>
</div>
</script>
<template id="cpn2">
<div>
template中的title,不能直接用定义的new Vue里的data里的title。
<h4>h42 {{ title }}</h4>
<p>h422222222222</p>
</div>
</template>
<template id="ccppnn">
<div>
<h5>当前记数:{{counter}}</h5>
<button @click="increment">+</button>
<button @click="decrement">-</button>
</div>
</template>
<template id="childCpn">
<div>
<button @click="increment2">+1</button>
<button @click="decrement2">-1</button>
</div>
</template>-->
<script>
Vue.component("inputDemo",{
props: ['content'],
template: `<input v-model="content.a">`
});
const hcpn = Vue.component('hcpn',{
template:'#cpn1'
});
//每个component都可以有data属性,但data必须是函数,必须返回的是对象,这个对象里边有需要的title等
const hcpn2 = Vue.component('hcpn2',{
template:'#cpn2',
data(){
return {title:'haha'}
}
});
const vm = new Vue({
el: '#app',
data: {
counter: 0,
total:0,
message:'hello world',
url:'<a href="https://www.baidu.com">百度一下</a>',
imgUrl:'https://gw.alicdn.com/tfs/TB176rg4VP7gK0jSZFjXXc5aXXa-286-118.png',
aHref:'https://www.taobao.com',
content: {
a: '双向绑定'
},
change:true,
isActive:false,
isLine:true,
movies:['海王','泰坦尼克号','速度与激情','花木兰','我和我的祖国','大鱼海棠'],
currentIndex:0,
blue:'blue',
firstName:'kobe',
lastName:'bryant',
books:[
{id:1,name:'算法导论',date:'2006-9',price:85.00,num:5},
{id:2,name:'UNIX编程艺术',date:'2006-2',price:59.00,num:1},
{id:3,name:'编程珠玑',date:'2008-10',price:39.00,num:1},
{id:4,name:'代码大全',date:'2006-3',price:128.00,num:1}
],
sex:'女性',
select:'第一',
agree:false,
originHobbies:['羽毛球','气球','火球','高尔夫球'],
hobbies:['羽毛球'],
selected:['第一个'], //当select是单选的时候,selected是一个值,当select是多选的时候,selected是一个数组
fruit:['苹果','香蕉','橘子','山竹','西瓜'],
},
methods:{
getFullName (){ return this.firstName + " " + this.lastName },
add (){ this.counter++;console.log('add被执行');},
sub (){ this.counter--;console.log('sub被执行');},
handleAddTen(count, event){ this.counter += count; console.log('handleAddTen被执行');},
btnClick (){ this.isActive = !this.isActive; },
getClass (){ return {active:this.isLine} },
btnClick2 (index){ this.currentIndex = index; },
result (price){ return '¥' + price.toFixed(2) },
reduceNum(index){ if(this.books[index].num > 1) {this.books[index].num -= 1;} else {alert('不能再减了'); } },
addNum(index){ this.books[index].num += 1; },
deleteTr(index){
let result = confirm("确定要删除吗?");
if(result == true){
this.books.splice(index,1)
}
},
changeTotal(counter2){ this.total = counter2 },
valueChange(event){ this.message = event.target.value },
},
computed:{//methods和computed都可以实现函数的调用,但是computed可以实现数据的缓存。如果用的多的用computed。
fullName:{
//每个属性都有一个getter,一个setter,一般情况下setter不使用;并且getter使用的时候,也省略get。
set:function(newValue){ //newValue是默认的存在的。
const name = newValue.slice(" ");
this.firstName = name[0];
this.lastName = name[1];
},
get:function(){
return this.firstName + " " + this.lastName;
}
},
allPrice(){
let result = 0;
for(let i in this.books){
result += this.books[i].price * this.books[i].num;
}
return result;
//第二种
//let result = 0;
//for(let item of this.books){
// result += item.price * item.num;
//}
//return result;
//第三种
//reurn this.books.reduce(function(pre,book){
// return pre + book.price * book.count
//},0)
}
},
//编程范式: 命令式编程/声明式编程
//编程范式: 面向对象编程(第一公民)/函数式编程(第一公民:函数)
filters:{
showPrice(price){ return '¥' + price.toFixed(2) }
},
//局部组件
components:{
cpn1:{
template:`
<div><h2>我是标题</h2><p>我是内容,哈哈哈哈</p></div>
`
},
cpn2:{
template:`
<div><h3>我是标题哦啊哈哈</h3><p>我是内容,嘤嘤嘤嘤嘤</p><cpn1></cpn1></div>
`,
components:{
cpn1:{
template:`
<div><h2>我是标题</h2><p>我是内容,哈哈哈哈</p></div>
`
}
}
},
childCpn:{
template:'#childCpn',
data(){
return {counter2:0}
},
methods:{
increment2(){
this.counter2++;
this.$emit('increment2',this.counter2);
},
decrement2(){
this.counter2--;
this.$emit('decrement2',this.counter2);
},
},
}
}
});
//组件
Vue.component('ccppnn',{
template:'#ccppnn',
data(){
return {counter:0}
},
methods:{
increment(){this.counter += 2 },
decrement(){this.counter -= 2 }
}
})
</script>
<div id="app_2">
<!--组件化的实现和使用步骤 全局组件 局部组件-->
全局组件 <my-cpn class="name1"></my-cpn>
<my-tem></my-tem>
局部组件 <h3cpn></h3cpn>
</div>
<script>
//全局组件 意味着可以在多个Vue的实例下使用
//1 创建组件构造器对象
const myComponent = Vue.extend({
template:`
<div>
<h2>my-cpn 组件标题1</h2>
<p>我是组件中的一个段落内容1</p>
</div>`
});
const myTemplate = Vue.extend({
template:`<div><h2>my-tem 标题标题2</h2><p>内容内容2</p></div>`
});
//2 注册组件
Vue.component('my-cpn',myComponent);
Vue.component('my-tem',myTemplate);
//3 使用组件
const h3cpn = Vue.extend({
template:`<span> s p a n <p>123</p></span>`
}); //template 后边的内容只 识别第一对 标签 里边的内容,直到第一个标签结束,后边的内容不识别,第一对内容中间的内容全部都识别
//语法糖:省去了extend的书写,直接在conponent里边写
var app_2 = new Vue({
el:'#app_2',
//局部组件
components:{
h3cpn:h3cpn
}
})
</script>
<div id="app_3">
<!--父组件 与 子组件 注册组件语法糖写法-->
<cpnc2></cpnc2>
<cpnc3></cpnc3>
<cpnc4></cpnc4>
</div>
<!--组件模板分离-->
<template id="cpnc4">
<div style="color:blue;">
<p>组件模板分离</p>
</div>
</template>
<script>
//创建子组件
const cpnC1 = Vue.extend({
template:`
<div>
<h2>我是子组件标题1</h2>
<p>我是组件中的一个段落内容1</p>
</div>`
})
//创建父组件
const cpnC2 = Vue.extend({
template:`
<div>
<h2>我是父组件标题222</h2>
<p>我是组件中的一个段落内容222</p>
<cpnc1></cpnc1>
</div>`,
components:{
cpnc1:cpnC1
}
})
let app_3 = new Vue({
el:'#app_3',
components:{
cpnc2:cpnC2,
//语法糖写法
cpnc3:{
template:`<div style="color:red;">语法糖写法</div>`
},
//组件模板分离
cpnc4:{template:cpnc4}
}
})
</script>
<div id="app_4">
<!--组件中的data必须是函数-->
<cpnn></cpnn>
<!--这里每一组的count不受影响,因为每一次都是重新return得来的数值,不是函数。
如果是函数,return得到的是相同的地址,所以一个改变,其他的也会发生改变。 -->
<cpnn2></cpnn2><cpnn2></cpnn2><cpnn2></cpnn2>
</div>
<template id="cpnn">
<div>调用组件的data:{{title}}</div>
</template>
<template id="cpnn2">
<div>当前计数:{{count}} <button @click="increment">+</button><button @click="decrement">-</button></div>
</template>
<script>
var app_4 = new Vue({
el:'#app_4',
components:{
//组件是一个单独功能模块的封装,这个模块有属于自己的HTML模板,也应该有属于自己的数据data,不能访问顶层VUE中的data数据
cpnn:{
data(){
return {
title:'Title标题'
}
},
template:cpnn
},//为什么必须是函数?
cpnn2:{
data(){return {count:0}},
template:cpnn2,
methods:{
increment(){ this.count++ },
decrement(){ this.count-- },
}
}
}
})
</script>
<div id="app_5">
<!--父子组件通信 父传子props 驼峰命名规则 -->
<cpncpn :cmovies="movies" :cmsg="msg"></cpncpn>
<!--在引用父元素的data时,如果在props写的是小驼峰的,在这里不识别,可以改成 :中划线- , 驼峰部分的大写改成小写 -->
</div>
<template id="cpncpn">
<div>
<ul>
<li v-for="item in cmovies">{{item}}</li>
</ul>
<p>{{cmsg}}</p>
</div>
</template>
<script>
const app_5 = new Vue({
el:'#app_5',
data:{
msg:'message',
movies:['海王','海贼王','海尔兄弟']
},
components:{
cpncpn:{
template:'#cpncpn',
//父传子,props可以是数组
// props:['cmsg','cmovies'],
//父传子,props可以是对象
props:{
//1 定义类型
cmsg:String,
//2 多个类型
// cmsg:[String,Number],
//3 必填 required
// cmsg:{
// type:String,
// required:true
// },
//4 带有默认值 default
// cmsg:{
// type:String,
// default:'aaabcd'
// },
//5 带有默认对象 类型是对象或者数组时,默认值必须是一个函数
cmovies:{
type: Array,
default(){
return {}
}
},
//6 自定义验证函数
// cmsg:{
// validator(value){
// //这个值必须匹配下列字符串中的一个
// return ['success','warning','danger'].indexOf(value) !== -1
// }
// },
}
}
},
})
</script>
<div id="app_6">
<!--父子组件通信 子传父 $emit()-->
<cpncpn2 @item_click="cpnClick"></cpncpn2>
</div>
<template id="cpncpn2">
<div><button v-for="item in categories" @click="btnClick(item)">{{item.name}}</button></div>
</template>
<script>
const cpncpn2={
template:'#cpncpn2',
data(){
return {
categories:[
{id:'aaa', name:'热门推荐'},
{id:'bbb', name:'手机数码'},
{id:'ccc', name:'家用家电'},
{id:'ddd', name:'电脑办公'}
]
}
},
methods:{
//子传父 $emit 发射事件 自定义事件
//在子函数中的methods中写一个函数(函数名自定义),(如果有参数要传递就直接写到小括号里)传递的函数名也是自定义(可以一样,可以不一样)。
//还要在父函数那里写一个函数进行接收(参数直接写到小括号里)。接收的函数名,是子函数传递的函数名
btnClick(item){
//console.log(item); 这个item_click暂时不要用小驼峰命名法,在父组件模板中不识别
this.$emit('item_click',item)
},
}
}
const app_6 = new Vue({
el:'#app_6',
data:{
msg:'message',
movies:['海王','海贼王','海尔兄弟']
},
components:{
cpncpn2
},
methods:{
cpnClick(item){
console.log(item);
}
}
})
//什么时候需要自定义事件?
//1、子组件需要向父组件传递数据时,需要用自定义事件
//2、v-on不仅可以用于监听DOM事件,也可以用于组件间的自定义事件
//自定义事件流程:
//1、在子组件中,通过$emit()来触发事件
//2、在父组件中,通过v-on来监听子组件事件
</script>
<!--父子组件通信 结合v-mobel双向绑定:cpn44-->
<!--不要直接在子组件中用v-mobel直接绑定原来父组件的数据,可以重新定义一下,再 绑定 重新定义的那个数据-->
<div id="app2">
<div v-for="(value,index) in origin">
<h3>{{value.info}}</h3>
<div style="display:flex">
<div v-for="items in value.project">{{items}}</div>
</div>
</div>
<cpn44 :number1='num1' :number2='num2' @itemclick='itemClick'></cpn44>
</div>
<template id="cpn44">
<div>
<h2>props传的值:{{number1}}</h2>
<h2>data重新定义的值:{{dnumber1}}</h2>
<input type="text" v-model="dnumber1" />
<h2>props传的值:{{number2}}</h2>
<h2>data重新定义的值:{{dnumber2}}</h2>
<input type="text" v-model="dnumber2" />
</div>
</template>
<script>
const cpn33 = Vue.component('cpn33',{
template:'#cpn33',
data(){
return{
num1:1,
}
},
methods:{},
})
const cpn44 = Vue.component('cpn44',{
template:'#cpn44',
props:{
number1: Number,
number2: Number
},
data() {
return {
dnumber1:this.number1,
dnumber2:this.number2,
}
},
methods:{
itemclick(item){
this.$emit('itemClick',item)
},
},
})
const vm2 = new Vue({
el:'#app2',
data:{
origin:[
{
info:"all1",
project:{"name":"wikina","age":"20","birthday":"1996"},
},
{
info:"all2",
project:{"name":"wikina","age":"20","birthda":"1996"},
},
{
info:"all3",
project:{"name":"wikina","age":"20","birthda":"1996"},
}
],
num1:1,
num2:0,
},
methods:{
itemClick(item){},
},
})
</script>
<!--bilibili 对数组操作的高阶函数:函数本身需要的参数可能也是函数-->
<script>
//filter map reduce
//filter 中的回调函数有一个要求:必须返回一个Boolean值
// true:返回true时,函数内部会自动将这次回调的n加入到新的数组中。
// false:返回false时,函数内部会过滤掉这次的n
//map 对数据进行映射操作。创建一个新数组,其结果是该数组中的每个元素都调用一个提供的函数后返回的结果。
//reduce 函数每次的调用都会产生一个回调值,下一次调用将这个值作为参数,并进行累计,对数组中所有的内容进行汇总。
// prev:函数传进来的初始值或上一次回调的返回值
// current:数组中当前处理的元素值
// currentIndex:当前元素索引
// arr:当前元素所属的数组本身
// initialValue:传给函数的初始值
const num=[10,20,30,40,50,60];
let num2 = num.filter(function(n){return n < 30});
console.log(num2);
let num3 = num2.map(function(n){ return n*2});
console.log(num3);
let num4 = num3.reduce(function(preValue,n){ return preValue + n },0);
console.log(num4);
// let newnum = num.filter(function(n){return n<30}).map(function(n){ return n*2}).reduce(function(preValue,n){return preValue + n},0);
let newnum = num.filter(n => n < 30).map(n => n * 2).reduce((pre,n) => pre + n);
console.log(newnum);
</script>
</body>
</html>
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。