В этой статье в основном обобщаются некоторые небольшие проблемы, возникшие в проекте, и соответствующие решения, чтобы в будущем не наступить на яму.В последующем дополнении, если у вас есть разные ответы на эти проблемы, пожалуйста, прокомментируйте
1. Поле ввода использует v-модель для привязки значения, но его нельзя изменить.
// 第一种情况
<el-input v-model="form.title"></el-input>
// 初始化
data () {
return {
form: {}
}
}
// 赋值,其中formData为父组件传过来的数据
mounted (){
this.form.title = this.formData.title
}
// 这里不生效的原因为title没有初始化
data () {
return {
form: {title:''}}
}
// 第二种情况
在表单中使用时,用:model=""给输入框赋值
<el-form :model="formData">
<el-form-item>
<el-input placeholder="请输入" :model="formData.value" size="small"/>
</el-form-item>
</el-form>
// 解决方案,改为
<el-input placeholder="请输入" v-model="formData.value" size="small"/>
2. Текстовое содержимое не переводится в html-теги
Я хочу ввести следующее, но после сохранения данных становитсяaaa
Решение: если это html-контент, javascript, xml или другой специальный контент, используйте
<xmp></xmp>
Если это простой текст со специальными символами, такими как пробелы и возврат каретки, добавьте<pre></pre>Этикетка
3. Основная функция экспорта
SensitiveOperationExport(params).then(res => {
if (res.data.code === '200') {
// 这里是导出
window.location.href = res.data.data.path
this.$message({
message: '导出成功!',
type: 'success'
})
} else {
this.$message.error({message: '导出失败!'})
}
})
4. При использовании таблицы элементов снимите некоторые флажки
<el-table-column type="selection" align="center" fixed :selectable="selectable"></el-table-column>
На официальном сайте есть такая операция
selectable, допустимо только для столбцов с type=selection, тип — Function, возвращаемое значение Function используется для определения возможности проверки флажка в этой строке.
// 判断表格数据是否可选
selectable(row, index) {
if (row.IsDefault === 0) {
return false // 返回false为不可选数据
} else {
return true
}
}
5. Данные, возвращаемые интерфейсом, имеют тип json, при отображении в таблице их можно преобразовать следующим образом
// 数据结构 content: "{'title': '这是标题'}"
this.title = JSON.parse(content).title
6. Нажмите на картинку, чтобы увеличить функцию в списке
Установите просмотрщик, который поддерживает переключение изображений, вращение, масштабирование и другие функции. Конкретный рабочий документ можно просмотреть на Baidu, и его также очень просто использовать на странице. Первый шаг — глобальная настройка.
// main.js 中引入配置
Viewer.setDefaults({
'zIndex': 9999,
'inline': false, // 是否默认展示缩略图
'button': true, // 右上角按钮
'navbar': true, // 底部缩略图
'title': true, // 当前图片标题
'toolbar': true, // 底部工具栏
'tooltip': true, // 显示缩放百分比
'movable': false, // 是否可以移动
'zoomable': true, // 是否可以缩放
'rotatable': true, // 是否可旋转
'scalable': true, // 是否可翻转
'transition': true, // 使用 CSS3 过度
'fullscreen': true, // 播放时是否全屏
'keyboard': true, // 是否支持键盘
'url': 'data-source'
})
// 页面中使用
<viewer>
<img :src="scope.row.content "/>
</viewer>
7. Двигайтесь вверх и двигайтесь вниз
Вообще говоря, перемещение вверх и вниз — это операция удаления интерфейса, но есть и такие, которые не могут удалить интерфейс.
/ 上移
moveUp (index, row) {
if (index > 0) {
let upDate = this.tableData[index - 1]
this.tableData.splice(index - 1, 1)
this.tableData.splice(index, 0, upDate)
}
},
// 下移
moveDown (index, row) {
if ((index + 1) === this.tableData.length) {
console.log('已经是最后一条,不可下移')
} else {
let downDate = this.tableData[index + 1]
this.tableData.splice(index + 1, 1)
this.tableData.splice(index, 0, downDate)
}
}
8. Выбор и обращение таблиц
<el-table :data="tableData" border :select-all="allSelect" @selection-change="changeFun" ref="form" height="700"></el-table>
// tableData 是表格数据
<div>
<el-button @click="toggleSelect(tableData)">全选</el-button>
<el-button @click="reverseSelect(tableData)">反选</el-button>
</div>
// 全选
toggleSelect (rows) {
if (rows) {
rows.forEach(row => {
this.$refs.form.toggleRowSelection(row, !this.allSelect)
})
this.allSelect = !this.allSelect
}
},
// 反选
reverseSelect (rows) {
let checked = this.data
if (rows) {
rows.map(row => {
checked && checked.map(item => {
if (row.index !== item.index) {
this.$refs.form.toggleRowSelection(item, false)
this.$refs.form.toggleRowSelection(row, true)
} else {
this.$refs.form.toggleRowSelection(row, false)
}
})
})
if (checked.length === 0) {
rows.forEach(row => {
this.$refs.form.toggleRowSelection(row, true)
})
}
}
},
// 获取选择的数据
changeFun (val) {
this.data = val
}
9. Нажмите и удерживайте, чтобы говорить
Эта функция зависит от recorder.js, использование которой было описано в предыдущей статье, поэтому я не буду вдаваться в подробности.
10. Переключатель редактирования и сохранения таблицы
// editColorShow: '' // 设置敏感操作默认显示编辑
// clearEdit: '000' // 替换editColorShow的值
<el-table-column label="操作" align="center"
width="200">
<template slot-scope="scope">
<el-button size="small" v-if="editColorShow !== scope.$index" type="primary" @click="editColor(scope.$index, scope.row)">编辑</el-button>
<el-button size="small" v-if="editColorShow === scope.$index" type="primary" @click="submitSettingOperation(scope.$index, scope.row)">保存</el-button>
</template>
</el-table-column>
// 方法中这样
editColor (index, row) {
this.editColorShow = index
},
submitSettingOperation (index, data) {
this.editColorShow = this.clearEdit
}
11. Глубокое копирование
Первый:
function copy(arr) {
var newObj = arr.constructor === Array ? [] : {}
if (typeof arr === 'object') {
for (var i in arr) {
if (typeof arr[i] === 'object') {
newObj[i] = copy(arr[i])
}
newObj[i] = arr[i]
}
return newObj
} else {
return
}
}
второй
function copy (obj) {
var newObj = obj.constructor === Array ? [] : {}
newObj = JSON.parse(JSON.stringify(obj))
return newObj
}
12. Проблема сброса формы
Когда я раньше сбрасывал форму, она была такой. одна строка кода.
this.$refs['infoForm'].resetFields()
// 前提是要重置的输入框必须设置prop属性才可以
13. Есть два способа экспортировать текстовый файл.
Первая чистая фронтальная загрузка
fetch('https://xxxxx.com/' + item.path).then(res => res.blob().then(blob => {
var a = document.createElement('a')
var url = window.URL.createObjectURL(blob)
var filename = 'text.txt'
a.href = url
a.download = filename
a.click()
window.URL.revokeObjectURL(url)
}))
Второй - скачать после получения содержимого txt
createDownload (fileName, content) {
var blob = new Blob([content])
var link = document.createElement('a')
var bodyEle = document.getElementsByTagName('body')[0]
link.innerHTML = fileName
link.download = fileName
link.href = URL.createObjectURL(blob)
bodyEle.appendChild(link)
link.click()
bodyEle.removeChild(link)
}
Хотя можно загрузить и то, и другое, необходимо убедиться, что загруженный интерфейс доступен на странице, и не возникнет междоменных проблем.
14. Экспорт Excel
Существует два метода экспорта формы. Первый зависит от третьей стороны. Во-первых, загрузите три зависимости.
скачатьBlob.js и Export2Excel.jsДва файла, импортированные в файл
// npm install file-saver xlsx script-loader --save
// 导出
onExportExcel (formName) {
import('@/vendor/Export2Excel').then(excel => {
// 表格的title
const tHeader = ['订单编号', '姓名', '员工编号', '手机号', '公司']
// 对应的字段
const filterVal = ['sn', 'user_name', 'user_no', 'user_phone', 'user_company']
const data = this.formatJson(filterVal, this.dataTable)
excel.export_json_to_excel({
header: tHeader,
data,
filename: `订单列表`
})
})
},
formatJson (filterVal, jsonData) {
let arr = jsonData.map(v => filterVal.map(j => v[j]))
return arr
}
Второй — через vue-json-excel, подробности см.vue-json-excel
// 安装 npm install vue-json-excel,引入
// vue中使用
<download-excel
class = "btn btn-default"
:data = "json_data"
:fields = "json_fields"
worksheet = "My Worksheet"
name = "filename.xls">
</download-excel>
data(){
return {
// 要导出的字段
json_fields: {
'Complete name': 'name',
'City': 'city',
'Telephone': 'phone.mobile',
'Telephone 2' : {
field: 'phone.landline',
callback: (value) => {
return `Landline Phone - ${value}`;
}
},
},
// 要导出的数据
json_data: [
{
'name': 'Tony Peña',
'city': 'New York',
'country': 'United States',
'birthdate': '1978-03-15',
'phone': {
'mobile': '1-541-754-3010',
'landline': '(541) 754-3010'
}
},
{
'name': 'Thessaloniki',
'city': 'Athens',
'country': 'Greece',
'birthdate': '1987-11-23',
'phone': {
'mobile': '+1 855 275 5071',
'landline': '(2741) 2621-244'
}
}
],
json_meta: [
[
{
'key': 'charset',
'value': 'utf-8'
}
]
]
}
}
15. Используйте iconfont в панели навигации, выберите проблему не меняющегося цвета
Давайте посмотрим на сравнение
Проект разработан на основе element-ui, и использования иконок не избежать, поэтому Али Галерея - хороший выбор.Проблема здесь заключается в том, что после выбора левой панели навигации цвет текста меняется, а иконка остается то же самое.Как правило, существует три способа обращения к галерее Ali: Unicode, класс шрифта, символ; я использую метод символа для ссылки следующим образом
1. Значок имеет формат svg, выберите значок, который будет использоваться, и загрузите формат svg.
2. Создайте папку значков для хранения значков и создайте папку svgIcon для использования значков следующим образом.
3. Причина, по которой иконка здесь не меняет цвет, заключается в том, что сама загруженная иконка цветная, поэтому при получении иконки через символ к пути svg будет добавлен атрибут fill, так что цвет не может быть изменено, а атрибут заполнения в значке можно оставить пустым. , это решает
16. Функция маршрутизации нечеткого поиска vue
Требования: На панели навигации имеется окно поиска, и вы можете перейти на указанную страницу в соответствии с введенным названием страницы.Код выглядит следующим образом
<template>
<div>
<el-select
ref="headerSearchSelect"
v-model="search"
:remote-method="querySearch" // 远程搜索方法
remote // 是否为远程搜索
filterable // 是否可搜索
default-first-option // 输入框按下回车,返回第一个匹配项,需搭配filterable或remote使用
placeholder="搜索"
class="header-search-select"
@change="change"
>
<el-option v-for="item in options" :key="item.path" :value="item" :label="item.title.join(' > ')" />
</el-select>
</div>
</template>
<script>
import path from 'path';
export default {
// 获取到当前账户下的所有可见页面路由
props: {
routers: {
type: Array
}
},
data () {
return {
search: '',
options: [],
searchPool: []
}
},
computed: {
routes() {
return this.routers
}
},
mounted () {
this.searchPool = this.generateRoutes(this.routes)
},
methods: {
// 远程搜索
querySearch (query) {
if (query !== '') {
// 数组去重
this.options = Array.from(new Set(this.searchQuery(query)))
} else {
this.options = []
}
},
// 改变时跳转
change (val) {
// 判断当前页与搜索的页面是否一致,如一致则清空不跳转,反之跳转
if (val.path !== this.$router.history.current.path) {
this.$router.push(val.path)
// 跳转路径后清空搜索框内容,也可以不清空
this.search = ''
this.options = []
} else {
this.search = ''
this.options = []
}
},
// 筛选符合条件的路由
searchQuery (query) {
const list = []
this.searchPool.map(item => {
item.title.filter(items => {
if (items.indexOf(query) > -1) {
list.push(item)
}
})
})
return list
},
// 处理路由数据
generateRoutes(routes, basePath = '/', prefixTitle = []) {
let res = []
for (const router of routes) {
if (router.hidden) { continue }
const data = {
path: path.resolve(basePath, router.path),
title: [...prefixTitle]
}
if (router.meta && router.meta.title) {
data.title = [...data.title, router.meta.title]
if (router.redirect !== 'noRedirect') {
res.push(data)
}
}
// recursive child routes
if (router.children) {
const tempRoutes = this.generateRoutes(router.children, data.path, data.title)
if (tempRoutes.length >= 1) {
res = [...res, ...tempRoutes]
}
}
}
return res
}
}
}
</script>
На что следует обратить внимание, так это на то, как прописан маршрут, должен быть соответствующий заголовок, например, этот
// 当页面没有子级菜单时
{
path: '/log',
component: Home,
name: 'Log',
redirect: '/redirect',
children: [
{
path: 'index',
name: 'LogIndex',
component: _import('log/Index'),
meta: {
title: '日志管理',
roles: [RoleName.Super, RoleName.AfterSale],
icon: 'custom-rizhi'
}
}
]
}
// 当页面有子级菜单时
{
path: '/operation',
component: Home,
name: 'Operation',
redirect: '/redirect',
meta: { title: '运营管理', icon: 'custom-yunying1' }, // 区别在于这里,有子级的一定要在这加上meta
children: [
{
path: 'payment',
name: 'OperationPayment',
component: _import('operation/Payment'),
meta: {
title: '支付管理',
roles: [RoleName.Operator] // 可通过roles判断当前用户是否有权限查看该页面
}
},
{
path: 'shop',
name: 'OperationShop',
component: _import('operation/Shop'),
meta: {
title: '店铺管理',
roles: [RoleName.Super, RoleName.Operator, RoleName.Staff, RoleName.Marketer]
}
},
{
path: 'banner',
name: 'OperationBanner',
component: _import('operation/Banner'),
meta: {
title: '图片管理',
roles: [RoleName.Super, RoleName.Operator, RoleName.Staff, RoleName.Marketer]
}
}
]
}
17. Добавьте несколько небольших вопросов о маршрутизации
<router-link to=""></router-link>: Разобрать в метку и указать путь перехода к<router-view>: просмотр компонента рендерингаДва способа импорта компонентов по маршруту
import app from '@/view/app'
{
path: '/',
component: app, // 第一种:直接引入
component: () => import('@/view/app') // 第二种:懒加载
}
- динамическая маршрутизация
{
path: '/argu:name' // name为动态路由参数
// 嵌套路由
path: '/parent',
children: [
{
path: '/child'
}
],
// 命名路由
path: '/login',
name: 'name' // 命名,在router-link中可以:to="{name: 'login'}"跳转
}
- Именованные представления, которые могут загружать несколько компонентов
<router-view/>
<router-view name="email"/>
{
path: 'names',
components: {
default: () => import('@/view/app'),
email: () => import('@/view/message')
}
}
- Три способа переадресации
{
path: '/email',
redirect: '/main', // 第一种
redirect: { // 第二种
name: 'main'
},
redirect: to => { // 第三种
return {
name: 'main'
}
}
}
6. Псевдоним (доступ к псевдониму эквивалентен доступу к текущему маршруту)
// 例如,访问main_index就相当于访问main
{
path: '/main',
alias: '/main_index'
}
7. Прыжок
this.$router.push('/home') // 可直接跳转到home页
// 携带参数跳转一
this.$router.push({
name: 'home',
querry: {
// 参数,显示在地址栏中
}
})
// 携带参数二
this.$router.push({
params: {
// 参数
}
})
// 携带参数三
this.$router.push({
// 第三种
name: '我是参数'
path:`/home${name}`
})
8. Заменить (разница между push и replace)
Браузер push запишет, вернется на предыдущую страницу, а замена будет рассматривать текущую страницу как родительскую.
Например: текущая страница домашняя, щелкните, чтобы перейти на страницу «О нас», нажмите «Нажать», чтобы перейти, а затем вернуться, предыдущая страница является домашней.
Текущая страница является домашней, нажмите, чтобы перейти на страницу «О нас», нажмите «Заменить», чтобы вернуться, а предыдущая страница посвящена
this.$router.replace({
name: 'home'
})
- props может передавать значения в роутер
{
path: '/about',
// 第一种
props: {
foood: 'apple'
},
// 第二种
props: router => {
food: router.query.food // 参数中传递了food值
}
}
// 页面中获取
props: {
foood: {
type: string,
default: 'orange'
}
}
routerСредняя конфигурацияmode: 'history'Адресную строку # можно удалить, но требуется внутренняя поддержка конфигурацииrouter.before()Предварительный прыжок, который можно использовать, чтобы определить, нужно ли входить в систему и иметь разрешение перед прыжком.
18. Случайным образом сгенерируйте значение идентификатора --> this._uid
<span>{{index}}</span>
// 初始化定义
index: `index_${this._uid}`
19. Решить проблему с предупреждением браузера проекта vue.
Решить проблему, что проект vue имеет сигнал тревоги при использовании element-ui.Я не знаю, видит ли браузер такую информацию при запуске проекта (я использую Google Chrome), хотя это не влияет на работу проекта. , но смотреть не очень удобно, содержание следующее
———————————————
[Нарушение] Добавлен непассивный прослушиватель событий к блокирующему прокрутку событию «колесо мыши». Рассмотрите возможность пометить обработчик события как «пассивный», чтобы сделать страницу более отзывчивой.Решение выглядит следующим образом
1. Установите зависимости npm i default-passive-events -S
2.main.js представляет импорт «пассивных событий по умолчанию»
3. решено
Решите проблему тревоги, когда проект Vue использует момент, содержание выглядит следующим образом
———————————————
Deprecation warning: value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are discouraged and will be removed in an upcoming major release. Please refer to http://momentjs.com/guides/#/warnings/js-date/ for more info.Решение выглядит следующим образом
1. Добавьте строку moment.suppressDeprecationWarnings = true в main.js, чтобы закрыть подсказку.
2. решено
20. Проблема, заключающаяся в том, что дочерний маркер блокируется слоем маски родительского маркера.
Дочернее добавление: append-to-body="true"
Родительское добавление: close-on-click-modal="false" :modal-append-to-body="false"
21. Операции форматирования
Добавьте следующий код в main.js, на странице используется {{time | dateformat}}
// 日期时间格式化
Vue.filter('dateformat', function(dataStr, pattern = 'YYYY-MM-DD HH:mm:ss') {
return moment(dataStr).format(pattern)
})
Vue.filter('getDate', function(dataStr, pattern = 'YYYY-MM-DD') {
return moment(dataStr).format(pattern)
})
Vue.filter('getTime', function(dataStr, pattern = 'HH:mm:ss') {
return moment(dataStr).format(pattern)
})
// 金额格式化
Vue.filter('money', function(val) {
val = val.toString().replace(/\$|\,/g, '')
if (isNaN(val)) {
val = '0'
}
const sign = (val === (val = Math.abs(val)))
val = Math.floor(val * 100 + 0.50000000001)
let cents = val % 100
val = Math.floor(val / 100).toString()
if (cents < 10) {
cents = '0' + cents
}
for (let i = 0; i < Math.floor((val.length - (1 + i)) / 3); i++) {
val = val.substring(0, val.length - (4 * i + 3)) + ',' + val.substring(val.length - (4 * i + 3))
}
return (((sign) ? '' : '¥') + val + '.' + cents)
})
// 银行卡号格式化
Vue.filter('bankCard', function(accNo) {
let result = ''
let index = 0
if (accNo !== undefined && accNo != null) {
for (let i = 0; i < accNo.length; i++) {
result += accNo.charAt(i)
index++
if (index === 4 && (i + 1 !== accNo.length)) {
result += ' '
index = 0
}
}
}
return result
})
22. Щелкните текст в таблице, чтобы он стал полем ввода и автоматически получил фокус
// input框自动获取焦点,自定义指令,与methods同级, input添加指令v-focus
directives: {
'focus': {
// 指令的定义
inserted(el) {
if (el.tagName.toLocaleLowerCase() === 'input') {
el.focus()
} else {
if (el.getElementsByTagName('input')) {
el.getElementsByTagName('input')[0].focus()
}
}
}
}
}
23. Фон частиц
插件 vue-particles 安装引入
24. При использовании таблицы элементов, когда таблица отображается динамически, таблица неупорядочена
<el-table>
<el-table-column v-if="checked" label="旧车价格" width="200" />
</el-table>
Решение состоит в том, чтобы добавить в таблицу атрибут ref и повторно отобразить таблицу в обновленном виде.
updated() {
this.$refs['table'].doLayout()
}
25. Преобразование массива в составной массив
Каскадное раскрывающееся меню может потребоваться в требованиях проекта, но данные, представленные в фоновом режиме, могут быть не такими, как мы хотим. В настоящее время нам нужно преобразовать формат данных
// 级联下拉
<el-cascader
v-model="ParentID"
:options="options"
:props="{ value: 'PowerID', label: 'PowerName'}"
/>
Фоновые данные следующие
const arr1 = [
{ parent: '0', power: '110' },
{ parent: '110', power: '101' },
{ parent: '110', power: '102' },
{ parent: '0', power: '220' },
{ parent: '220', power: '201' },
{ parent: '220', power: '202' },
{ parent: '101', power: '1011' }
]
Наши идеальные данные выглядят так
{ parent: '0', power: '110', children: [
{ parent: '110', power: '101', children: [{ parent: '101', power: '1011' }] },
{ parent: '110', power: '102' }
] },
{{ parent: '0', power: '220' }, children: [
{ parent: '220', power: '201' },
{ parent: '220', power: '202' }
]}
Обработка данных
const render = it => {
const children = arr1.filter(item => item.parent === it.power).map(render)
if (children.length) {
it.children = children
}
return it
}
this.options = arr1.filter(it => it.parent === '0').map(render)
26. Строки слияния таблиц
<el-table
:data="data2"
border
stripe
style="width: 100%"
:height="tableHeight"
:header-cell-style="{textAlign: 'center',background:'#eef1f6'}"
:sort-orders="['ascending', 'descending']"
:default-sort="{prop: 'LineSort', order: 'descending'}"
:span-method="objectSpanMethod" // 这一行是主要的
/>
// 处理相同数据合并
setTable() {
const spanOneArr = []
const spanTwoArr = []
var concatOne = 0
// 判断是否为最后一级
this.tableData.forEach((item, index) => {
if (index === 0) {
spanOneArr.push(1)
spanTwoArr.push(1)
} else {
if (item.LineName === this.tableData[index - 1].LineName) { // 需合并相同内容的判断条件
spanOneArr[concatOne] += 1
spanOneArr.push(0)
} else {
spanOneArr.push(1)
concatOne = index
}
}
})
return {
one: spanOneArr,
two: spanTwoArr
}
},
// 合并行
objectSpanMethod({ row, column, rowIndex, columnIndex }) {
if (columnIndex === 0 || columnIndex === 1 || columnIndex === 4 || columnIndex === 5 || columnIndex === 6 || columnIndex === 7) {
const _row = (this.setTable(this.tableData).one)[rowIndex]
const _col = _row > 0 ? 1 : 0
return {
rowspan: _row,
colspan: _col
}
}
},
27. Динамически добавлять ряд форм
<el-dialog :title="showForm ? '添加' : '编辑'" :visible.sync="addVisible" width="910px" class="dialog-style" :close-on-click-modal="false">
<el-form ref="editForm" :model="editForm" label-width="90px" style="width: 90%">
<el-form-item label="服务费率" prop="ServiceRate">
<el-input v-model="editForm.ServiceRate" placeholder="0">
<template slot="append">%</template>
</el-input>
</el-form-item>
<el-form-item label="最低服务费" prop="ServiceCharge">
<el-input v-model="editForm.ServiceCharge" placeholder="0">
<template slot="append">元</template>
</el-input>
</el-form-item>
<el-form-item label="贷款期数" prop="LoanPeriod">
<el-input v-model="editForm.LoanPeriod" placeholder="0">
<template slot="append">个月</template>
</el-input>
</el-form-item>
<el-form-item label="贷款利率" prop="lendingRate" style="position: relative">
<el-input v-model="editForm.lendingRate" placeholder="0">
<template slot="append">%</template>
</el-input>
<i class="icon-btn hoverStyle el-icon-circle-plus-outline" @click="addItem" />
</el-form-item>
<!-- 动态增加的表单 -->
<div v-for="(item, index) in editForm.dynamicItem" :key="index" style="display: inline-flex;">
<el-form-item label="贷款期数" :prop="item.LoanPeriod + '_' + index">
<el-input v-model="item.LoanPeriod" placeholder="0">
<template slot="append">个月</template>
</el-input>
</el-form-item>
<el-form-item label="贷款利率" :prop="item.lendingRate + '_' + index" style="position: relative;margin-left: 26px;">
<el-input v-model="item.lendingRate" placeholder="0">
<template slot="append">%</template>
</el-input>
<i class="icon-btn hoverStyle el-icon-remove-outline" @click="deleteItem(index, item)" />
<el-button type="text" class="up-btn" :disabled="index === 0" @click="moveUp(index)">上移</el-button>
<el-button type="text" class="down-btn" :disabled="index === editForm.dynamicItem.length - 1" @click="moveDown(index)">下移</el-button>
</el-form-item>
</div>
</el-form>
<div class="dialog-footer">
<el-button class="btn-footer" type="primary" @click="addSaveData">保 存</el-button>
<el-button class="btn-footer" @click="closeAddDialog('editForm')">取 消</el-button>
</div>
</el-dialog>
// methods中
// 添加增加一行表单
addItem() {
this.editForm.dynamicItem.push({
RId: 0, // 新增传0
BId: 0, // 新增传0
LoanPeriod: '', // 期数
lendingRate: '', // 贷款利率
LoanSort: 0 // 排序按1开始
})
},
// 添加删除一行表单
deleteItem(index, row) {
this.editForm.dynamicItem.splice(index, 1)
},
// 上移
moveUp(index) {
if (index > 0) {
const upDate = this.editForm.dynamicItem[index - 1]
this.editForm.dynamicItem.splice(index - 1, 1)
this.editForm.dynamicItem.splice(index, 0, upDate)
}
},
// 下移
moveDown(index) {
const downDate = this.editForm.dynamicItem[index + 1]
this.editForm.dynamicItem.splice(index + 1, 1)
this.editForm.dynamicItem.splice(index, 0, downDate)
}
28. Измените стиль полосы прокрутки таблицы элементов.
// 修改table滚动条
.el-table{
.el-table__fixed,
.el-table__fixed-right {
height: 100% !important;
}
}
//滚动条的宽度
::-webkit-scrollbar {
width: 10px;
height: 8px;
}
//滚动条的滑块
::-webkit-scrollbar-thumb {
background-color: #dedfe0;
border-radius: 3px;
}