使用Vue
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src= "https://unpkg.com/vue@next"></script>
mvvm设计模式
1.createApp表示创建一个Vue应用,存储到App变量中
2.传入的参数表示,这个应用最外层的组件,应该如何展示
3.mvvm 设计模式,m->model 数据,v->view 视图,vm->viewModel 视图数据连接层
const app = Vue.createApp({
data(){
return{
message:"hello world"
}
},
template:"<div>{{message}}</div>"
});
//vm代表的就是Vue应用的根组件
const vm = app.mount('#root');
生命周期函数
vue生命周期函数:在某一时刻会自动执行的函数
//实例生成之前会自动执行的函数
beforeCreate() {
console.log("beforeCreated");
},
//在实例生成之后会自动生成的函数
created() {
console.log("Created");
},
//在组件内容自动渲染到页面之前自动执行的函数
beforeMount() {
console.log( document.getElementById('root').innerHTML,"beforeMount");
},
//在组件内容被渲染到页面之后自动执行的函数
mounted() {
console.log(document.getElementById('root').innerHTML,"mounted");
},
//当数据发生变化时会立即自动执行的函数
beforeUpdate() {
console.log(document.getElementById('root').innerHTML,"beforeUpdate");
},
//当数据发生变化,页面重新渲染后,会自动执行的函数
updated() {
console.log(document.getElementById('root').innerHTML,"Updated");
},
//组件即将销毁时触发的函数
beforeUnmount() {
console.log(document.getElementById('root').innerHTML,'beforeUnmount');
},
//组件销毁完毕触发的函数
unmounted() {
console.log(document.getElementById('root').innerHTML,'unmount');
},
//组件销毁时触发的函数
beforeDestroy() {
},
//组件触发时,Vue示例解除了事件监听以及dom的绑定(无响应了),但dom节点依旧存在
destroyed() {
},
模板语法
data(){
return{
message:"hello world",
count: 2 ,
price: 5 ,
}
},
watch:{
price(){
setTimeout(()=>{
console.log('price changed')
},3000)
}
},
computed:{
total(){
return Data.now();
// return this.count*this.price;
}
},
methods: {
getTotal(){
return Data.now();
// return this.count*this.price;
},
},
template:`
<div>{{message}}---{{getTotal}}</div>
`
样式绑定
<style>
.red{
color: red;
}
.green{
color: green;
}
</style>
<script>
const app = Vue.createApp({
data(){
return{
classString:'red',
classObject:{red:false,green:true},
classArray:['red','green',{brown:false}],
styleString:'color:yellow;',
styleObject:{
color:'orange',
background:'yellow'
}
}
},
template:`
<div :style="styleObject">
hello world
<demo class="green" />
</div>
`
});
app.component('demo',{
template: `
<div :class="$attrs.class">single</div>
<div>gaga</div>
`
})
const vm = app.mount('#root');
</script>
条件渲染v-if,v-show
const app = Vue.createApp({
data(){
return{
show:false,
conditionOne:false,
conditionTwo:true,
}
},
template:`
<div v-if="show">hello world</div>
<div v-if="conditionOne">if</div>
<div v-else-if="conditionTwo">else-if</div>
<div v-else>else</div>
<div v-show="show">Bye world</div>
`
});
const vm = app.mount('#root');
列表渲染
const app = Vue.createApp({
data(){
return{
listArray:['dell','lee','teacher'],
listObject:{
firstName:'dell',
lastName:'lee',
job:'teacher'
}
}
},
methods: {
handleAddBtnClick(){
//1.数组的变更函数 push,pop,unshift,shift,reverse,splice,sort
// this.listArray.push('hello ya'); //在最后添加
// this.listArray.pop();// 在最后删除
// this.listArray.shift();//从头开始删除
// this.listArray.unshift('heiheihei');//从头开始添加
// this.listArray,reverse();//重组
// this.listArray.sort();
//2.最直接替换数组
// this.listArray=['bye','mo','fit'];
// this.listArray=['bye'].concat(['world']);
//3.直接更新数组内容
this.listArray[1]='hello';
//4.直接添加对象内容,也可以自动的展示出来
this.listObject.age=100;
this.listObject.sex='male';
}
},
template:`
<div>
<template
v-for="(value,key,index) in listObject"
:key="index"
>
<div v-if="key!=='lastName'">
{{value}}---{{key}}
</div>
</template>
<div v-for="item in 10">{{item}}</div>
<div>
<div v-for="(value,key,index) in listObject" :key="index">
{{value}}---{{key}}
</div>
</div>
<button @click="handleAddBtnClick">新增</button>
</div>
`
});
const vm = app.mount('#root');
事件绑定@,v-bind,:
methods: {
handleBtnClick(num,event){
console.log(event);
this.counter+=num;
}
},
template:`
<div>
{{counter}}
<button @click="handleBtnClick(2,$event)">button</button>
</div>
`
});
表单双向绑定v-model
const app = Vue.createApp({
data(){
return{
message:[],
options:[
{text:'A',value:{value:'A'}},
{text:'B',value:{value:'B'}},
{text:'C',value:{value:'C'}},
]
}
},
methods: {
handleBtnClick(num,event){
console.log(event);
this.counter+=num;
}
},
template:`
<div>
{{message}}
jack <input type="checkbox" v-model="message" value="jack" />
dell <input type="checkbox" v-model="message" value="dell" />
lee <input type="checkbox" v-model="message" value="lee" />
</div>
<div>
{{message}}
<select v-model="message" multiple>
<option v-for="item in options" :value="item.value">{{item.text}}</option>
</select>
</div>
`
});
组件
1.局部组件
const counter = {
data(){
},
template:``
}
const app = Vue.createApp({
components:{counter:counter},
});
2.全局组件
app.component('counter',{
props:['modelValue'],
emits:['add'],
// emits:{
// add:(count)=>{
// if(count>0){
// return true;
// }else{return false}
// }
// },
methods: {
handleItemClick(){
this.$emit('update:modelValue',2,5)
}
},
template:`
<div @click="handleItemClick">{{modelValue}}</div>
`
})
Noprops
const app = Vue.createApp({
template:`
<div>
<counter msg="hello" msg1="bye" />
</div>
`
});
app.component('counter',{
// props:["msg"],
// inheritAttrs:false,
mounted() {
console.log(this.$attrs);
},
template:`
<div :msg="$attrs.msg">Counter</div>
<div v-bind="$attrs">Counter</div>
<div :mod="$attrs.msg1">Counter</div>
`
})
父子组件
const app = Vue.createApp({
data(){
return{
count:1
}
},
methods:{
handleAdd(param,param2){
this.count+=param2;
}
},
template:`
<div>
<counter :count="count" @add="handleAdd"/>
</div>
`
});
app.component('counter',{
props:['count'],
// emits:['add'],
emits:{
add:(count)=>{
if(count>0){
return true;
}else{return false}
}
},
methods: {
handleItemClick(){
this.$emit('add',2,5)
}
},
template:`
<div @click="handleItemClick">{{count}}</div>
`
})
const app = Vue.createApp({
data(){
return{
count:1,
text:'hello'
}
},
template:`
<div>
<counter v-model="count"/>
</div>
`
});
app.component('counter',{
props:['modelValue'],
emits:['add'],
// emits:{
// add:(count)=>{
// if(count>0){
// return true;
// }else{return false}
// }
// },
methods: {
handleItemClick(){
this.$emit('update:modelValue',2,5)
}
},
template:`
<div @click="handleItemClick">{{modelValue}}</div>
`
})
双向绑定
const app = Vue.createApp({
data(){
return{
count:1,
count1:2
}
},
template:`
<div>
<counter v-model:count="count" v-model:count1="count1"/>
</div>
`
});
app.component('counter',{
props:['count','count1'],
// emits:['add'],
methods: {
handleItemClick(){
this.$emit('update:count',this.count+3)
},
handleItemClick1(){
this.$emit('update:count1',this.count1+5)
}
},
template:`
<div @click="handleItemClick">{{count}}</div>
<div @click="handleItemClick1">{{count1}}</div>
`
})
const app = Vue.createApp({
data(){
return{
count:'a',
}
},
template:`
<div>
<counter v-model.uppercase="count" />
</div>
`
});
app.component('counter',{
props:{
'modelValue':String,
'modelModifiers':{
default:()=>({})
}
},
mounted() {
console.log(this.modelModifiers);
},
// emits:['add'],
methods: {
handleItemClick(){
let newValue = this.modelValue+'b';
if(this.modelModifiers.uppercase){
newValue = newValue.toUpperCase();
}
this.$emit('update:modelValue',newValue);
},
},
template:`
<div @click="handleItemClick">{{modelValue}}</div>
`
})
插槽
slot插槽:
1.父模板里调用的数据属性,使用的都是父模板里的数据
2.子模板里调用的数据属性,使用的都是子模板里的数据
const app = Vue.createApp({
data(){
return{
text:'提交',
}
},
template:`
<div>
<myform>
<div>{{text}}</div>
<test></test>
</myform>
<myform>
<button>{{text}}</button>
</myform>
<myform>
</myform>
</div>
`
});
app.component('test',{
template:`<div>test</div>`
}),
app.component('myform',{
methods: {
handleClick(){
alert(123)
}
},
template:`
<div>
<input />
<span @click="handleClick">
<slot>default value</slot>
</span>
</div>
`
})
具名插槽
const app = Vue.createApp({
data(){
return{
text:'提交',
}
},
template:`
<layout>
<template v-slot:header>
<div>header</div>
</template>
<template v-slot:footer>
<div>footer</div>
</template>
</layout>
`
});
app.component('layout',{
template:`
<div>
<slot name="header"></slot>
<div>content</div>
<slot name="footer"></slot>
</div>
`
})
具名插槽:
//解构:
// template:`
// <list v-slot="{item}">
// <div>{{item}}</div>
// </list>
// `
const app = Vue.createApp({
data(){
return{
text:'提交',
}
},
template:`
<list v-slot="slotProps">
<div>{{slotProps.item}}</div>
</list>
`
});
app.component('list',{
data(){
return{list:[1,2,3]}
},
template:`
<div>
<slot v-for="item in list" :item="item"/>
</div>
`
})
动态组件
动态组件:根据数据的变化,结合component这个标签来动态随时切换组件的实现
下面两行等效于<component :is="currentItem" />
<input-item v-show="currentItem==='input-item'"/>
<common-item v-show="currentItem==='common-item'"/>
<keep-alive>缓存特性
const app = Vue.createApp({
data(){
return{
currentItem:'input-item',
}
},
methods: {
handleClick(){
if(this.currentItem==='input-item'){
this.currentItem='common-item';
}else{
this.currentItem='input-item';
}
}
},
template:`
<keep-alive>
<component :is="currentItem" />
</keep-alive>
<button @click="handleClick">切换</button>
`
});
app.component('input-item',{
template:`
<input />
`
});
app.component('common-item',{
template:`
<div>hello world</div>
`
});
异步组件
const AsyncCommonItem = Vue.defineAsyncComponent(()=>{
return new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve({
template:'<div>this is an AsyncCommonItem</div>'
})
},4000)
})
})
const app = Vue.createApp({
data(){
return{
currentItem:'input-item',
}
},
template:`
<div>
<common-item/>
<async-common-item />
</div>
`
});
app.component('common-item',{
template:`
<div>hello world</div>
`
});
app.component('async-common-item',AsyncCommonItem);
补充
v-once 让某个元素标签只渲染一次
ref 实际上是获取 Dom节点/组件用的语法
provide/inject跨组件传递
网友评论