引入
基础示例
main.js
App.vue
School.vue
import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false
new Vue({
render: h => h(App),
}).$mount('#app')
<template>
<div>
<School />
<School />
<School />
</div>
</template>
<script>
import School from "./components/School.vue";
export default {
name: "App",
components: { School },
};
</script>
<style></style>
<template>
<div>
<h2>学校名称:{{name}}</h2>
<h2>学校地址:{{addr}}</h2>
</div>
</template>
<script>
export default {
name: 'School',
data() {
return {
name: 'hello小学',
addr: 'earth'
}
},
}
</script>
<style>
</style>
ref属性
main.js
App.vue
School.vue
import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false
new Vue({
render: h => h(App),
}).$mount('#app')
<template>
<div>
<h3 v-text="msg" ref="title"></h3>
<button ref="btn" @click="showmsg">点我输出上方dom元素</button>
<School ref="sch"/>
</div>
</template>
<script>
import School from "./components/School.vue";
export default {
name: "App",
components: { School },
data() {
return {
msg: "欢迎学习vue"
}
},
methods: {
showmsg() {
console.log(this.$refs.title); // 真实DOM元素
console.log(this.$refs.btn); // 真实DOM元素
console.log(this.$refs.sch); // 组件实例对象 vc
}
}
};
</script>
<style>
</style>
<template>
<div>
<h2>学校名称:{{name}}</h2>
<h2>学校地址:{{addr}}</h2>
</div>
</template>
<script>
export default {
name: 'School',
data() {
return {
name: 'hello小学',
addr: 'earth'
}
},
}
</script>
<style>
</style>
props配置
:
属性带冒号,必须传入指定类型,否则抛出错误
main.js
App.vue
Student.vue
import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false
new Vue({
render: h => h(App),
}).$mount('#app')
<template>
<div>
<Student name="李四" sex="女" :age="18" />
<Student name="张三" sex="" />
</div>
</template>
<script>
import Student from "./components/Student.vue";
export default {
name: "App",
components: { Student },
};
</script>
<style></style>
<template>
<div>
<h3>{{ msg }}</h3>
<h2>学生姓名:{{ name }}</h2>
<h2>学生性别:{{ sex }}</h2>
<h2>学生年龄:{{ myAge + 1 }}</h2>
<button @click="modifyAge">修改年龄减1</button>
</div>
</template>
<script>
export default {
name: 'Student',
data() {
return {
msg: '快乐的一天',
myAge: this.age
}
},
methods: {
modifyAge() {
this.myAge -= 1
}
},
// 方式一: 简单接收
// props: ['name', 'sex', 'age']
// 方式二:按类型简单接收
// props:{
// name: String,
// sex: String,
// age: Number
// }
// 方式三:按要求接收
props: {
name: {
type: String,
required: true
},
sex: {
type: String,
required: true
},
age: {
type: Number,
default: 99
}
}
}
</script>
<style></style>
混合,共享配置
main.js
mixin.js
App.vue
Student.vue
School.vue
import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false
new Vue({
render: h => h(App),
}).$mount('#app')
// 混合, 共享配置, 以组件原数据为准
// 生命周期钩子会先执行混合的,再执行组件的
export const mixin = {
methods: {
showName() {
alert(this.name)
}
},
mounted() {
console.log('mixin mouted');
},
}
export const mixin2 = {
data() {
return {
a: 1000,
x: 200
}
},
}
<template>
<div>
<School />
<hr />
<Student />
</div>
</template>
<script>
import School from './components/School.vue';
import Student from "./components/Student.vue";
export default {
name: "App",
components: { Student, School }
};
</script>
<style>
</style>
<template>
<div>
<h2>学生姓名:{{ name }}</h2>
<h2>学生性别:{{ sex }}</h2>
<button @click="showName">show name</button>
</div>
</template>
<script>
import { mixin } from '../mixin'
export default {
name: 'Student',
data() {
return {
name: 'xiaoai',
sex: '男'
}
},
mixins: [mixin], // 局部混合
mounted() {
console.log('student mouted');
},
}
</script>
<style></style>
<template>
<div>
<h3>学校名称:{{ name }}</h3>
<h3>学校地址:{{ addr }}</h3>
<!-- <button @click="showName">show name</button> -->
<button @click="showName">show name</button>
</div>
</template>
<script>
// 引入混合
import {mixin} from "../mixin";
export default {
name: "School",
data() {
return {
name: "xx小学",
addr: "earth",
};
},
mixins: [mixin]
// mixins: [mixin],
}
</script>
<style>
</style>
插件
plugins.js
main.js
App.vue
export default {
install(Vue) {
console.log('install', Vue)
// 插件中使用 mySlice
Vue.filter('mySlice', function(value){
return value.slice(0, 4)
})
Vue.prototype.hello = () => {alert('hello')}
}
}
// 引入Vue
import Vue from "vue";
import App from "./App.vue"
import plugins from './plugins'
Vue.config.productionTip = false
Vue.use(plugins)
new Vue({
render: h => h(App)
}).$mount('#app')
<template>
<div>
<hr />
<button @click="hello">测试原型</button>
</div>
</template>
<script>
export default {
name: "App"
};
</script>
<style>
</style>
scoped 限制
- 限制样式为当前组件使用
- 此示例使用 less 来混入样式,需
pnpm i -D less less-loader
来安装依赖
main.js
App.vue
Student.vue
School.vue
// 引入Vue
import Vue from "vue";
import App from "./App.vue"
Vue.config.productionTip = false
new Vue({
render: h => h(App)
}).$mount('#app')
<template>
<div>
<School />
<hr />
<Student />
</div>
</template>
<script>
import School from './components/School.vue';
import Student from "./components/Student.vue";
export default {
name: "App",
components: { Student, School }
};
</script>
<style></style>
<template>
<div class="demo">
<h2>学生姓名:{{name}}</h2>
<h2>学生性别:{{sex}}</h2>
<h2 class="qwe">hehe</h2>
</div>
</template>
<script>
export default {
name: 'Student',
data() {
return {
name: 'xiaoai',
sex: '男'
}
},
}
</script>
<style lang="less" scoped>
/* scoped 指明了作用域,只对当前组件有效 */
.demo{
background-color: orange;
.qwe{
font-size: 40px;
}
}
</style>
<template>
<div class="demo">
<h3>学校名称:{{ name }}</h3>
<h3>学校地址:{{ addr }}</h3>
</div>
</template>
<script>
// 引入混合
export default {
name: "School",
data() {
return {
name: "xx小学",
addr: "earth",
};
},
}
</script>
<style scoped>
.demo{
background-color: skyblue;
}
</style>
自定义事件
main.js
App.vue
Student.vue
School.vue
// 引入Vue
import Vue from "vue"
import App from "./App.vue"
Vue.config.productionTip = false
// const Demo = Vue.extend({})
// const d = new Demo()
// Vue.prototype.x = d
new Vue({
render: (h) => h(App),
beforeCreate() {
Vue.prototype.$bus = this // 安装全局事件总线
},
}).$mount("#app")
<template>
<div class="app">
<h2>{{ msg }}</h2>
<!-- 属性实现传递 -->
<School />
<hr />
<!-- 自定义事件实现方式 -->
<Student />
</div>
</template>
<script>
import School from "./components/School.vue";
import Student from "./components/Student.vue";
export default {
name: "App",
components: { Student, School },
data() {
return {
msg: "欢迎学习vue",
studentName: "",
};
},
};
</script>
<style scoped>
.app {
background-color: grey;
padding: 10px;
}
</style>
<template>
<div class="student">
<h2>学生姓名:{{ name }}</h2>
<h2>学生性别:{{ sex }}</h2>
<button @click="sendName">把名称传给shool组件</button>
</div>
</template>
<script>
export default {
name: "Student",
data() {
return {
name: "xiaoai",
sex: "男",
n: 1,
};
},
methods: {
sendName() {
this.$bus.$emit("hello", this.name);
},
},
};
</script>
<style lang="less" scoped>
/* scoped 指明了作用域,只对当前组件有效 */
.student {
background-color: pink;
padding: 5px;
margin-top: 10px;
}
</style>
<template>
<div class="school">
<h3>学校名称:{{ name }}</h3>
<h3>学校地址:{{ addr }}</h3>
</div>
</template>
<script>
export default {
name: "School",
data() {
return {
name: "xx小学",
addr: "earth",
};
},
mounted() {
this.$bus.$on("hello", (data) => {
console.log("我是school组件,收到了数据:", data);
});
},
beforeDestroy() {
this.$bus.$off("hello");
},
};
</script>
<style scoped>
.school {
background-color: skyblue;
padding: 5px;
margin-top: 10px;
}
</style>
使用发布订阅
pnpm install pubsub-js
main.js
App.vue
Student.vue
School.vue
// 引入Vue
import Vue from "vue"
import App from "./App.vue"
Vue.config.productionTip = false
new Vue({
render: (h) => h(App)
}).$mount("#app")
<template>
<div class="app">
<h2>{{ msg }}</h2>
<!-- 属性实现传递 -->
<School />
<hr />
<!-- 自定义事件实现方式 -->
<Student />
</div>
</template>
<script>
import School from "./components/School.vue";
import Student from "./components/Student.vue";
export default {
name: "App",
components: { Student, School },
data() {
return {
msg: "欢迎学习vue",
studentName: "",
};
},
};
</script>
<style scoped>
.app {
background-color: grey;
padding: 10px;
}
</style>
<template>
<div class="student">
<h2>学生姓名:{{ name }}</h2>
<h2>学生性别:{{ sex }}</h2>
<button @click="sendName">把名称传给shool组件</button>
</div>
</template>
<script>
import pubsub from 'pubsub-js'
export default {
name: "Student",
data() {
return {
name: "xiaoai",
sex: "男",
n: 1,
};
},
methods: {
sendName() {
// this.$bus.$emit("hello", this.name);
pubsub.publish('hello', 666)
},
},
};
</script>
<style lang="less" scoped>
/* scoped 指明了作用域,只对当前组件有效 */
.student {
background-color: pink;
padding: 5px;
margin-top: 10px;
}
</style>
<template>
<div class="school">
<h3>学校名称:{{ name }}</h3>
<h3>学校地址:{{ addr }}</h3>
<button @click="death">取消订阅</button>
</div>
</template>
<script>
import pubsub from 'pubsub-js'
export default {
name: "School",
data() {
return {
name: "xx小学",
addr: "earth",
};
},
mounted() {
// this.$bus.$on("hello", (data) => {
// console.log("我是school组件,收到了数据:", data);
// });
this.pubID = pubsub.subscribe('hello', function(msgName, data){
console.log('有人发布了hello消息', msgName, data);
})
},
beforeDestroy() {
// this.$bus.$off("hello");
// 两种方式均可取消订阅
pubsub.unsubscribe(this.pubID)
// pubsub.unsubscribe('hello')
},
methods: {
death(){
// this.$destroy()
pubsub.unsubscribe(this.pubID)
// pubsub.unsubscribe('hello')
console.log('组件卸载了');
}
},
};
</script>
<style scoped>
.school {
background-color: skyblue;
padding: 5px;
margin-top: 10px;
}
</style>
动画
.v-enter-active 类是 Vue.js 在使用
具体来说,当你使用
.v-enter: 应用于元素在进入过渡开始时。
.v-enter-active: 应用于整个进入过渡过程中,可以用来定义过渡的持续时间、延时和曲线函数。
.v-enter-to: 应用于元素在进入过渡结束时。
.v-leave: 应用于元素在离开过渡开始时。
.v-leave-active: 应用于整个离开过渡过程中。
.v-leave-to: 应用于元素在离开过渡结束时。
这些类名的前缀 v- 可以通过
main.js
App.vue
Student.vue
School.vue
School.vue
School.vue
import Vue from "vue";
import App from './App.vue'
new Vue({
render: h => h(App)
}).$mount('#app')
<template>
<div>
<h1>动画效果</h1>
<Test />
<h1>过度效果</h1>
<Test2 />
<h1>多个元素过度效果</h1>
<Test3 />
<h1>第三方库动画</h1>
<Test4 />
</div>
</template>
<script>
import Test from './components/Test.vue'
import Test2 from './components/Test2.vue'
import Test3 from './components/Test3.vue'
import Test4 from './components/Test4.vue'
export default {
name: "App",
components: {Test, Test2, Test3, Test4}
};
</script>
<style>
</style>
<template>
<div>
<button @click="isShow = !isShow">切换/隐藏</button>
<!-- appear 一进来就播放动画 -->
<transition appear>
<h3 v-show="isShow">你好啊</h3>
</transition>
<hr />
<transition name="other">
<h3 v-show="isShow">另一个动画</h3>
</transition>
</div>
</template>
<script>
export default {
name: "Test",
data() {
return {
isShow: true,
showClass: {
come: false,
},
};
},
};
</script>
<style scoped>
h3 {
background-color: orange;
}
/* linear 加上为匀速 */
.v-enter-active {
animation: mytest 1s linear;
}
.v-leave-active {
animation: mytest 1s linear reverse;
}
.other-enter-active {
animation: mytest 1s linear;
}
.other-leave-active {
animation: mytest 1s linear reverse;
}
@keyframes mytest {
from {
transform: translateX(-100%);
}
to {
transform: translateX(0px);
}
}
</style>
<template>
<div>
<button @click="isShow = !isShow">切换/隐藏</button>
<!-- appear 一进来就播放动画 -->
<transition appear>
<h3 v-show="isShow">你好啊</h3>
</transition>
</div>
</template>
<script>
export default {
name: "Test",
data() {
return {
isShow: true,
showClass: {
come: false,
},
};
},
};
</script>
<style scoped>
h3 {
background-color: red;
/* transition: 1s linear; */
}
.v-enter-active,.v-leave-active{
transition: 1s linear;
}
/* 进入的起点 离开的终点*/
.v-enter, .v-leave-to{
transform: translateX(-100%);
}
/* 进入的终点 离开的起点 */
.v-enter-to, .v-leave{
transform: translateX(0);
}
</style>
<template>
<div>
<button @click="isShow = !isShow">切换/隐藏</button>
<!-- appear 一进来就播放动画 -->
<transition-group appear>
<h3 v-show="isShow" key="1">Hello</h3>
<h3 v-show="isShow" key="2">World</h3>
</transition-group>
</div>
</template>
<script>
export default {
name: "Test",
data() {
return {
isShow: true,
showClass: {
come: false,
},
};
},
};
</script>
<style scoped>
h3 {
background-color: skyblue;
/* transition: 1s linear; */
}
.v-enter-active,.v-leave-active{
transition: 1s linear;
}
/* 进入的起点 离开的终点*/
.v-enter, .v-leave-to{
transform: translateX(-100%);
}
/* 进入的终点 离开的起点 */
.v-enter-to, .v-leave{
transform: translateX(0);
}
</style>
<template>
<div>
<button @click="isShow = !isShow">切换/隐藏</button>
<transition-group name="animate__animated animate__bounce" appear
enter-active-class="animate__swing"
leave-active-class="animate__backOutUp">
<h3 v-show="isShow" key="1">Hello</h3>
<h3 v-show="isShow" key="2">World</h3>
</transition-group>
</div>
</template>
<script>
import "animate.css";
export default {
name: "Test",
data() {
return {
isShow: true,
};
},
};
</script>
<style scoped>
h3 {
background-color: blue;
/* transition: 1s linear; */
}
</style>
跨域问题
- 开启代理服务器
单个代理服务器
多个代理服务器
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
transpileDependencies: true,
lintOnSave: false,
// 开启代理服务器, 方式一
devServer: {
proxy: 'http://localhost:5000'
}
})
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
transpileDependencies: true,
lintOnSave: false,
// 开启代理服务器, 方式二
devServer: {
proxy: {
'/v1': {
target: 'http://localhost:5000',
pathRewrite: {
'^/v1': '' // 将前缀 /v1 重写为 空,否则转发时会带上前缀
},
ws: true, // 用于支持 websocket
changeOrigin: true // 是否 欺骗target 与他同源
},
'/v2': {
target: 'http://localhost:5001',
pathRewrite: {
'^/v2': '' // 将前缀 /v1 重写为 空,否则转发时会带上前缀
}
}
}
}
})
- 服务端示例
js
js
const express = require('express')
const app = express()
app.use((request,response,next)=>{
console.log('有人请求服务器1了');
console.log('请求来自于',request.get('Host'));
console.log('请求的地址',request.url);
next()
})
app.get('/students',(request,response)=>{
const students = [
{id:'001',name:'tom',age:18},
{id:'002',name:'jerry',age:19},
{id:'003',name:'tony',age:120},
]
response.send(students)
})
app.listen(5000,(err)=>{
if(!err) console.log('服务器1启动成功了,请求学生信息地址为:http://localhost:5000/students');
})
const express = require('express')
const app = express()
app.use((request,response,next)=>{
console.log('有人请求服务器2了');
next()
})
app.get('/cars',(request,response)=>{
const cars = [
{id:'001',name:'奔驰',price:199},
{id:'002',name:'马自达',price:109},
{id:'003',name:'捷达',price:120},
]
response.send(cars)
})
app.listen(5001,(err)=>{
if(!err) console.log('服务器2启动成功了,请求汽车信息地址为:http://localhost:5001/cars');
})
- 客户端示例
main.js
App.vue
import Vue from "vue";
import App from './App.vue'
new Vue({
render: h => h(App)
}).$mount('#app')
<template>
<div>
<h2>发送请求</h2>
<button @click="getStudents">获取学生信息</button>
<button @click="getCars">获取汽车信息</button>
</div>
</template>
<script>
import axios from "axios";
export default {
name: "App",
methods: {
getStudents() {
// 如果当前有对应资源则不会进行代理转发
axios.get("http://localhost:8080/v1/students").then(
(response) => {
console.log("请求成功", response.data);
},
(error) => {
console.log("请求失败了", error.message);
}
);
axios.get("http://localhost:8080/1.txt").then(
(response) => {
console.log("2请求成功", response.data);
},
(error) => {
console.log("2请求失败了", error.message);
}
);
},
getCars() {
axios.get("http://localhost:8080/v2/cars").then(
(response) => {
console.log("response", response.data);
},
(error) => {
console.log("error", error.message);
}
);
},
},
};
</script>
<style>
</style>
插槽
main.js
App.vue
ZoneCategory.vue
SlotNameCategory.vue
SlotCategory.vue
School.vue
import Vue from "vue";
import App from './App.vue'
new Vue({
render: h => h(App),
beforeCreate() {
Vue.prototype.$bus = this
}
}).$mount('#app')
<template>
<div>
<h3>使用了插槽-作用域插槽</h3>
<div class="container">
<ZoneCategory>
<template slot-scope="indata">
<ul>
<li v-for="(data, index) in indata.games" :key="index">
{{ data }}
</li>
</ul>
</template>
</ZoneCategory>
<ZoneCategory>
<template slot-scope="indata">
<ol>
<li v-for="(data, index) in indata.games" :key="index">
{{ data }}
</li>
</ol>
</template>
</ZoneCategory>
<ZoneCategory>
<template slot-scope="{ games }">
<!-- 支持结构赋值 -->
<h4 v-for="(data, index) in games" :key="index">
{{ data }}
</h4>
</template>
</ZoneCategory>
</div>
<hr />
<h3>使用了插槽-具名插槽</h3>
<div class="container">
<SlotNameCategory title="美食">
<img
slot="center"
src="https://tse4-mm.cn.bing.net/th/id/OIP-C.gihAGoizdsi2TYvWcGG1WQHaE1?w=287&h=187&c=7&r=0&o=5&dpr=2&pid=1.7"
alt=""
/>
<a slot="footer" href="http://www.baidu.com">百度一下,你就知道</a>
</SlotNameCategory>
<SlotNameCategory title="游戏">
<u slot="center">
<li v-for="(data, index) in games" :key="index">{{ data }}</li>
</u>
<!-- <div class="foot" slot="footer"> -->
<template v-slot:footer>
<!-- template 好处是不会额外多一层div -->
<div class="foot">
<a a href="http://www.baidu.com/s?wd=单机游戏">单机游戏</a>
<a href="http://www.baidu.com/s?wd=网络游戏">网络游戏</a>
</div>
<h4 style="text-align: center">欢迎来打游戏</h4>
</template>
<!-- </div> -->
</SlotNameCategory>
<SlotNameCategory title="电影">
<video controls src="http://vjs.zencdn.net/v/oceans.mp4"></video>
<div class="foot" slot="footer">
<a href="http://www.baidu.com/s?wd=经典">经典</a>
<a href="http://www.baidu.com/s?wd=热门">热门</a>
<a href="http://www.baidu.com/s?wd=推荐">推荐</a>
</div>
<h4 slot="footer" style="text-align: center">欢迎来观看</h4>
</SlotNameCategory>
</div>
<hr />
<h3>使用了插槽-默认插槽</h3>
<div class="container">
<SlotCategory title="美食">
<img
src="https://tse4-mm.cn.bing.net/th/id/OIP-C.gihAGoizdsi2TYvWcGG1WQHaE1?w=287&h=187&c=7&r=0&o=5&dpr=2&pid=1.7"
alt=""
/>
</SlotCategory>
<SlotCategory title="游戏">
<ul>
<li v-for="(data, index) in games" :key="index">{{ data }}</li>
</ul>
</SlotCategory>
<SlotCategory title="电影">
<video controls src="http://vjs.zencdn.net/v/oceans.mp4"></video>
</SlotCategory>
</div>
<hr />
<h3>未使用插槽缺点</h3>
<div class="container">
<Category title="美食" :listData="foods" />
<Category title="游戏" :listData="games" />
<Category title="电影" :listData="films" />
</div>
<hr />
</div>
</template>
<script>
import Category from "./components/Category.vue";
import SlotCategory from "./components/SlotCategory.vue";
import SlotNameCategory from "./components/SlotNameCategory.vue";
import ZoneCategory from "./components/ZoneCategory.vue";
export default {
name: "App",
components: { Category, SlotCategory, SlotNameCategory, ZoneCategory },
data() {
return {
foods: ["火锅", "烧烤", "小龙虾", "牛排"],
games: ["星际争霸", "dota", "英雄联盟", "王者荣耀"],
films: ["《教父》", "《拆弹专家》", "《你好,李焕英》", "《死神来了》"],
};
},
};
</script>
<style>
.container,
.foot {
display: flex;
justify-content: space-around;
}
video {
width: 100%;
}
</style>
<template>
<div class="ZoneCategory">
<h3>{{title}}分类</h3>
<slot :games="games">我是默认值</slot>
</div>
</template>
<script>
export default {
name: 'ZoneCategory',
props: ['title'],
data() {
return {
// games: ["星际争霸", "dota", "英雄联盟", "王者荣耀"],
}
},
}
</script>
<style scoped>
.ZoneCategory{
background-color: skyblue;
width: 200px;
height: 300px;
}
h3{
text-align: center;
background-color: orange;
}
img{
width: 100%;
}
</style>
<template>
<div class="SlotNameCategory">
<h3>{{title}}分类</h3>
<slot name="center">没传时这里是默认值center</slot>
<slot name="footer">没传时这里是默认值footer</slot>
</div>
</template>
<script>
export default {
name: 'SlotNameCategory',
props: ['title']
}
</script>
<style scoped>
.SlotNameCategory{
background-color: skyblue;
width: 200px;
height: 300px;
}
h3{
text-align: center;
background-color: orange;
}
img{
width: 100%;
}
</style>
<template>
<div class="SlotCategory">
<h3>{{title}}分类</h3>
<slot>没传时这里是默认值</slot>
</div>
</template>
<script>
export default {
name: 'SlotCategory',
props: ['title']
}
</script>
<style scoped>
.SlotCategory{
background-color: skyblue;
width: 200px;
height: 300px;
}
h3{
text-align: center;
background-color: orange;
}
img{
width: 100%;
}
</style>
<template>
<div class="category">
<h3>{{title}}分类</h3>
<ul >
<li v-for="(data, index) in listData" :key="index">{{data}}</li>
</ul>
<img src="https://tse4-mm.cn.bing.net/th/id/OIP-C.gihAGoizdsi2TYvWcGG1WQHaE1?w=287&h=187&c=7&r=0&o=5&dpr=2&pid=1.7" alt="">
<video controls
src="http://vjs.zencdn.net/v/oceans.mp4"
></video>
</div>
</template>
<script>
export default {
name: 'Category',
props: ['title', 'listData']
}
</script>
<style scoped>
.category{
background-color: skyblue;
width: 200px;
height: 300px;
}
h3{
text-align: center;
background-color: orange;
}
img,video{
width: 100%;
}
</style>